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 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 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 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 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481
|
/*
* SnapPea.h
*
* This file defines the interface between SnapPea's comptational kernel
* ("the kernel") and the user-interface ("the UI"). Both parts
* must #include this file, and anything shared between the two parts
* must be declared in this file. The only communication between the
* two parts is via function calls -- no external variables are shared.
*
* All external symbols in the UI must begin with 'u' followed by a
* capital letter. Nothing in the kernel should begin in this way.
*
* Typedef names use capitals for the first letter of each word,
* e.g. Triangulation, CuspIndex.
*
* SnapPea 2.0 was funded by the University of Minnesota's
* Geometry Center and the U.S. National Science Foundation.
* SnapPea 3.0 is funded by the U.S. National Science Foundation
* and the MacArthur Foundation. SnapPea and its source code may
* be used freely for all noncommercial purposes. Please direct
* questions, problems and suggestions to Jeff Weeks
* (www.geometrygames.org/contact.html).
*
* Copyright 1999 by Jeff Weeks. All rights reserved.
*/
#ifndef _SnapPea_
#define _SnapPea_
/* BUFFER_LENGTH() measures the number of items in an array,
* not the number of bytes, and automatically adjusts to changes
* in the number of elements or the size of each element.
*/
#define BUFFER_LENGTH(a) ( sizeof(a) / sizeof((a)[0]) )
/*
* Note: values of the SolutionType enum are stored as integers in
* the triangulation.doc file format. Changing the order of the
* entries in the enum would therefore invalidate all previously stored
* triangulations.
*/
typedef int SolutionType;
enum
{
not_attempted, /* solution not attempted, or user cancelled */
geometric_solution, /* all positively oriented tetrahedra; not flat or degenerate */
nongeometric_solution, /* positive volume, but some negatively oriented tetrahedra */
flat_solution, /* all tetrahedra flat, but no shapes = {0, 1, infinity} */
degenerate_solution, /* at least one tetrahedron has shape = {0, 1, infinity} */
other_solution, /* volume <= 0, but not flat or degenerate */
no_solution /* gluing equations could not be solved */
};
typedef int FuncResult;
enum
{
func_OK = 0,
func_cancelled,
func_failed,
func_bad_input
};
typedef struct
{
double real,
imag;
} Complex;
typedef unsigned char Boolean;
/*
* The values of MatrixParity should not be changed.
* (They must correspond to the values in the parity[] table in tables.c.)
*/
typedef int MatrixParity;
enum
{
orientation_reversing = 0,
orientation_preserving = 1
};
/*
* SnapPea represents a Moebius transformation as a matrix
* in SL(2,C) plus a specification of whether the Moebius
* transformation is orientation_preserving or orientation_reversing.
*
* If mt->parity is orientation_preserving, then mt->matrix is
* interpreted in the usual way as the Moebius transformation
*
* az + b
* f(z) = --------
* cz + d
*
*
* If mt->parity is orientation_reversing, then mt->matrix is
* interpreted as a function of the complex conjugate z' ("z-bar")
*
* az' + b
* f(z) = ---------
* cz' + d
*/
typedef Complex SL2CMatrix[2][2];
typedef struct
{
SL2CMatrix matrix;
MatrixParity parity;
} MoebiusTransformation;
/*
* Matrices in O(3,1) represent isometries in the Minkowski space
* model of hyperbolic 3-space. The matrices are expressed relative
* to a coordinate system in which the metric is
*
* -1 0 0 0
* 0 1 0 0
* 0 0 1 0
* 0 0 0 1
*
* That is, the first coordinate is timelike, and the remaining
* three are spacelike. O(3,1) matrices represent both
* orientation_preserving and orientation_reversing isometries.
*/
typedef double O31Matrix[4][4];
typedef double GL4RMatrix[4][4];
/*
* An O31Vector is a vector in (3,1)-dimensional Minkowski space.
* The 0-th coordinate is the timelike one.
*/
typedef double O31Vector[4];
/*
* MatrixInt22 is a 2 x 2 integer matrix. A MatrixInt22
* may, for example, describe how the peripheral curves of
* one Cusp map to those of another.
*/
typedef int MatrixInt22[2][2];
/*
* An AbelianGroup is represented as a sequence of torsion coefficients.
* A torsion coefficient of 0 represents an infinite cyclic factor.
* For example, the group Z + Z + Z/2 + Z/5 is represented as the
* sequence (0, 0, 2, 5). We make the convention that torsion coefficients
* are always nonnegative.
*
* The UI may declare pointers to AbelianGroups, but only the kernel
* may allocate or deallocate the actual memory used to store an
* AbelianGroup. (This allows the kernel to keep track of memory
* allocation/deallocation as a debugging aid.)
*/
typedef struct
{
int num_torsion_coefficients; /* number of torsion coefficients */
long int *torsion_coefficients; /* pointer to array of torsion coefficients */
} AbelianGroup;
/*
* A closed geodesic may be topologically a circle or a mirrored interval.
*/
typedef int Orbifold1;
enum
{
orbifold1_unknown,
orbifold_s1, /* circle */
orbifold_mI /* mirrored interval */
};
/*
* The following 2-orbifolds may occur as the link of an
* edge midpoint in a cell decomposition of a 3-orbifold.
*
* 94/10/4. The UI will see only types orbifold_nn
* and orbifold_xnn. Edges of the other types have 0-cells
* of the singular set at their midpoints, and are now
* subdivided in Dirichlet_extras.c. JRW
*/
typedef int Orbifold2;
enum
{
orbifold_nn, /* (nn) 2-sphere with two cone points (n may be 1) */
orbifold_no, /* (n|o) cross surface with cone point (n may be 1) */
orbifold_xnn, /* (*nn) disk with mirror boundary with two */
/* corner reflectors */
orbifold_2xn, /* (2*n) disk with order two cone point and mirror */
/* boundary with one corner reflector */
orbifold_22n /* (22n) sphere with three cone points */
};
/*
* A MultiLength records the complex length of a geodesic together with a
* parity telling whether it preserves or reverses orientation, a topology
* telling whether it's a circle or a mirrored interval, and a multiplicity
* telling how many distinct geodesics have that complex length, parity and
* topology.
*/
typedef struct
{
Complex length;
MatrixParity parity;
Orbifold1 topology;
int multiplicity;
} MultiLength;
/*
* A CuspNbhdHoroball records a horoball to be drawn as part of a
* picture of a cusp cross section. Only the kernel should allocate
* and free CuspNbhdHoroballs and CuspNbhdHoroballLists. These
* definitions are provided to the UI so it access the data easily.
*/
typedef struct
{
Complex center;
double radius;
int cusp_index;
} CuspNbhdHoroball;
typedef struct
{
/*
* The horoball field points to an array
* of num_horoballs CuspNbhdHoroballs.
*/
int num_horoballs;
CuspNbhdHoroball *horoball;
} CuspNbhdHoroballList;
/*
* A CuspNbhdSegment records a 1-cell to be drawn as part of a
* picture of a cusp cross section. (Typically it's either part of
* a triangulation of the cusp cross section, or part of a Ford domain.)
* Only the kernel should allocate and free CuspNbhdSegments and
* CuspNbhdSegmentLists. These definitions are provided to the UI
* so it can easily access the data.
*
* JRW 99/03/17 When the CuspNbhdSegment describes a triangulation
* (as opposed to a Ford domain),
*
* the start_index tells the edge index of the vertical edge
* that runs from the given segment's beginning
* to the viewer's eye,
*
* the middle_index tells the edge index of the given segment, and
*
* the end_index tells the edge index of the vertical edge
* that runs from the given segment's end
* to the viewer's eye.
*
* These indices let the viewer see how the horoball picture
* "connects up" to form the manifold.
*/
typedef struct
{
Complex endpoint[2];
int start_index,
middle_index,
end_index;
} CuspNbhdSegment;
typedef struct
{
/*
* segment is a pointer to an array of num_segments CuspNbhdSegments.
*/
int num_segments;
CuspNbhdSegment *segment;
} CuspNbhdSegmentList;
typedef int Orientability;
enum
{
oriented_manifold,
nonorientable_manifold,
unknown_orientability
};
typedef int CuspTopology;
enum
{
torus_cusp,
Klein_cusp,
unknown_topology
};
typedef int DirichletInteractivity;
enum
{
Dirichlet_interactive,
Dirichlet_stop_here,
Dirichlet_keep_going
};
/*
* An LRFactorization specifies the monodromy for a punctured torus
* bundle over a circle. The factorization is_available whenever
* (det(monodromy) = +1 and |trace(monodromy)| >= 2) or
* (det(monodromy) = -1 and |trace(monodromy)| >= 1).
* LR_factors points to an array of L's and R's, interpreted as factors
*
* L = ( 1 0 ) R = ( 1 1 )
* ( 1 1 ) ( 0 1 )
*
* The factors act on a column vector, beginning with the last
* (i.e. rightmost) factor.
*
* If negative_determinant is TRUE, the product is left-multiplied by
*
* ( 0 1 )
* ( 1 0 )
*
* If negative_trace is TRUE, the product is left-multiplied by
*
* (-1 0 )
* ( 0 -1 )
*
* When the factorization is unavailable, is_available is set to FALSE,
* num_LR_factors is set to zero, and LR_factors is set to NULL.
* But the negative_determinant and negative_trace flags are still set,
* so the UI can display this information correctly.
*/
typedef struct
{
Boolean is_available,
negative_determinant,
negative_trace;
int num_LR_factors;
char *LR_factors;
} LRFactorization;
/*
* The full definition of a Shingling appears near the top of shingling.c.
* But computationally a Shingling is just a collection of planes in
* hyperbolic space (typically viewed as circles on the sphere at infinity).
* Each plane has an index (which defines the color of the circle at
* infinity).
*/
typedef struct
{
/*
* A plane in hyperbolic 3-space defines a hyperplane through
* the origin in the Minkowski space model. Use the hyperplane's
* normal vector to represent the original plane. [Note: the
* normal is computed once, in the standard coordinate system,
* and does not change as the UI rotates the polyhedron.]
*/
O31Vector normal;
/*
* A plane in hyperbolic 3-space intersects the sphere at infinity
* in a circle. It's easy to draw the circle if we know its center
* and two orthogonal "radials". (The 0-components of the center
* and radials may be ignored.) [Note: the center and radials are
* rotated in real time according to the polyhedron's current
* position, and are scaled according to the window's pixel size.]
*/
O31Vector center,
radialA,
radialB;
/*
* The face planes of the original Dirichlet domain have index 0,
* the face planes of the next layer (cf. shingling.c) have index 1,
* and so on.
*/
int index;
} Shingle;
typedef struct
{
/*
* A Shingling is just an array of Shingles.
*/
int num_shingles;
Shingle *shingles;
} Shingling;
/*
* The following are "opaque typedefs". They let the UI declare and
* pass pointers to Triangulations, IsometryLists, etc. without
* knowing what a Triangulation, IsometryList, etc. is. The definitions
* of struct Triangulation, struct IsometryList, etc. are private to the
* kernel. SymmetryLists and IsometryLists are represented by the same
* data structure because Symmetries are just Isometries from a manifold
* to itself.
*/
typedef struct Triangulation Triangulation;
typedef struct IsometryList IsometryList;
typedef struct SymmetryGroup SymmetryGroup;
typedef struct SymmetryGroupPresentation SymmetryGroupPresentation;
typedef struct DualOneSkeletonCurve DualOneSkeletonCurve;
typedef struct TerseTriangulation TerseTriangulation;
typedef struct GroupPresentation GroupPresentation;
typedef struct CuspNeighborhoods CuspNeighborhoods;
typedef struct NormalSurfaceList NormalSurfaceList;
/*
* winged_edge.h describes the winged edge data structure used
* to describe Dirichlet domains.
*/
#include "winged_edge.h"
/*
* link_projection.h describes the format in which the UI passes
* link projections to the kernel.
*/
#include "link_projection.h"
/*
* When the UI reads a Triangulation from disk, it passes the results
* to the kernel using the format described in triangulation_io.h.
*/
#include "triangulation_io.h"
/*
* covers.h defines a representation of a manifold's fundamental group
* into the symmetric group on n letters.
*/
#include "covers.h"
/* To guarantee thread-safety, it's useful to declare */
/* global variables to be "const", for example */
/* */
/* static const Complex minus_i = {0.0, -1.0}; */
/* */
/* Unfortunately the current gcc compiler complains when */
/* non-const variables are passed to functions expecting */
/* const arguments. Obviously this is harmless, but gcc */
/* complains anyhow. So for now let's use the following */
/* CONST macro, to allow the const declarations to be */
/* reactivated if desired. */
/* */
/* Note: In Win32, windef.h also defines CONST = const, */
/* so clear its definition before making our own. */
#undef CONST
#define CONST
/* #define CONST const */
#ifdef __cplusplus
extern "C" {
#endif
/************************************************************************/
/*
* The UI provides the following functions for use by the kernel:
*/
extern void uAcknowledge(const char *message);
/*
* Presents the string *message to the user and waits for acknowledgment ("OK").
*/
extern int uQuery(const char *message, const int num_responses,
const char *responses[], const int default_response);
/*
* Presents the string *message to the user and asks the user to choose
* one of the responses. Returns the number of the chosen response
* (numbering starts at 0). In an interactive context, the UI should
* present the possible responses evenhandedly -- none should be
* presented as a default. However, in a batch context (when no human
* is present), uQuery should return the default_response.
*/
extern void uFatalError(char *function, char *file);
/*
* Informs the user that a fatal error has occurred in the given
* function and file, and then exits.
*/
extern void uAbortMemoryFull(void);
/*
* Informs the user that the available memory has been exhausted,
* and aborts SnapPea.
*/
extern void uPrepareMemFullMessage(void);
/*
* uMemoryFull() is a tricky function, because the system may not find
* enough memory to display an error message. (I tried having it stash
* away some memory and then free it to support the desired dialog box,
* but at least on the Mac this didn't work for some unknown reason.)
* uPrepareMemFullMessage() gives the system a chance to prepare
* a (hidden) dialog box. Call it once when the UI initializes.
*/
extern void uLongComputationBegins(char *message, Boolean is_abortable);
extern FuncResult uLongComputationContinues(void);
extern void uLongComputationEnds(void);
/*
* The kernel uses these three functions to inform the UI of a long
* computation. The UI relays this information to the user in whatever
* manner it considers appropriate. For example, it might wait a second
* or two after the beginning of a long computation, and then display
* a dialog box containing *message (a typical message might be
* "finding canonical triangulation" or "computing hyperbolic structure").
* If is_abortable is TRUE, the dialog box would contain an abort button.
* The reason for waiting a second or two before displaying the dialog
* box is to avoid annoying the user with flashing dialog boxes for
* computations which turn out not to be so long after all.
*
* The kernel is responsible for calling uLongComputationContinues() at
* least every 1/60 second or so during a long computation.
* uLongComputationContinues() serves two purposes:
*
* (1) It lets the UI yield time to its window system. (This is
* crucial for smooth background operation in the Mac's
* cooperative multitasking environment. I don't know whether
* it is necessary in X or NeXT.)
*
* (2) If the computation is abortable, it checks whether the user
* has asked to abort, and returns the result (func_cancelled
* to abort, func_OK to continue).
*
* While the kernel is responsible for making sure uLongComputationContinues()
* is called often enough, uLongComputationContinues() itself must take
* responsibility for not repeating time-consuming operations too often.
* For example, it might return immediately from a call if less than
* 1/60 of a second has elapsed since the last time it carried out
* its full duties.
*
* uLongComputationEnds() signals that the long computation is over.
* The kernel must call uLongComputationEnds() even after an aborted
* computation. ( uLongComputationContinues() merely informs the kernel
* that the user punched the abort button. The kernel must still call
* uLongComputationEnds() to dismiss the dialog box in the usual way.)
*
* If the UI receives a call to uLongComputationEnds() when no long
* computation is in progress, or a call to uLongComputationBegins()
* when a long computation is already in progress, it should notify
* the user of the error and exit.
*
* If the UI receives a call to uLongComputationContinues() when in
* fact no long computation is in progress, it should simply take
* care of any background responsibilities (see (1) above) and not
* complain. The reason for this provision is that the calls to
* uLongComputationBegins() and uLongComputationEnds() occur in high
* level functions, while the calls to uLongComputationContinues()
* occur at the lowest level, perhaps in a different file. Someday
* those low-level functions (for example, the routines for solving
* simultaneous linear equations) might be called as part of some quick,
* non-abortable computation.
*/
/************************************************************************/
/************************************************************************/
/*
* The kernel provides the following functions for use by the UI.
*
* A brief specification follows each function prototype.
* Complete documentation appears in the corresponding source file.
*/
/************************************************************************/
/* */
/* abelian_group.c */
/* */
/************************************************************************/
extern void expand_abelian_group(AbelianGroup *g);
/*
* Expands an AbelianGroup into its most factored form,
* e.g. Z/2 + Z/2 + Z/4 + Z/3 + Z/9 + Z.
* Each nonzero torsion coefficient is a power of a prime.
*/
extern void compress_abelian_group(AbelianGroup *g);
/*
* Compresses an AbelianGroup into its least factored form,
* Z/2 + Z/6 + Z/36 + Z.
* Each torsion coefficient divides all subsequent torsion coefficients.
*/
extern void free_abelian_group(AbelianGroup *g);
/*
* Frees the storage used to hold the AbelianGroup *g.
*/
/************************************************************************/
/* */
/* ambiguous_cusp_bases.c */
/* */
/************************************************************************/
extern void resolve_ambiguous_bases(
Triangulation *aTriangulation,
char *aDehydratedDescription);
/*
* For census manifolds with square or hexagonal cusps,
* chooses a well-defined (meridian, longitude) pair
* based on the homology of the manifold as a whole.
* For non-census manifolds, posts a warning and leaves
* the existing (meridian, longitude) unchanged.
*/
/************************************************************************/
/* */
/* canonize.c */
/* canonize_part_1.c */
/* canonize_part_2.c */
/* */
/************************************************************************/
extern FuncResult canonize(Triangulation *manifold);
/*
* Replaces the given Triangulation with the canonical retriangulation
* of the canonical cell decomposition. Returns func_OK upon success,
* func_failed if it cannot find a hyperbolic structure for *manifold.
*/
extern FuncResult proto_canonize(Triangulation *manifold);
extern void canonical_retriangulation(Triangulation *manifold);
/*
* These functions comprise the two halves of canonize() in canonize.c.
*
* proto_canonize() replaces a Triangulation by the canonical
* triangulation of the same manifold (if the canonical cell
* decomposition is a triangulation) or by an arbitrary subdivision
* of the canonical cell decomposition into Tetrahedra (if the canonical
* cell decomposition contains cells other than tetrahedra).
* Returns func_OK upon success, func_failed if it cannot find a
* hyperbolic structure for *manifold.
*
* canonical_retriangulation() replaces the given subdivision of the
* canonical cell decomposition with the canonical retriangulation.
* This operation introduces finite vertices whenever the canonical cell
* decomposition is not a triangulation to begin with. The hyperbolic
* structure is discarded.
*/
extern Boolean is_canonical_triangulation(Triangulation *manifold);
/*
* Given a subdivision of the canonical cell decomposition as produced
* by proto_canonize(), says whether it is the canonical decomposition
* itself. In other words, it says whether the canonical cell decomposition
* is a triangulation.
*/
/************************************************************************/
/* */
/* change_peripheral_curves.c */
/* */
/************************************************************************/
extern FuncResult change_peripheral_curves(
Triangulation *manifold,
CONST MatrixInt22 change_matrices[]);
/*
* If all the change_matrices have determinant +1, installs the
* corresponding new peripheral curves and returns func_OK.
* (See change_peripheral_curves.c for details.)
* Otherwise does nothing and returns func_bad_input.
*/
/************************************************************************/
/* */
/* chern_simons.c */
/* */
/************************************************************************/
extern void set_CS_value( Triangulation *manifold,
double a_value);
/*
* Set the Chern-Simons invariant of *manifold to a_value.
*/
extern void get_CS_value( Triangulation *manifold,
Boolean *value_is_known,
double *the_value,
int *the_precision,
Boolean *requires_initialization);
/*
* If the Chern-Simons invariant of *manifold is known, sets
* *value_is_known to TRUE and writes the current value and its precision
* (the number of significant digits to the right of the decimal point)
* to *the_value and *the_precision, respectively.
*
* If the Chern-Simons invariant is not known, sets *value_is_known to
* FALSE, and then sets *requires_initialization to TRUE if the_value
* is unknown because the computation has not been initialized, or
* to FALSE if the_value is unknown because the solution contains
* negatively oriented Tetrahedra. The UI might want to convey
* these situations to the user in different ways.
*/
/************************************************************************/
/* */
/* complex.c */
/* */
/************************************************************************/
extern Complex complex_minus (Complex z0, Complex z1),
complex_plus (Complex z0, Complex z1),
complex_mult (Complex z0, Complex z1),
complex_div (Complex z0, Complex z1),
complex_sqrt (Complex z),
complex_conjugate (Complex z),
complex_negate (Complex z),
complex_real_mult (double r, Complex z),
complex_exp (Complex z),
complex_log (Complex z, double approx_arg);
extern double complex_modulus (Complex z);
extern double complex_modulus_squared (Complex z);
extern Boolean complex_nonzero (Complex z);
extern Boolean complex_infinite (Complex z);
/*
* The usual complex arithmetic functions.
*
* Standard complex constants (Zero, One, etc.) are defined in the kernel.
*/
/************************************************************************/
/* */
/* complex_length.c */
/* */
/************************************************************************/
extern Complex complex_length_mt(MoebiusTransformation *mt);
extern Complex complex_length_o31(O31Matrix m);
/*
* Computes the complex length of an isometry. Please see
* complex_length.c for full definitions and explanations.
* complex_length_mt() and complex_length_o31() are identical except
* for the form in which the input is given.
*/
/************************************************************************/
/* */
/* continued_fractions.c */
/* */
/************************************************************************/
extern Boolean appears_rational(double x0, double x1, double confidence,
long *num, long *den);
/*
* Checks whether a finite-precision real number x known to lie in the
* interval (x0, x1) appears to be a rational number p/q. If it does,
* it sets *num and *den to p and q, respectively, and returns TRUE.
* Otherwise it sets *num and *den to 0 and returns FALSE.
* The confidence parameter gives the maximal acceptable probability
* of a "false positive".
*/
/************************************************************************/
/* */
/* core_geodesic.c */
/* */
/************************************************************************/
extern void core_geodesic( Triangulation *manifold,
int cusp_index,
int *singularity_index,
Complex *core_length,
int *precision);
/*
* Examines the Cusp of index cusp_index in *manifold.
*
* If the Cusp is unfilled or the Dehn filling coefficients are not
* integers, sets *singularity_index to zero and leaves *core_length
* undefined.
*
* If the Cusp has relatively prime integer Dehn filling coefficients,
* sets *singularity_index to 1 and *core_length to the complex length
* of the central geodesic.
*
* If the Cusp has non relatively prime integer Dehn filling coefficients,
* sets *singularity_index to the index of the singular locus, and
* *core_length to the complex length of the central geodesic in the
* smallest manifold cover of a neighborhood of the singular set.
*
* In the latter two cases, if the precision pointer is not NULL,
* *precision is set to the number of decimal places of accuracy in
* the computed value of *core_length.
*
* core_geodesic() is intended for use by the UI. Kernel function may
* find compute_core_geodesic() (declared in kernel_prototypes.h) more
* convenient.
*/
/************************************************************************/
/* */
/* cover.c */
/* */
/************************************************************************/
Triangulation *construct_cover( Triangulation *base_manifold,
RepresentationIntoSn *representation,
int n);
/*
* Constructs the n-sheeted cover of the given base_manifold defined
* by the given transitive representation.
*/
/************************************************************************/
/* */
/* current_curve_basis.c */
/* */
/************************************************************************/
extern void current_curve_basis( Triangulation *manifold,
int cusp_index,
MatrixInt22 basis_change);
extern void install_current_curve_bases(Triangulation *manifold);
/*
* current_curve_basis() accepts a Triangulation and a cusp index,
* and computes a 2 x 2 integer matrix basis_change with the property
* that
*
* if the Cusp of index cusp_index is filled, and has
* relatively prime integer Dehn filling coefficients,
*
* the first row of basis_change is set to the current
* Dehn filling coefficients, and
* the second row of basis_change is set to the shortest
* curve which completes a basis.
*
* else
*
* basis_change is set to the identity
*
* install_current_curve_bases() installs the above basis
* on all cusps of the manifold.
*/
/************************************************************************/
/* */
/* cusp_neighborhoods.c */
/* */
/************************************************************************/
extern CuspNeighborhoods *initialize_cusp_neighborhoods(
Triangulation *manifold);
/*
* Initializes a CuspNeighborhoods data structure.
* It works with a copy of manifold, leaving the original untouched.
* It does all indicated Dehn fillings.
* Returns a pointer to the CuspNeighborhoods structure upon success,
* of NULL if the "manifold" isn't a cusped hyperbolic 3-manifold.
*/
extern void free_cusp_neighborhoods(
CuspNeighborhoods *cusp_neighborhoods);
/*
* Frees the CuspNeighborhoods structure, including the copy of
* the Triangulation it contains.
*/
extern int get_num_cusp_neighborhoods(
CuspNeighborhoods *cusp_neighborhoods);
/*
* Returns the number of cusps. This will be the number of unfilled
* cusps in the original manifold, which may be less than the total
* number of cusps.
*/
extern CuspTopology get_cusp_neighborhood_topology(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index);
/*
* Returns the CuspTopology of the given cusp.
*/
extern double get_cusp_neighborhood_displacement(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index);
/*
* Returns the (linear) displacement of the horospherical cross
* section of the given cusp from its home position. At the home
* position the cusp cross section has area (3/8)sqrt(3) and
* encloses a volume of (3/16)sqrt(3) in the cusp. At its home
* position, a cusp cannot overlap itself, nor can it overlap any
* other cusp which does not already overlap itself. Please see
* cusp_neighborhoods.c for details.
*/
extern Boolean get_cusp_neighborhood_tie(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index);
/*
* Says whether this cusp's neighborhood is tied to other cusps'.
*/
extern double get_cusp_neighborhood_cusp_volume(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index);
/*
* Returns the volume enclosed by the horospherical cross section
* of the given cusp.
*/
extern double get_cusp_neighborhood_manifold_volume(
CuspNeighborhoods *cusp_neighborhoods);
/*
* Returns the volume of the manifold.
*/
extern Triangulation *get_cusp_neighborhood_manifold(
CuspNeighborhoods *cusp_neighborhoods);
/*
* Returns a pointer to a copy of the manifold. The UI may do as it
* pleases with the copy, and should free it when it's done.
*/
extern double get_cusp_neighborhood_reach(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index);
/*
* Returns the displacement at which the cusp cross section first
* bumps into itself.
*/
extern double get_cusp_neighborhood_max_reach(
CuspNeighborhoods *cusp_neighborhoods);
/*
* Returns the maximum reach over the whole manifold.
*/
extern double get_cusp_neighborhood_stopping_displacement(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index);
extern int get_cusp_neighborhood_stopper_cusp_index(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index);
/*
* Return the displacement at which the cusp first bumps into another
* cusp (or possibly into itself), and the cusp it bumps into.
* Unlike the reach, the stopper and the stopping displacement depend
* on the current displacements of all the cusps in the triangulation.
* They vary dynamically as the user moves the cusp cross sections.
*/
extern void set_cusp_neighborhood_displacement(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index,
double new_displacement);
/*
* Sets the cusp neighborhood's displacement to the requested value,
* clipping it to the range [0, stopping_displacement] if necessary.
* Recomputes the canonical cell decomposition.
*/
extern void set_cusp_neighborhood_tie(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index,
Boolean new_tie);
/*
* Tells the kernel whether this cusp's neighborhood should be
* tied to other cusps (which have previously been "tied").
* The kernel makes all tied cusps have the same displacement.
*/
extern void get_cusp_neighborhood_translations(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index,
Complex *meridian,
Complex *longitude);
/*
* Returns the meridional and longitudinal translation vectors
* for the given cusp cross section, taking into account its current
* displacement. For a Klein bottle cusp, the longitudinal translation
* will be that of the double cover. As a convenience, the longitude
* will always point in the x-direction.
*/
extern CuspNbhdHoroballList *get_cusp_neighborhood_horoballs(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index,
Boolean full_list,
double cutoff_height);
/*
* Returns a list of horoballs seen from the given cusp, taking into
* account the cusp cross sections' current displacements. Only one
* translate is given for each horoball -- to draw the full picture the
* UI must find all visible translates using the meridian and longitude
* provided by get_cusp_neighborhood_translations(). For a Klein bottle
* cusp, get_cusp_neighborhood_horoballs() reports data for the double
* cover. If full_list is TRUE, get_cusp_neighborhood_horoballs()
* reports all horoballs whose Euclidean height in the upper half space
* model is at least cutoff_height. If full_list is FALSE, it reports
* only a few of the largest horoballs (the cutoff_height is ignored).
* This lets the UI draw a simpler picture while the user is changing
* something in real time, and then draw a more complete picture afterwards.
*/
extern void free_cusp_neighborhood_horoball_list(
CuspNbhdHoroballList *horoball_list);
/*
* Frees a CuspNbhdHoroballList when the UI's done with it.
*/
extern CuspNbhdSegmentList *get_cusp_neighborhood_triangulation(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index);
/*
* Returns a list of edges in the restriction of the canonical cell
* decomposition to the cusp cross section, taking into account the
* cusp cross section's current displacement. Only one translate is
* given for each edge -- to draw the full picture the UI must find all
* visible translates using the meridian and longitude provided by
* get_cusp_neighborhood_translations(). For a Klein bottle cusp,
* get_cusp_neighborhood_triangulation() reports data for the double cover.
*/
extern CuspNbhdSegmentList *get_cusp_neighborhood_Ford_domain(
CuspNeighborhoods *cusp_neighborhoods,
int cusp_index);
/*
* Returns a list of edges in the Ford domain, taking into account the
* cusp cross section's current displacement. Only one translate is
* given for each edge -- to draw the full picture the UI must find all
* visible translates using the meridian and longitude provided by
* get_cusp_neighborhood_translations(). For a Klein bottle cusp,
* get_cusp_neighborhood_Ford_domain() reports data for the double cover.
*/
extern void free_cusp_neighborhood_segment_list(
CuspNbhdSegmentList *segment_list);
/*
* Frees a CuspNbhdSegmentList when the UI's done with it.
*/
/************************************************************************/
/* */
/* decode_CHW.c */
/* */
/************************************************************************/
extern Triangulation *CHW_to_tri( char *anEncoding,
Boolean aChernSimonsIsPresent,
double aChernSimonsValue);
/*
* Decode a CHW-encoded triangulation. Please see decode_CHW.c for details.
*/
/************************************************************************/
/* */
/* Dirichlet.c */
/* */
/************************************************************************/
extern WEPolyhedron *Dirichlet(
Triangulation *manifold,
double vertex_epsilon,
Boolean centroid_at_origin,
DirichletInteractivity interactivity,
Boolean maximize_injectivity_radius);
/*
* Computes a Dirichlet domain for the given manifold or orbifold.
* Returns NULL if the Dehn filling coefficients are not all integers,
* of if roundoff errors lead to topological problems.
* Returns a pointer to the Dirichlet domain otherwise.
*/
extern WEPolyhedron *Dirichlet_with_displacement(
Triangulation *manifold,
double displacement[3],
double vertex_epsilon,
Boolean centroid_at_origin,
DirichletInteractivity interactivity,
Boolean maximize_injectivity_radius);
/*
* Like Dirichlet(), only allows an arbitrary displacement
* of the basepoint. The displacement is in tangent space
* coordinates, so the distances can't be interpreted too literally.
* Reasonable displacements are to the order of 0.1.
* Large displacements are possible, but degrade the numerical
* accuracy of the resulting Dirichlet domain.
*/
extern WEPolyhedron *Dirichlet_from_generators(
O31Matrix generators[],
int num_generators,
double vertex_epsilon,
DirichletInteractivity interactivity,
Boolean maximize_injectivity_radius);
/*
* Like Dirichlet(), only starts with a set of O(3,1) matrix generators
* instead of a Triangulation.
*/
extern WEPolyhedron *Dirichlet_from_generators_with_displacement(
O31Matrix generators[],
int num_generators,
double displacement[3],
double vertex_epsilon,
DirichletInteractivity interactivity,
Boolean maximize_injectivity_radius);
/*
* Combines the functionality of Dirichlet_with_displacement() and
* Dirichlet_from_generators().
*/
extern void change_basepoint(
WEPolyhedron **polyhedron,
Triangulation *manifold,
O31Matrix *generators,
int num_generators,
double displacement[3],
double vertex_epsilon,
Boolean centroid_at_origin,
DirichletInteractivity interactivity,
Boolean maximize_injectivity_radius);
/*
* Reads the face pairing matrices from the polyhedron, shifts the
* basepoint by the given displacement (optionally letting the basepoint
* move to a local maximum of the injectivity radius function), and
* recomputes the Dirichlet domain.
* If *polyhedron is NULL, computes the Dirichlet domain directly from
* the manifold, but with the given displacement of the initial basepoint.
* In either case, a pointer to the resulting Dirichlet domain (or NULL
* if an error occurs as described in Dirichlet() above) is written
* to *polyhedron.
*/
extern void free_Dirichlet_domain(WEPolyhedron *Dirichlet_domain);
/*
* Frees the storage occupied by a WEPolyhedron.
*/
/************************************************************************/
/* */
/* Dirichlet_rotate.c */
/* */
/************************************************************************/
extern void set_identity_matrix(O31Matrix position);
/*
* Sets the matrix to the identity.
*/
extern void update_poly_position(O31Matrix position, O31Matrix velocity);
/*
* Multiplies the position by the velocity.
*/
extern void update_poly_vertices(WEPolyhedron *polyhedron,
O31Matrix position, double scale);
/*
* Multiplies the standard vertex coordinates x[] by the position matrix
* to obtain the rotated coordinates xx[], and then multiplies the
* rotated coordinates by the constant "scale".
*/
extern void update_poly_visibility(WEPolyhedron *polyhedron,
O31Matrix position, O31Vector direction);
/*
* Checks which vertices, edges and faces are visible to the user with
* the polyhedron in its present position, and sets their visibility
* fields accordingly.
*/
/************************************************************************/
/* */
/* Dirichlet_conversion.c */
/* */
/************************************************************************/
extern Triangulation *Dirichlet_to_triangulation(WEPolyhedron *polyhedron);
/*
* Converts a Dirichlet domain to a Triangulation, leaving the
* Dirichlet domain unchanged. For closed manifolds, drills out
* an arbitrary curve and expresses the manifold as a Dehn filling.
*/
/************************************************************************/
/* */
/* double_cover.c */
/* */
/************************************************************************/
extern Triangulation *double_cover(Triangulation *manifold);
/*
* Returns a pointer to the double cover of the nonorientable
* Triangulation *manifold.
*/
/************************************************************************/
/* */
/* dual_curves.c */
/* */
/************************************************************************/
extern void dual_curves( Triangulation *manifold,
int max_size,
int *num_curves,
DualOneSkeletonCurve ***the_curves);
/*
* Computes a reasonable selection of simple closed curves in
* a manifold's dual 1-skeleton.
*/
extern void get_dual_curve_info( DualOneSkeletonCurve *the_curve,
Complex *complete_length,
Complex *filled_length,
MatrixParity *parity);
/*
* Reports the complex length of a curve in the dual 1-skeleton,
* relative to both the complete and filled hyperbolic structures,
* and also its parity (orientation_preserving or orientation_reversing).
*/
extern void free_dual_curves( int num_curves,
DualOneSkeletonCurve **the_curves);
/*
* Frees the array of curves computed by dual_curves().
*/
/************************************************************************/
/* */
/* drilling.c */
/* */
/************************************************************************/
extern Triangulation *drill_cusp( Triangulation *old_manifold,
DualOneSkeletonCurve *curve_to_drill,
char *new_name);
/*
* Drills a curve out of the dual 1-skeleton of an n-cusp manifold to
* create an (n+1)-cusp manifold.
*/
/************************************************************************/
/* */
/* filling.c */
/* */
/************************************************************************/
extern Triangulation *fill_cusps( Triangulation *manifold,
Boolean fill_cusp[],
char *new_name,
Boolean fill_all_cusps);
/*
* Permanently fills k of the cusps of an n-cusp manifold.
* Typically fill_all_cusps is FALSE, and the function returns
* an ideal Triangulation of the resulting (n - k)-cusp manifold.
* fill_cusp[] is a Boolean array specifying which k cusps (k < n)
* are to be filled.
*
* In the exceptional case that fill_all_cusps is TRUE, the function
* returns a triangulation with finite vertices only.
* Such triangulations are unacceptable for most SnapPea routines,
* and should be used only for writing to disk. When fill_all_cusps
* is TRUE, fill_cusp is ignored and may be NULL.
*
* new_name is the name to be given to the new Triangulation.
*/
extern Triangulation *fill_reasonable_cusps(Triangulation *manifold);
/*
* Makes reasonable choices for fill_cusp[] and new_name, and calls
* fill_cusps(). Specifically, it will fill all cusps with relatively
* prime Dehn filling coefficients, unless this would leave no cusps
* unfilled, in which case it leaves cusp 0 unfilled. It copies the
* name from the original manifold.
*/
extern Boolean cusp_is_fillable(Triangulation *manifold, int cusp_index);
/*
* Returns TRUE if a cusp has relatively prime integer Dehn filling
* coefficients, FALSE otherwise.
*/
extern Boolean is_closed_manifold(Triangulation *manifold);
/*
* Returns TRUE iff all cusps are filled and the coefficients
* are relatively prime integers.
*/
/************************************************************************/
/* */
/* fundamental_group.c */
/* */
/************************************************************************/
extern GroupPresentation *fundamental_group(
Triangulation *manifold,
Boolean simplify_presentation,
Boolean fillings_may_affect_generators,
Boolean minimize_number_of_generators);
/*
* Computes the fundamental group of the manifold, taking into account
* Dehn fillings, and returns a pointer to it. Please see
* fundamental_group.c for an explanation of the arguments.
*/
extern int fg_get_num_generators(GroupPresentation *group);
/*
* Returns the number of generators in the GroupPresentation.
*/
extern Boolean fg_integer_fillings(GroupPresentation *group);
/*
* Says whether the underlying space is a manifold or orbifold,
* as opposed to some other generalized Dehn filling.
*/
extern FuncResult fg_word_to_matrix(
GroupPresentation *group,
int *word,
O31Matrix result_O31,
MoebiusTransformation *result_Moebius);
/*
* Converts an abstract word in the fundamental group to a matrix
* in the matrix representation. The abstract word is given as a
* string of integers. The integer 1 means the first generator,
* 2 means the second, etc., while -1 is the inverse of the first
* generator, -2 is the inverse of the second, etc. The integer 0
* indicates the end of the string. The result is given both as
* an O31Matrix and a MoebiusTransformation. Returns func_OK if
* successful, or func_bad_input if the input word is not valid.
*/
extern int fg_get_num_relations(GroupPresentation *group);
/*
* Returns the number of relations in the GroupPresentation.
*/
extern int *fg_get_relation( GroupPresentation *group,
int which_relation);
/*
* Returns the specified relation (using 0-based indexing).
* It allocates the memory for it, so you should pass the pointer
* back to fg_free_relation() when you're done with it.
* Each relation is a string of integers. The integer 1 means
* the first generator, 2 means the second, etc., while -1 is the
* inverse of the first generator, -2 is the inverse of the second, etc.
* The integer 0 indicates the end of the string.
*/
extern void fg_free_relation(int *relation);
/*
* Frees a relation allocated by fg_get_relation().
*/
extern int fg_get_num_cusps(GroupPresentation *group);
/*
* Returns the number of cusps of the underlying manifold.
* This *includes* the filled cusps. So, for example, if you do (5,1)
* Dehn filling on the figure eight knot complement, you can see the
* words in the fundamental group corresponding to the (former!) cusp's
* meridian and longitude.
*/
extern int *fg_get_meridian( GroupPresentation *group,
int which_cusp);
extern int *fg_get_longitude( GroupPresentation *group,
int which_cusp);
/*
* Returns the word corresponding to a meridian or longitude, in the
* same format used by fg_get_relation() above. They allocate the
* memory for the string of integers, so you should pass the pointer
* back to fg_free_relation() when you're done with it. Meridians and
* longitudes are available whether the cusps are filled or not, as
* explained for fg_get_num_cusps() above.
*/
extern int *fg_get_original_generator( GroupPresentation *group,
int which_generator);
/*
* Returns a word which expresses one of the standard geometric
* generators (as defined in choose_generators.c) in terms of the
* group presentation's generators. The word is in the same format
* used by fg_get_relation() above. Note that which_generator is
* given relative to 0-based indexing, but the letters in the word
* you get out use 1-based numbering, as in fg_get_relation().
* Please free the word with fg_free_relation() when you're done.
*/
extern void free_group_presentation(GroupPresentation *group);
/*
* Frees the storage occupied by a GroupPresentation.
*/
/************************************************************************/
/* */
/* homology.c */
/* */
/************************************************************************/
extern AbelianGroup *homology(Triangulation *manifold);
/*
* If all Dehn filling coefficients are integers, returns a pointer to
* the first homology group of *manifold. In particular, it will
* happily compute homology groups of orbifolds. If one or more Dehn
* filling coefficients are not integers, returns NULL. This function
* allocates the memory for the AbelianGroup; the UI should call
* free_abelian_group() (no pun intended) to release it.
*
* 96/12/11 Checks for overflows, and returns NULL if any occur.
*/
extern AbelianGroup *homology_from_fundamental_group(
GroupPresentation *group);
/*
* Abelianizes a group presentation and returns the result.
* Returns NULL if overflows occur.
*/
/************************************************************************/
/* */
/* hyperbolic_structure.c */
/* */
/************************************************************************/
extern SolutionType find_complete_hyperbolic_structure(Triangulation *manifold);
/*
* Attempts to find a complete hyperbolic structure for the
* Triangulation *manifold. Sets the solution_type[complete] member of
* *manifold to the type of solution found. If this type is anything
* other than no_solution, stores the hyperbolic structure by setting
* the *shape[complete] field of each Tetrahedron in the Triangulation. The
* solution is also stored as the initial filled solution, by setting the
* solution_type[filled] member of *manifold and the *shape[filled] fields
* of the Tetrahedra; the is_complete flag of each Cusp is set to TRUE.
*
* The hyperbolic structure is computed using Newton's method, beginning
* with all tetrahedra regular.
*
* Returns: the type of solution found.
*/
extern SolutionType do_Dehn_filling(Triangulation *manifold);
/*
* Attempts to find a hyperbolic structure for a *manifold, based on
* the current Dehn filling coefficients. Sets the solution_type[filled]
* member of *manifold to the type of solution found. If
* this type is anything other than no_solution, stores the hyperbolic
* structure by setting the *shape[filled] field of each Tetrahedron in
* the Triangulation.
*
* The hyperbolic structure is computed using Newton's method; the
* initial guess is the previous Dehn filled solution.
*
* Returns: the type of solution found.
*/
extern SolutionType remove_Dehn_fillings(Triangulation *manifold);
/*
* Removes all Dehn fillings.
*
* Returns: the type of solution restored.
*/
/************************************************************************/
/* */
/* index_to_hue.c */
/* */
/************************************************************************/
extern double index_to_hue(unsigned int index);
/*
* Maps the nonnegative integers to a set of easily distinguishable hues.
*
* index 0 1 2 3 4 5 6 . . .
* hue 0 1/2 1/4 3/4 1/8 5/8 3/8 . . .
*/
extern double index_to_prettier_hue(unsigned int aHueIndex);
/*
* Similar to horoball_hue() but with a slightly different formula.
* (Note to self: Think about these different options at some point.)
*/
extern double horoball_hue(unsigned int index);
/*
* Provides hand chosen hues for indices 0-5, and uses index_to_hue()
* to interpolate thereafter. The hope is for nicer looking horoball
* packings.
*/
/************************************************************************/
/* */
/* interface.c */
/* */
/************************************************************************/
extern char *get_triangulation_name(Triangulation *manifold);
/*
* Return a pointer to the name of the Triangulation *manifold.
* The pointer points to the actual name, not a copy.
*/
extern void set_triangulation_name(Triangulation *manifold, const char *new_name);
/*
* Sets the Triangulation's name to new_name.
*/
extern SolutionType get_complete_solution_type(Triangulation *manifold);
/*
* Returns the SolutionType of the complete structure.
*/
extern SolutionType get_filled_solution_type(Triangulation *manifold);
/*
* Returns the SolutionType of the current Dehn filling.
*/
extern int get_num_tetrahedra(Triangulation *manifold);
/*
* Returns the number of tetrahedra in the Triangulation *manifold.
*/
extern Orientability get_orientability(Triangulation *manifold);
/*
* Returns the orientability of *manifold.
*/
extern int get_num_cusps(Triangulation *manifold);
/*
* Returns the number of cusps in *manifold.
*/
extern int get_num_or_cusps(Triangulation *manifold);
/*
* Returns the number of orientable cusps in *manifold.
*/
extern int get_num_nonor_cusps(Triangulation *manifold);
/*
* Returns the number of nonorientable cusps in *manifold.
*/
extern int get_max_singularity(Triangulation *manifold);
/*
* Returns the maximum value of gcd(m,l) over all integer Dehn filling
* coefficients (m,l) for filled cusps in *manifold.
*/
extern int get_num_generators(Triangulation *manifold);
/*
* Returns the number of generators being used to represent *manifold's
* fundamental group.
*/
extern void get_cusp_info( Triangulation *manifold,
int cusp_index,
CuspTopology *topology,
Boolean *is_complete,
double *m,
double *l,
Complex *initial_shape,
Complex *current_shape,
int *initial_shape_precision,
int *current_shape_precision,
Complex *initial_modulus,
Complex *current_modulus);
/*
* Provides information about the cusp whose index is cusp_index in
* *manifold. (The cusp indices run from zero to one less than the
* number of cusps.)
*
* *topology is set to torus_cusp, Klein_cusp, or unknown_topology.
* *is_complete is set to TRUE if the cusp is not Dehn filled, and
* FALSE if it is.
* *m and *l are set to the current Dehn filling coefficients.
* They will be meaningful only if the cusp is filled.
* If the cusp is nonorientable, only *m will be meaningful
* (because *l must be zero for a Klein bottle cusp -- see
* the comment at the top of holonomy.c).
* *initial_shape is set to the initial shape (longitude/meridian) of the
* cusp, i.e. the shape it had when all cusps were unfilled.
* *current_shape is set to the cusp's current shape if the cusp is_complete,
* zero otherwise.
* *initial_shape_precision is set to the number of decimal places of accuracy
* in the computed value of initial_shape.
* *current_shape_precision is set to the number of decimal places of accuracy
* in the computed value of current_shape.
* *initial_modulus is set to the modulus ( (second shortest translation)/
* (shortest translation) ) of the initial cusp shape.
* *current_modulus is set to the modulus of the current cusp shape.
*
* You may pass NULL for pointers to values you aren't interested in.
*/
extern FuncResult set_cusp_info(Triangulation *manifold,
int cusp_index,
Boolean cusp_is_complete,
double m,
double l);
/*
* Looks for a cusp with index cusp_index in Triangulation *manifold.
* If not found,
* alerts the user and exits (this should never occur
* unless there is a bug in the UI).
* If found,
* if cusp_is_complete is TRUE,
* sets the is_complete field of the cusp to TRUE, and
* sets the Dehn filling coefficients to 0.0,
* if cusp_is_complete is FALSE
* sets the is_complete field of the cusp to FALSE, and
* sets the Dehn filling coefficients to m and l.
*
* set_cusp_info() checks for errors in the values of m and l.
* The (0,0) Dehn filling is never allowed, and only (p,0) fillings are
* allowed on nonorientable cusps. If an error is detected, the cusp
* will be left unchanged.
*
* Returns:
* func_OK for success
* func_bad_input for illegal Dehn filling coefficients
*/
extern void get_holonomy( Triangulation *manifold,
int cusp_index,
Complex *meridional_holonomy,
Complex *longitudinal_holonomy,
int *meridional_precision,
int *longitudinal_precision);
/*
* Passes back the holonomies of the meridian and longitude,
* and an estimate of their precision (number of decimal
* digits to the right of the decimal point).
*/
extern void get_tet_shape( Triangulation *manifold,
int which_tet,
Boolean fixed_alignment,
double *shape_rect_real, /* OK to pass NULL */
double *shape_rect_imag, /* OK to pass NULL */
double *shape_log_real, /* OK to pass NULL */
double *shape_log_imag, /* OK to pass NULL */
int *precision_rect_real, /* OK to pass NULL */
int *precision_rect_imag, /* OK to pass NULL */
int *precision_log_real, /* OK to pass NULL */
int *precision_log_imag, /* OK to pass NULL */
Boolean *is_geometric); /* OK to pass NULL */
/*
* Provides information about the shape of the Tetrahedron in
* position which_tet in the linked list (which_tet takes a value
* in the range [0, (#tetrahedra - 1)] ). (Note: which_tet
* does not explicitly refer to the "index" field of the Tetrahedron
* data structure, although in practice it will coincide.)
* get_tet_shape() provides the shape of the Tetrahedron in both
* rectangular and logarithmic forms, relative to whatever coordinate
* system was used most recently. This means that the rectangular
* form will satisfy |z| < 1 and |z - 1| < 1. The last four arguments
* give the precision of the preceding four, expressed as the number
* of significant deciomal digits following the decimal point.
* (Warning: the precision is only a rough estimate. The last
* digit or two may sometimes be incorrect.) The flag *is_geometric
* is set to TRUE iff all dihedral angles lie in the range [0,pi].
*/
extern int get_num_edge_classes( Triangulation *manifold,
int edge_class_order,
Boolean greater_than_or_equal);
/*
* If greater_than_or_equal == TRUE, returns the number of EdgeClasses
* whose order is greater than or equal to edge_class_order.
* If greater_than_or_equal == FALSE, returns the number of EdgeClasses
* whose order is exactly edge_class_order.
*/
/************************************************************************/
/* */
/* isometry.c */
/* */
/************************************************************************/
extern FuncResult compute_isometries(
Triangulation *manifold0,
Triangulation *manifold1,
Boolean *are_isometric,
IsometryList **isometry_list,
IsometryList **isometry_list_of_links);
/*
* Checks whether manifold0 and manifold1 are isometric (taking into
* account the Dehn fillings). If manifold0 and manifold1 are cusped
* manifolds, sets *isometry_list and *isometry_list_of_links as
* in compute_cusped_isometries() below. Returns
* func_OK if all goes well,
* func_bad_input if some Dehn filling coefficients are not
* relatively prime integers,
* func_failed if it can't decide.
*/
extern int isometry_list_size(IsometryList *isometry_list);
/*
* Returns the number of Isometries in the IsometryList.
*/
extern int isometry_list_num_cusps(IsometryList *isometry_list);
/*
* Returns the number of cusps in each of the underlying manifolds.
* If the IsometryList is empty (as would be the case when the
* underlying manifolds have different numbers of cusps), then
* isometry_list_num_cusps()'s return value is undefined.
*/
extern void isometry_list_cusp_action( IsometryList *isometry_list,
int anIsometryIndex,
int aCusp,
int *cusp_image,
int cusp_map[2][2]);
/*
* Fills in the cusp_image and cusp_map[2][2] to describe the action
* of the given Isometry on the given Cusp.
*/
extern Boolean isometry_extends_to_link(IsometryList *isometry_list, int i);
/*
* Returns TRUE if Isometry i extends to the associated links (i.e. if it
* takes meridians to meridians), FALSE if it doesn't.
*/
extern void isometry_list_orientations(
IsometryList *isometry_list,
Boolean *contains_orientation_preserving_isometries,
Boolean *contains_orientation_reversing_isometries);
/*
* Says whether the IsometryList contains orientation-preserving
* and/or orientation-reversing elements. Assumes the underlying
* Triangulations are oriented.
*/
extern void free_isometry_list(IsometryList *isometry_list);
/*
* Frees the IsometryList.
*/
/************************************************************************/
/* */
/* isometry_cusped.c */
/* */
/************************************************************************/
extern Boolean same_triangulation( Triangulation *manifold0,
Triangulation *manifold1);
/*
* Check whether manifold0 and manifold1 have combinatorially
* equivalent triangulations (ignoring Dehn fillings).
* This function is less versatile than a call to
* compute_isometries(manifold0, manifold1, &are_isometric, NULL, NULL)
* but it's useful for batch processing, when you want to avoid the
* overhead of constantly recomputing canonical retriangulations.
*/
/************************************************************************/
/* */
/* length_spectrum.c */
/* */
/************************************************************************/
extern void length_spectrum( WEPolyhedron *polyhedron,
double cutoff_length,
Boolean full_rigor,
Boolean multiplicities,
double user_radius,
MultiLength **spectrum,
int *num_lengths);
/*
* Takes as input a manifold in the form of a Dirichlet domain, and
* finds all geodesics of length less than or equal to cutoff_length.
* Please length_spectrum.c for details.
*/
extern void free_length_spectrum(MultiLength *spectrum);
/*
* Deallocates the memory used to store the length spectrum.
*/
/*
* Added 2007/11/12:
*/
void ortholengths( Triangulation *manifold, /* input */
double tiling_radius, /* input */
Complex *shortest_geodesic, /* output */
double *tube_radius, /* output */
unsigned int *num_ortholengths, /* output */
Complex **ortholengths, /* output */
Complex **basings); /* output */
void free_ortholengths( Complex **ortholengths,
Complex **basings);
/*
* ortholengths() doesn't test its tiling_radius and so doesn't provide
* a rigorous guarantee of anything, but in practice it works.
*/
/************************************************************************/
/* */
/* link_complement.c */
/* */
/************************************************************************/
extern Triangulation *triangulate_link_complement(
KLPProjection *aLinkProjection);
/*
* Triangulate the complement of aLinkProjection.
*/
/************************************************************************/
/* */
/* matrix_conversion.c */
/* */
/************************************************************************/
extern void Moebius_to_O31(MoebiusTransformation *A, O31Matrix B);
extern void O31_to_Moebius(O31Matrix B, MoebiusTransformation *A);
/*
* Convert matrices back and forth between SL(2,C) and O(3,1).
*/
extern void Moebius_array_to_O31_array( MoebiusTransformation arrayA[],
O31Matrix arrayB[],
int num_matrices);
extern void O31_array_to_Moebius_array( O31Matrix arrayB[],
MoebiusTransformation arrayA[],
int num_matrices);
/*
* Convert arrays of matrices back and forth between SL(2,C) and O(3,1).
*/
extern Boolean O31_determinants_OK( O31Matrix arrayB[],
int num_matrices,
double epsilon);
/*
* Returns TRUE if all the O31Matrices in the array have determinants
* within epsilon of plus or minus one, and FALSE otherwise.
*/
/************************************************************************/
/* */
/* matrix_generators.c */
/* */
/************************************************************************/
extern void matrix_generators( Triangulation *manifold,
MoebiusTransformation generators[],
Boolean centroid_at_origin);
/*
* Computes the MoebiusTransformations representing the action
* of the generators of a manifold's fundamental group on the sphere at
* infinity. Writes the MoebiusTransformations to the array generators[],
* which it assumes has already been allocated. You may use
* get_num_generators() to determine how long an array to allocate.
* If centroid_at_origin is TRUE, the initial tetrahedron is positioned
* with its centroid at the origin; otherwise the initial tetrahedron
* is positioned with its vertices at {0, 1, infinity, z}.
*/
/************************************************************************/
/* */
/* my_malloc.c */
/* */
/************************************************************************/
extern void verify_my_malloc_usage(void);
/*
* The UI should call verify_my_malloc_usage() upon exit to verify that
* the number of calls to my_malloc() was exactly balanced by the number
* of calls to my_free(). In case of error, verify_my_malloc_usage()
* passes an appropriate message to uAcknowledge.
*/
/************************************************************************/
/* */
/* normal_surface_construction.c */
/* */
/************************************************************************/
extern FuncResult find_normal_surfaces( Triangulation *manifold,
NormalSurfaceList **surface_list);
/*
* Tries to find connected, embedded normal surfaces of nonnegative
* Euler characteristic. If spheres or projective planes are found,
* then tori and Klein bottles aren't reported, because from the point
* of view of the Geometrization Conjecture, one wants to cut along
* spheres and projective planes first. Surfaces are guaranteed to be
* connected. They aren't guaranteed to be incompressible, although
* typically they are. There is no guarantee that all such normal
* surfaces will be found. Returns its result as a pointer to a
* NormalSurfaceList, the internal structure of which is private to
* the kernel. To get information about the normal surfaces on the list,
* use the functions below. To split along a normal surface, call
* split_along_normal_surface(). When you're done with the
* NormalSurfaceList, free it using free_normal_surfaces().
*
* The present implementation works only for cusped manifolds.
* Returns func_bad_input for closed manifolds, or non-manifolds.
*/
extern int number_of_normal_surfaces_on_list(
NormalSurfaceList *surface_list);
/*
* Returns the number of normal surfaces contained in the list.
*/
extern Boolean normal_surface_is_orientable(
NormalSurfaceList *surface_list,
int index);
extern Boolean normal_surface_is_two_sided(
NormalSurfaceList *surface_list,
int index);
extern int normal_surface_Euler_characteristic(
NormalSurfaceList *surface_list,
int index);
/*
* Return information about a given normal surface on the list.
* The indices run from 0 through (number of surfaces - 1).
*/
extern void free_normal_surfaces(NormalSurfaceList *surface_list);
/*
* Frees an array of NormalSurfaceLists.
*/
/************************************************************************/
/* */
/* normal_surface_splitting.c */
/* */
/************************************************************************/
extern FuncResult split_along_normal_surface(
NormalSurfaceList *surface_list,
int index,
Triangulation *pieces[2]);
/*
* Splits the manifold (stored privately in the NormalSurfaceList)
* along the normal surface of the given index (indices range from 0 to
* (number of surfaces - 1)). If the normal surface is a 2-sided
* projective plane, split_along_normal_surface() returns func_bad_input;
* otherwise it returns func_OK. If the normal surface is a sphere or
* 1-sided projective plane, the resulting spherical boundary component(s)
* are capped off with 3-ball(s); otherwise the new torus or Klein bottle
* boundary component(s) become cusp(s). If the normal surface is
* nonseparating, the result is returned in pieces[0], and pieces[1]
* is set to NULL. If the normal surface is separating, the two pieces
* are returned in pieces[0] and pieces[1].
*/
/************************************************************************/
/* */
/* o31_matrices.c */
/* */
/************************************************************************/
/*
* Most of the functions in o31_matrices.c are private to the kernel.
* The following have been made available to the UI as well.
*/
extern double gl4R_determinant(GL4RMatrix m);
extern double o31_trace(O31Matrix m);
/************************************************************************/
/* */
/* orient.c */
/* */
/************************************************************************/
extern void reorient(Triangulation *manifold);
/*
* Reverse a manifold's orientation.
*/
/************************************************************************/
/* */
/* punctured_torus_bundles.c */
/* */
/************************************************************************/
extern void bundle_LR_to_monodromy( LRFactorization *anLRFactorization,
MatrixInt22 aMonodromy);
/*
* Multiplies out anLRFactorization to obtain aMonodromy.
*/
extern void bundle_monodromy_to_LR( MatrixInt22 aMonodromy,
LRFactorization **anLRFactorization);
/*
* If (det(aMonodromy) = +1 and |trace(aMonodromy)| >= 2) or
* (det(aMonodromy) = -1 and |trace(aMonodromy)| >= 1),
* then bundle_monodromy_to_LR() conjugates aMonodromy to a
* nonnegative or nonpositive matrix, and factors it as
* anLRFactorization. These cases include all monodromies of
* hyperbolic manifolds, as well as the nonhyperbolic cases
* (det(aMonodromy) = +1 and |trace(aMonodromy)| = 2), which
* the user might want to see factored just for fun.
* Otherwise bundle_monodromy_to_LR() sets
* (*anLRFactorization)->is_available to FALSE, but nevertheless
* sets negative_determinant and negative_trace correctly in case
* the UI wants to display them. The UI should indicate that the
* factorization is not available (e.g. by displaying "N/A") so
* the user doesn't confuse this case with an empty factorization.
*/
extern LRFactorization *alloc_LR_factorization(int aNumFactors);
extern void free_LR_factorization(LRFactorization *anLRFactorization);
/*
* Allocates/frees LRFactorizations.
*/
extern Triangulation *triangulate_punctured_torus_bundle(
LRFactorization *anLRFactorization);
/*
* If the manifold is hyperbolic (i.e. if the number of LR factors
* is at least two for an orientable bundle, or at least one for a
* nonorientable bundle), triangulates the complement and returns
* a pointer to it. Otherwise returns NULL.
*/
/************************************************************************/
/* */
/* representations.c */
/* */
/************************************************************************/
RepresentationList *find_representations( Triangulation *manifold,
int n,
PermutationSubgroup range);
/*
* Finds all transitive representations of a manifold's fundamental
* group into Z/n or S(n), for use in constructing n-sheeted covers.
* To dispose of the RepresentationList when you're done, use
* free_representation_list() below.
*/
void free_representation_list(
RepresentationList *representation_list);
/*
* Frees a RepresentationList.
*/
/************************************************************************/
/* */
/* shingling.c */
/* */
/************************************************************************/
extern Shingling *make_shingling(WEPolyhedron *polyhedron, int num_layers);
/*
* Constructs the shingling defined by the given Dirichlet domain.
* Please see the top of shingling.c for detailed documentation.
*/
extern void free_shingling(Shingling *shingling);
/*
* Releases the memory occupied by the shingling.
*/
extern void compute_center_and_radials( Shingle *shingle,
O31Matrix position,
double scale);
/*
* Uses shingle->normal along with the given position and scale to
* compute shingle->center, single->radialA and shingle->radialB.
*/
/************************************************************************/
/* */
/* shortest_cusp_basis.c */
/* */
/************************************************************************/
extern Complex cusp_modulus(Complex cusp_shape);
/*
* Accepts a cusp_shape (longitude/meridian) and returns the cusp modulus.
* Loosely speaking, the cusp modulus is defined as
* (second shortest translation)/(shortest translation); it is a complex
* number z lying in the region |Re(z)| <= 1/2 && |z| >= 1. If z lies
* on the boundary of this region, we choose it so that Re(z) >= 0.
*/
extern void shortest_cusp_basis( Complex cusp_shape,
MatrixInt22 basis_change);
/*
* Accepts a cusp_shape (longitude/meridian) and computes the 2 x 2 integer
* matrix which transforms the old basis (u, v) = (meridian, longitude)
* to the new basis (u', v') = (shortest, second shortest).
*/
extern Complex transformed_cusp_shape( Complex cusp_shape,
CONST MatrixInt22 basis_change);
/*
* Accepts a cusp_shape and a basis_change, and computes the shape of the
* cusp relative to the transformed basis. The transformed basis may or
* may not be the (shortest, second shortest) basis.
*/
extern void install_shortest_bases( Triangulation *manifold);
/*
* Installs the (shortest, second shortest) basis on each torus Cusp
* of manifold, but does not change the bases on Klein bottle cusps.
*/
/************************************************************************/
/* */
/* simplify_triangulation.c */
/* */
/************************************************************************/
extern void basic_simplification(Triangulation *manifold);
/*
* Simplifies the triangulation in a speedy yet effective manner.
*/
extern void randomize_triangulation(Triangulation *manifold);
/*
* Randomizes the Triangulation, and then resimplifies it.
*/
/************************************************************************/
/* */
/* sl2c_matrices.c */
/* */
/************************************************************************/
/*
* Most of the functions in sl2c_matrices.c are private to the kernel.
* The following has been made available to the UI as well.
*/
extern Complex sl2c_determinant(CONST SL2CMatrix m);
/*
* Returns the determinant of m.
*/
/************************************************************************/
/* */
/* symmetry_group.c */
/* */
/************************************************************************/
extern FuncResult compute_symmetry_group(
Triangulation *manifold,
SymmetryGroup **symmetry_group_of_manifold,
SymmetryGroup **symmetry_group_of_link,
Triangulation **symmetric_triangulation,
Boolean *is_full_group);
/*
* Computes the SymmetryGroup of a closed or cusped manifold.
* If the manifold is cusped, also computes the SymmetryGroup of the
* corresponding link (defined at the top of symmetry_group_cusped.c).
*/
extern void free_symmetry_group(SymmetryGroup *symmetry_group);
/*
* Frees a SymmetryGroup.
*/
/************************************************************************/
/* */
/* symmetry_group_info.c */
/* */
/************************************************************************/
extern Boolean symmetry_group_is_abelian( SymmetryGroup *symmetry_group,
AbelianGroup **abelian_description);
/*
* If the SymmetryGroup is abelian, sets *abelian_description to point
* to the SymmetryGroup's description as an AbelianGroup, and returns TRUE.
* Otherwise sets *abelian_description to NULL and returns FALSE.
*/
extern Boolean symmetry_group_is_dihedral(SymmetryGroup *symmetry_group);
/*
* Returns TRUE if the SymmetryGroup is dihedral, FALSE otherwise.
*/
extern Boolean symmetry_group_is_polyhedral(SymmetryGroup *symmetry_group,
Boolean *is_full_group,
int *p,
int *q,
int *r);
/*
* Returns TRUE if the SymmetryGroup is polyhedral, FALSE otherwise.
* If the SymmetryGroup is polyhedral, reports whether it's the full group
* (binary polyhedral, not just plain polyhedral), and reports the values
* for (p,q,r). The pointers for is_full_group, p, q and r may be NULL
* if this information is not desired.
*/
extern Boolean symmetry_group_is_S5(SymmetryGroup *symmetry_group);
/*
* Returns TRUE if the SymmetryGroup is the symmetric group on 5 letters,
* FALSE otherwise.
*/
extern Boolean symmetry_group_is_direct_product(SymmetryGroup *symmetry_group);
/*
* Returns TRUE if the SymmetryGroup is a nontrivial, nonabelian direct
* product, FALSE otherwise.
*/
extern SymmetryGroup *get_symmetry_group_factor(SymmetryGroup *symmetry_group,
int factor_number);
/*
* If the SymmetryGroup is a nontrivial, nonabelian direct product,
* returns a pointer to factor "factor_number" (factor_number = 0 or 1).
* Otherwise returns NULL. This is a pointer to the internal data
* structure -- not a copy! -- so please don't free it.
*/
extern Boolean symmetry_group_is_amphicheiral(SymmetryGroup *symmetry_group);
/*
* Returns TRUE if the SymmetryGroup contains orientation-reversing
* elements, FALSE otherwise. Assumes the underlying manifold is oriented.
*/
extern Boolean symmetry_group_invertible_knot(SymmetryGroup *symmetry_group);
/*
* Assumes the underlying manifold is oriented and has exactly
* one Cusp. Returns TRUE if some Symmetry acts on the Cusp
* via the matrix (-1, 0; 0, -1); returns FALSE otherwise.
*/
extern int symmetry_group_order(SymmetryGroup *symmetry_group);
/*
* Returns the order of the SymmetryGroup.
*/
extern int symmetry_group_product(SymmetryGroup *symmetry_group, int i, int j);
/*
* Returns the product of group elements i and j. We use the
* convention that products of symmetries read right to left.
* That is, the composition symmetry[i] o symmetry[j] acts by
* first doing symmetry[j], then symmetry[i].
*/
extern int symmetry_group_order_of_element(SymmetryGroup *symmetry_group, int i);
/*
* Returns the order of group element i.
*/
extern IsometryList *get_symmetry_list(SymmetryGroup *symmetry_group);
/*
* Returns the list of "raw" Isometries comprising a SymmetryGroup.
*/
extern SymmetryGroup *get_commutator_subgroup(SymmetryGroup *symmetry_group);
extern SymmetryGroup *get_abelianization (SymmetryGroup *symmetry_group);
/*
* Compute the commutator subgroup [G,G] and the abelianization G/[G,G].
* The UI should eventually use free_symmetry_group() to free them.
*/
extern SymmetryGroup *get_center(SymmetryGroup *symmetry_group);
/*
* Computes the center of G, which is the subgroup consisting of
* elements which commute with all elements in G.
* The UI should eventually use free_symmetry_group() to free it.
*/
extern SymmetryGroupPresentation *get_symmetry_group_presentation(
SymmetryGroup *symmetry_group);
/*
* Returns a presentation for the given SymmetryGroup.
* The internal structure of the SymmetryGroupPresentation is private
* to the kernel; use the functions below to get information about it.
* When you're done with it, use free_symmetry_group_presentation()
* to free the storage.
*/
extern int sg_get_num_generators(SymmetryGroupPresentation *group);
/*
* Returns the number of generators in the SymmetryGroupPresentation.
*/
extern int sg_get_num_relations(SymmetryGroupPresentation *group);
/*
* Returns the number of relations in the SymmetryGroupPresentation.
*/
extern int sg_get_num_factors( SymmetryGroupPresentation *group,
int which_relation);
/*
* Returns the number of factors in the specified relation.
* For example, the relation a^3 * b^-2 * c^5 has three factors.
* The parameter which_relation uses 0-based indexing.
*/
extern void sg_get_factor( SymmetryGroupPresentation *group,
int which_relation,
int which_factor,
int *generator,
int *power);
/*
* Reports the generator and power of the specified factor in the
* specified relation. For example, if relation 1 (i.e. the second
* relation) is a^3 * b^-2 * c^5, then passing which_relation = 1 and
* which_factor = 2 will cause it to report *generator = 2 and
* *power = 5.
*/
extern void free_symmetry_group_presentation(SymmetryGroupPresentation *group);
/*
* Frees the storage occupied by a SymmetryGroupPresentation.
*/
/************************************************************************/
/* */
/* terse_triangulation.c */
/* */
/************************************************************************/
extern TerseTriangulation *tri_to_terse(Triangulation *manifold);
extern TerseTriangulation *tri_to_canonical_terse(
Triangulation *manifold,
Boolean respect_orientation);
/*
* tri_to_terse() accepts a pointer to a Triangulation, computes
* a corresponding TerseTriangulation, and returns a pointer to it.
* tri_to_canonical_terse() is similar, but chooses the
* TerseTriangulation which is "least" among all possible choices
* of base Tetrahedron and base Permutation.
*/
extern Triangulation *terse_to_tri(TerseTriangulation *tt);
/*
* Accepts a pointer to a TerseTriangulation, expands it to a full
* Triangulation, and returns a pointer to it.
*/
extern void free_terse_triangulation(TerseTriangulation *tt);
/*
* Releases the memory used to store a TerseTriangulation.
*/
/************************************************************************/
/* */
/* triangulations.c */
/* */
/************************************************************************/
extern void data_to_triangulation( TriangulationData *data,
Triangulation **manifold_ptr);
/*
* Uses the TriangulationData (defined in triangulation_io.h) to
* construct a Triangulation. Sets *manifold_ptr to point to the
* Triangulation, or to NULL if it fails.
*/
extern void triangulation_to_data( Triangulation *manifold,
TriangulationData **data_ptr);
/*
* Allocates the TriangulationData and writes in the data describing
* the manifold. Sets *data_ptr to point to the result. The UI
* should call free_triangulation_data() when it's done with the
* TriangulationData.
*/
extern void free_triangulation_data(TriangulationData *data);
/*
* If the UI lets the kernel allocate a TriangulationData structure
* (as in a call to triangulation_to_data()), then the UI should
* call free_triangulation_data() to release it.
* If the UI allocates its own TriangulationData structure (as in
* preparing for a call to data_to_triangulation()), then the UI
* should release the structure itself.
*/
extern void free_triangulation(Triangulation *manifold);
/*
* If manifold != NULL, frees up the storage associated with a
* triangulation structure.
* If manifold == NULL, does nothing.
*/
extern void copy_triangulation(Triangulation *source, Triangulation **destination);
/*
* Makes a copy of the Triangulation *source.
*/
/************************************************************************/
/* */
/* two_bridge.c */
/* */
/************************************************************************/
extern void two_bridge( Triangulation *manifold,
Boolean *is_two_bridge, long int *p, long int *q);
/*
* Checks whether *manifold is the (conjectured) canonical triangulation
* of a 2-bridge knot or link complement. If it is, sets *is_two_bridge
* to TRUE and writes the fraction p/q describing the knot or link into
* (*p)/(*q). If it's not, sets *is_two_bridge to FALSE and leaves *p
* and *q undefined.
*/
/************************************************************************/
/* */
/* volume.c */
/* */
/************************************************************************/
extern double volume(Triangulation *manifold, int *precision);
/*
* Computes and returns the volume of the manifold.
* If the pointer "precision" is not NULL, estimates the number
* of decimal places of accuracy, and places the result in the
* variable *precision.
*/
#ifdef __cplusplus
}
#endif
#endif
|