43#ifndef _CHOMP_HOMOLOGY_CHAINS_H_
44#define _CHOMP_HOMOLOGY_CHAINS_H_
63template <
class eucl
idom>
66template <
class eucl
idom>
69template <
class eucl
idom>
72template <
class eucl
idom>
75template <
class eucl
idom>
79template <
class eucl
idom>
81template <
class eucl
idom>
92template <
class eucl
idom>
154 euclidom e,
int_t number = -1,
175 const char *label = NULL)
const;
179 std::ostream &
show (std::ostream &out,
const char *label = NULL)
const;
206template <
class eucl
idom>
212template <
class eucl
idom>
221 _n =
new int_t [len];
222 _e =
new euclidom [len];
224 throw "Not enough memory to create a chain copy.";
226 for (
int_t i = 0; i < len; ++ i)
234template <
class eucl
idom>
253 _n =
new int_t [len];
254 _e =
new euclidom [len];
256 throw "Not enough memory to create a chain copy =.";
261 for (
int_t i = 0; i < len; ++ i)
269template <
class eucl
idom>
280template <
class eucl
idom>
286template <
class eucl
idom>
292template <
class eucl
idom>
308 while ((i < len) && (_n [i] < n))
310 if ((i < len) && (_n [i] == n))
317template <
class eucl
idom>
320 for (
int_t i = 0; i < len; ++ i)
330template <
class eucl
idom>
334 throw "Wrong coefficient requested from a chain.";
338template <
class eucl
idom>
342 throw "Wrong number requested from a chain.";
346template <
class eucl
idom>
349 for (
int_t i = 0; i < len; ++ i)
351 if (_e [i]. delta () > 1)
357template <
class eucl
idom>
367 int_t best_delta = _e [0]. delta ();
372 for (
int_t i = 1; (i < len) && (best_delta > 1); ++ i)
375 int_t this_delta = _e [i]. delta ();
378 if (this_delta < best_delta)
380 best_delta = this_delta;
391 int_t best_length = table [_n [best_i]]. size ();
392 for (
int_t i = best_i + 1; i < len; ++ i)
394 if (_e [i]. delta () != best_delta)
396 int_t this_length = table [_n [i]]. size ();
397 if (best_length > this_length)
399 best_length = this_length;
409template <
class eucl
idom>
415 euclidom *old_e = _e;
418 _n =
new int_t [len + 1];
419 _e =
new euclidom [len + 1];
421 throw "Cannot add an element to a chain.";
427 for (
int_t j = 0; j < i; ++ j)
434 for (
int_t j = i + 1; j < len; ++ j)
436 _n [j] = old_n [j - 1];
437 _e [j] = old_e [j - 1];
450template <
class eucl
idom>
455 throw "Trying to remove an element from an empty chain.";
459 euclidom *old_e = _e;
464 _n =
new int_t [len - 1];
465 _e =
new euclidom [len - 1];
467 throw "Cannot add an element to a chain.";
474 for (
int_t j = 0; j < i; ++ j)
479 for (
int_t j = i; j < len; ++ j)
481 _n [j] = old_n [j + 1];
482 _e [j] = old_e [j + 1];
492template <
class eucl
idom>
497 if (number1 == number2)
501 if (number1 > number2)
506 while ((i1 < len) && (_n [i1] < number1))
509 while ((i2 < len) && (_n [i2] < number2))
513 if ((i1 < len) && (_n [i1] == number1))
516 if ((i2 < len) && (_n [i2] == number2))
521 euclidom temp = _e [i1];
522 for (
int_t i = i1 + 1; i < i2; ++ i)
527 _n [i2 - 1] = number2;
533 else if ((i2 < len) && (_n [i2] == number2))
535 euclidom temp = _e [i2];
536 for (
int_t i = i2; i > i1; -- i)
550template <
class eucl
idom>
559 while ((i < len) && (_n [i] < n))
563 if ((i < len) && (_n [i] == n))
570 return removepair (i);
578 return insertpair (i, n, e);
582template <
class eucl
idom>
587 while ((i < len) && (_n [i] < n))
591 if ((i < len) && (_n [i] == n))
592 return removepair (i);
597template <
class eucl
idom>
603 if ((e == 0) || !other. len)
607 int_t tablen = len + other. len;
609 euclidom *bigetab =
new euclidom [tablen];
610 if (!bigntab || !bigetab)
611 throw "Not enough memory to add chains.";
615 int_t i = 0, j = 0, k = 0;
618 while ((i < len) || (j < other. len))
623 bigntab [k] = other. _n [j];
624 bigetab [k] = e * other. _e [j];
628 table [bigntab [k]]. add (number,
634 else if ((j >= other. len) || (_n [i] < other. _n [j]))
636 bigntab [k] = _n [i];
637 bigetab [k] = _e [i];
642 else if (_n [i] > other. _n [j])
644 bigntab [k] = other. _n [j];
645 bigetab [k] = e * other. _e [j];
649 table [bigntab [k]]. add (number,
656 bigntab [k] = _n [i];
657 euclidom addelem = e * other. _e [j];
659 bigetab [k] = _e [i] + addelem;
661 if (!(bigetab [k] == 0))
665 table [bigntab [k]]. add (number,
672 table [bigntab [k]]. remove (number);
678 if ((k != len) || (k == tablen))
688 if ((k == len) && (k != tablen))
690 for (
int_t i = 0; i < len; ++ i)
692 _n [i] = bigntab [i];
693 _e [i] = bigetab [i];
713 _e =
new euclidom [k];
715 throw "Cannot shorten a sum of chains.";
717 for (
int_t i = 0; i < len; ++ i)
719 _n [i] = bigntab [i];
720 _e [i] = bigetab [i];
737template <
class eucl
idom>
752 while ((i < len) || (j < other. len))
757 n = other. _n [j ++];
758 else if (j >= other. len)
760 else if (_n [i] < other. _n [j])
762 else if (other. _n [j] < _n [i])
763 n = other. _n [j ++];
774 table [n]. swapnumbers (othernumber, number);
780template <
class eucl
idom>
800template <
class eucl
idom>
806 for (
int_t i = 0; i < len; ++ i)
808 if (_n [i] == number)
826 for (
int_t i = 0; i < len; ++ i)
848template <
class eucl
idom>
850 const char *label)
const
854 for (
int_t i = 0; i < len; ++ i)
857 int_t n = _n [i] + 1;
860 out << (i ?
" + " :
"") <<
861 (label ? label :
"") << n;
863 out << (i ?
" - " :
"-") <<
864 (label ? label :
"") << n;
866 out << (i ?
" + " :
"") << e <<
" * " <<
867 (label ? label :
"") << n;
872template <
class eucl
idom>
884template <
class eucl
idom>
893template <
class eucl
idom>
900 while (in. peek () != closing)
908 if (in. peek () !=
'*')
909 throw "The multiplication sign '*' while reading a chain.";
920 throw "A zero coefficient in a chain detected.";
929 if ((in. peek () ==
',') || (in. peek () ==
'+'))
949template <
class element>
976 throw "Copying constructor not implemented "
977 "for a simple list.";
984 throw "Operator = not implemented "
985 "for a simple list.";
1002template <
class element>
1008template <
class element>
1016template <
class element>
1019 element **newelem =
new element * [num + 1];
1020 for (
int i = 0; i < num; ++ i)
1021 newelem [i] = elem [i];
1022 newelem [num ++] = &m;
1028template <
class element>
1032 while ((pos < num) && (elem [pos] != &m))
1037 elem [pos] = elem [pos + 1];
1043template <
class element>
1053 return elem [cur ++];
1065template <
class eucl
idom>
1219 const char *txt = NULL)
const;
1225 const char *txt = NULL)
const;
1231 const char *label = NULL)
const;
1235 int_t howmany = 0,
const char *label =
"Row ")
const;
1239 int_t howmany = 0,
const char *label =
"Row ")
const;
1243 int_t howmany = 0,
const char *label =
"Col ")
const;
1247 int_t howmany = 0,
const char *label =
"Col ")
const;
1251 const char *maplabel = NULL,
1252 const char *xlabel = NULL,
const char *ylabel = NULL)
1256 std::ostream &
showmap (std::ostream &out,
const char *maplabel = NULL,
1257 const char *xlabel = NULL,
const char *ylabel = NULL)
1301 const euclidom &b,
int_t pos2);
1309 static void extendedGCD (
const euclidom &a,
const euclidom &b,
1310 euclidom &x, euclidom &y);
1322 const int_t setCols [],
1325 bool update_linked);
1337 const int_t setCols [],
1340 bool update_linked);
1346template <
class eucl
idom>
1348 allrows (0), allcols (0), rows (NULL), cols (NULL)
1353template <
class eucl
idom>
1363template <
class eucl
idom>
1367 if ((nrows > numrows) || (ncols > numcols))
1368 throw "Trying to define a matrix smaller than it really is";
1371 increase (numrows, numcols);
1380template <
class eucl
idom>
1394 throw "Not enough memory for matrix rows.";
1395 for (
int_t i = 0; i < m. allrows; ++ i)
1396 newrows [i] = m. rows [i];
1404 throw "Not enough memory for matrix columns.";
1406 newcols [i] = m. cols [i];
1411template <
class eucl
idom>
1423 allrows = m. allrows;
1424 allcols = m. allcols;
1432 throw "Not enough memory for matrix rows.";
1433 for (
int_t i = 0; i < m. allrows; ++ i)
1434 newrows [i] = m. rows [i];
1442 throw "Not enough memory for matrix columns.";
1443 for (
int_t i = 0; i < m.allcols; ++ i)
1444 newcols [i] = m. cols [i];
1451template <
class eucl
idom>
1454 if (!nrows && !ncols)
1455 increase (size, size);
1456 else if ((size > nrows) || (size > ncols))
1457 size = (nrows < ncols) ? nrows : ncols;
1458 for (
int_t i = 0; i < size; ++ i)
1467template <
class eucl
idom>
1472 throw "Incorrect row number.";
1474 throw "Incorrect column number.";
1478 increaserows (row + row / 2 + 1);
1484 increasecols (col + col / 2 + 1);
1489 cols [col]. add (row, e);
1490 rows [row]. add (col, e);
1494template <
class eucl
idom>
1498 if ((row >= nrows) || (col >= ncols))
1505 return rows [row]. getcoefficient (col);
1507 return cols [col]. getcoefficient (row);
1516template <
class eucl
idom>
1519 if ((n < 0) || (n >= nrows))
1520 throw "Incorrect row number.";
1524template <
class eucl
idom>
1527 if ((n < 0) || (n >= ncols))
1528 throw "Incorrect column number.";
1532template <
class eucl
idom>
1538template <
class eucl
idom>
1544template <
class eucl
idom>
1549 if ((dest < 0) || (dest >= nrows) || (source < 0) ||
1551 throw "Trying to add rows out of range.";
1554 rows [dest]. add (rows [source], e, dest, cols);
1558 while ((m = img_img. take ()) != NULL)
1560 m -> rows [dest]. add (m -> rows [source], e,
1563 while ((m = img_dom. take ()) != NULL)
1565 m -> cols [source]. add (m -> cols [dest], -e,
1571template <
class eucl
idom>
1576 if ((dest < 0) || (dest >= ncols) || (source < 0) ||
1578 throw "Trying to add columns out of range.";
1581 cols [dest]. add (cols [source], e, dest, rows);
1585 while ((m = dom_dom. take ()) != NULL)
1587 m -> cols [dest]. add (m -> cols [source], e,
1590 while ((m = dom_img. take ()) != NULL)
1592 m -> rows [source]. add (m -> rows [dest], -e,
1598template <
class eucl
idom>
1606 if ((i < 0) || (i >= nrows) || (j < 0) || (j >= nrows))
1607 throw "Trying to swap rows out of range.";
1610 rows [i].
swap (rows [j], i, j, cols);
1614 while ((m = img_img. take ()) != NULL)
1615 if ((m -> rows) && (m -> nrows))
1616 m -> rows [i].
swap (m -> rows [j], i, j, m -> cols);
1618 while ((m = img_dom. take ()) != NULL)
1619 if ((m -> cols) && (m -> ncols))
1620 m -> cols [i].
swap (m -> cols [j], i, j, m -> rows);
1625template <
class eucl
idom>
1633 if ((i < 0) || (i >= ncols) || (j < 0) || (j >= ncols))
1634 throw "Trying to swap cols out of range.";
1637 cols [i].
swap (cols [j], i, j, rows);
1641 while ((m = dom_dom. take ()) != NULL)
1642 if ((m -> cols) && (m -> ncols))
1643 m -> cols [i].
swap (m -> cols [j], i, j, m -> rows);
1645 while ((m = dom_img. take ()) != NULL)
1646 if ((m -> rows) && (m -> nrows))
1647 m -> rows [i].
swap (m -> rows [j], i, j, m -> cols);
1652template <
class eucl
idom>
1659 therow. multiply (e);
1662 for (
int_t i = 0; i < therow. size (); ++ i)
1663 cols [therow. num (i)]. multiply (e, n);
1668template <
class eucl
idom>
1675 thecol. multiply (e);
1678 for (
int_t i = 0; i < thecol. size (); ++ i)
1679 rows [thecol. num (i)]. multiply (e, n);
1684template <
class eucl
idom>
1690 int_t random_i = -1;
1693 int_t loopcounter = 0;
1698 i = random_i = std::rand () % (which ? nrows : ncols);
1703 int_t candidate = -1;
1704 int_t candidates_left = 3;
1707 if (which ? !ncols : !nrows)
1708 return (((req_elements > 0) ||
1709 (i >= (which ? nrows : ncols))) ? -1 : i);
1712 while (i < (which ? nrows : ncols))
1715 int_t l = (which ? rows : cols) [i]. size ();
1716 if ((req_elements >= 0) && (l >= req_elements))
1718 else if ((req_elements < 0) && !l)
1720 if (!candidates_left || !(which ? rows : cols) [i].
1721 contains_non_invertible ())
1729 random_i = std::rand () %
1730 (which ? nrows : ncols);
1738 if (++ i >= (which ? nrows : ncols))
1744 if ((random_i >= 0) && !loopcounter && (i >= random_i))
1752template <
class eucl
idom>
1755 return findrowcol (req_elements, start, 1);
1758template <
class eucl
idom>
1761 return findrowcol (req_elements, start, 0);
1764template <
class eucl
idom>
1768 throw "Trying to reduce a row out of range.";
1770 int_t the_other = -1;
1774 while ((len = rows [n]. size ()) > 1)
1780 int_t best_i = local. findbest (cols);
1783 int_t preferred_i = (preferred < 0) ? -1 :
1784 local. findnumber (preferred);
1788 if ((preferred_i >= 0) &&
1789 (local. coef (preferred_i). delta () ==
1790 local. coef (best_i). delta ()))
1791 best_i = preferred_i;
1794 the_other = local. num (best_i);
1797 for (
int_t i = 0; i < len; ++ i)
1804 euclidom quotient = local. coef (i) /
1805 local. coef (best_i);
1808 addcol (local. num (i), local. num (best_i),
1816template <
class eucl
idom>
1820 throw "Trying to reduce a column out of range.";
1822 int_t the_other = -1;
1826 while ((len = cols [n]. size ()) > 1)
1832 int_t best_i = local. findbest (rows);
1835 int_t preferred_i = (preferred < 0) ? -1 :
1836 local. findnumber (preferred);
1840 if ((preferred_i >= 0) &&
1841 (local. coef (preferred_i). delta () ==
1842 local. coef (best_i). delta ()))
1843 best_i = preferred_i;
1846 the_other = local. num (best_i);
1849 for (
int_t i = 0; i < len; ++ i)
1856 euclidom quotient = local. coef (i) /
1857 local. coef (best_i);
1860 addrow (local. num (i), local. num (best_i),
1868template <
class eucl
idom>
1871 const char *label)
const
1873 if ((first < 0) || (first >= tablen))
1875 if ((howmany <= 0) || (first + howmany > tablen))
1876 howmany = tablen - first;
1877 for (
int_t i = 0; i < howmany; ++ i)
1878 out << (label ? label :
"") << (first + i + 1) <<
": " <<
1879 table [first + i] <<
'\n';
1884template <
class eucl
idom>
1886 int_t first,
int_t howmany,
const char *label)
const
1888 return showrowscols (out, rows, nrows, first, howmany, label);
1891template <
class eucl
idom>
1893 int_t first,
int_t howmany,
const char *label)
const
1896 showrows (tout, first, howmany, label);
1900template <
class eucl
idom>
1902 int_t first,
int_t howmany,
const char *label)
const
1904 return showrowscols (out, cols, ncols, first, howmany, label);
1907template <
class eucl
idom>
1909 int_t first,
int_t howmany,
const char *label)
const
1912 showcols (tout, first, howmany, label);
1916template <
class eucl
idom>
1918 const char *maplabel,
const char *xlabel,
const char *ylabel)
const
1922 if (maplabel && (maplabel [0] ==
'\t'))
1927 for (
int_t i = 0; i < ncols; ++ i)
1929 out << (maplabel ? maplabel :
"f") <<
" (" <<
1930 (xlabel ? xlabel :
"") << (i + 1) <<
") = ";
1931 cols [i]. show (out, ylabel) <<
'\n';
1936template <
class eucl
idom>
1938 const char *maplabel,
const char *xlabel,
const char *ylabel)
const
1941 showmap (tout, maplabel, xlabel, ylabel);
1945template <
class eucl
idom>
1950 if (!nrows || !ncols)
1954 long countreduced = 0;
1955 long count = 4 * ((nrows > ncols) ? ncols : nrows);
1958 int_t nr =
static_cast<int_t> (std::rand () % nrows);
1968 if ((rows [nr]. size () == 1) &&
1969 (rows [nr]. coef (0). delta () == 1) &&
1970 (cols [rows [nr]. num (0)]. size () > 1))
1973 reducecol (rows [nr]. num (0), -1);
1981 nr_add = ((std::rand () >> 2) + 171) % nrows;
1991 if (!quiet && !(count % 373))
1992 scon << std::setw (12) << count <<
1993 "\b\b\b\b\b\b\b\b\b\b\b\b";
1997 sout << countreduced <<
" +";
2002template <
class eucl
idom>
2006 if (!nrows || !ncols)
2010 simple_reductions (quiet);
2016 int_t row, col, prev_row, prev_col;
2021 prev_row = -1, prev_col = -1;
2026 while ((row >= 0) || (col >= 0))
2029 while ((row >= 0) || (col >= 0))
2032 col = reducerow (row, prev_col);
2038 row = reducecol (col, prev_row);
2045 if (!quiet && !(count % 373))
2046 scon << std::setw (12) << count <<
2047 "\b\b\b\b\b\b\b\b\b\b\b\b";
2056 sout <<
" " << count <<
" reductions made. ";
2061template <
class eucl
idom>
2068 for (
int_t n = 0; n < ncols; ++ n)
2070 if (cols [n]. empty ())
2072 if (cols [n]. coef (0). delta () != 1)
2074 int_t r = cols [n]. num (0);
2083 if (invertible_count)
2084 *invertible_count = cur;
2087 for (
int_t n = cur; n < ncols; ++ n)
2089 if (cols [n]. empty ())
2091 int_t r = cols [n]. num (0);
2102template <
class eucl
idom>
2107 sout <<
"Determining the 'diagonal'... ";
2108 int_t indexBegin = 0;
2109 int_t indexEnd = arrange_towards_SNF (&indexBegin);
2112 sout << indexBegin <<
" invertible + " <<
2113 (indexEnd - indexBegin) <<
" noninvertible coefs.\n";
2118 sout <<
"Correcting the division condition... ";
2119 int_t countCorrections = 0;
2120 bool divisionOK =
false;
2126 for (
int_t index = indexBegin + 1; index < indexEnd; ++ index)
2128 euclidom e1 (
this -> get (index - 1, index - 1));
2129 euclidom e2 (
this -> get (index, index));
2130 if (e2 % e1 == zero)
2135 division_SNF_correction (e1, index - 1, e2, index);
2136 ++ countCorrections;
2139 sout << countCorrections <<
" corrections.\n";
2143template <
class eucl
idom>
2145 (
const euclidom &a,
int_t pos1,
const euclidom &b,
int_t pos2)
2153 extendedGCD (a, b, sigma, tau);
2154 euclidom beta (a * sigma + b * tau);
2155 euclidom alpha (a / beta);
2156 euclidom gamma (b / beta);
2166 this -> addcol (pos1, pos2, one);
2170 int_t setRowsCols [2];
2171 setRowsCols [0] = pos1;
2172 setRowsCols [1] = pos2;
2177 M. add (0, 0, sigma);
2179 M. add (1, 0, -gamma);
2180 M. add (1, 1, alpha);
2185 invM. define (2, 2);
2186 invM. add (0, 0, alpha);
2187 invM. add (0, 1, -tau);
2188 invM. add (1, 0, gamma);
2189 invM. add (1, 1, sigma);
2193 this -> mult_left (setRowsCols, setRowsCols, M, invM,
true);
2197 this -> addcol (pos2, pos1, (-tau) * gamma);
2203template <
class eucl
idom>
2205 (
const int_t setRows [],
2206 const int_t setCols [],
2217 int_t size = M. getnrows ();
2220 for (
int_t row = 0; row < size; ++ row)
2224 for (
int_t col = 0; col < size; ++ col)
2227 this -> getrow (setCols [col]);
2228 int_t rowSize = rowChain. size ();
2229 for (
int cur = 0; cur < rowSize; ++ cur)
2231 int_t num (rowChain. num (cur));
2232 if (affected. findnumber (num) < 0)
2233 affected. add (num, one);
2238 int_t col_count = affected. size ();
2239 for (
int_t col = 0; col < col_count; ++ col)
2241 int_t col_nr = affected. num (col);
2244 for (
int_t k = 0; k < size; ++ k)
2246 int_t row_k = setCols [k];
2247 e += M. get (row, k) *
2248 this -> get (row_k, col_nr);
2251 newRows [row]. add (col_nr, e);
2256 for (
int_t row = 0; row < size; ++ row)
2258 int_t row_nr = setRows [row];
2263 int_t len_prev = row_prev. size ();
2264 for (
int_t i = 0; i < len_prev; ++ i)
2266 int_t col_nr (row_prev. num (i));
2267 euclidom e (row_ch. getcoefficient (col_nr));
2270 euclidom coef (
this -> get (row_nr, col_nr));
2271 this -> add (row_nr, col_nr, -coef);
2276 int_t len = row_ch. size ();
2277 for (
int_t i = 0; i < len; ++ i)
2279 int_t col_nr (row_ch. num (i));
2280 euclidom e (row_ch. coef (i) -
2281 this -> get (row_nr, col_nr));
2283 this -> add (row_nr, col_nr, e);
2291 while ((m = img_img. take ()) != NULL)
2292 if ((m -> rows) && (m -> nrows))
2293 m -> mult_left (setRows, setCols, M, invM,
false);
2294 while ((m = img_dom. take ()) != NULL)
2295 if ((m -> cols) && (m -> ncols))
2296 m -> mult_right (setCols, setRows, invM, M,
false);
2301template <
class eucl
idom>
2303 (
const int_t setRows [],
2304 const int_t setCols [],
2315 int_t size = M. getncols ();
2318 for (
int_t col = 0; col < size; ++ col)
2322 for (
int_t row = 0; row < size; ++ row)
2325 this -> getcol (setRows [row]);
2326 int_t colSize = colChain. size ();
2327 for (
int cur = 0; cur < colSize; ++ cur)
2329 int_t num (colChain. num (cur));
2330 if (affected. findnumber (num) < 0)
2331 affected. add (num, one);
2336 int_t row_count = affected. size ();
2337 for (
int_t row = 0; row < row_count; ++ row)
2339 int_t row_nr = affected. num (row);
2342 for (
int_t k = 0; k < size; ++ k)
2344 int_t col_k = setRows [k];
2345 e +=
this -> get (row_nr, col_k) *
2349 newCols [col]. add (row_nr, e);
2354 for (
int_t col = 0; col < size; ++ col)
2356 int_t col_nr = setCols [col];
2361 int_t len_prev = col_prev. size ();
2362 for (
int_t i = 0; i < len_prev; ++ i)
2364 int_t row_nr (col_prev. num (i));
2365 euclidom e (col_ch. getcoefficient (row_nr));
2368 euclidom coef (
this -> get (row_nr, col_nr));
2369 this -> add (row_nr, col_nr, -coef);
2374 int_t len = col_ch. size ();
2375 for (
int_t i = 0; i < len; ++ i)
2377 int_t row_nr (col_ch. num (i));
2378 euclidom e (col_ch. coef (i) -
2379 this -> get (row_nr, col_nr));
2381 this -> add (row_nr, col_nr, e);
2389 while ((m = dom_dom. take ()) != NULL)
2390 if ((m -> cols) && (m -> ncols))
2391 m -> mult_left (setRows, setCols, M, invM,
false);
2392 while ((m = dom_img. take ()) != NULL)
2393 if ((m -> rows) && (m -> nrows))
2394 m -> mult_right (setCols, setRows, invM, M,
false);
2399template <
class eucl
idom>
2401 (
const euclidom &a,
const euclidom &b, euclidom &x, euclidom &y)
2403 euclidom aa (a), bb (b);
2404 euclidom xx, yy, lastx, lasty;
2411 euclidom quotient (aa / bb);
2412 euclidom remainder (aa % bb);
2415 euclidom xxx = lastx - quotient * xx;
2418 euclidom yyy = lasty - quotient * yy;
2427template <
class eucl
idom>
2432 throw "Trying to invert a non-square matrix.";
2440 m. identity (ncols);
2445 for (
int_t col = 0; col < ncols; ++ col)
2448 int_t len = cols [col]. size ();
2451 throw "Matrix inverting: Zero column found.";
2454 while ((chosen < len) &&
2455 ((cols [col]. num (chosen) < col) ||
2456 (cols [col]. coef (chosen). delta () != 1)))
2462 throw "Matrix inverting: "
2463 "No invertible element in a column.";
2469 invcoef = invcoef / cols [col]. coef (chosen);
2470 m. multiplyrow (cols [col]. num (chosen), invcoef);
2471 multiplyrow (cols [col]. num (chosen), invcoef);
2474 m. swaprows (col, cols [col]. num (chosen));
2475 swaprows (col, cols [col]. num (chosen));
2479 for (
int_t i = 0; i < len; ++ i)
2481 if (cols [col]. num (i) == col)
2483 euclidom coef = invcoef * cols [col]. coef (i);
2484 m. addrow (cols [col]. num (i), col, coef);
2485 addrow (cols [col]. num (i), col, coef);
2492 for (
int_t i = 0; i < ncols; ++ i)
2494 cols [i]. take (m. cols [i]);
2495 rows [i]. take (m. rows [i]);
2501template <
class eucl
idom>
2505 if (m1. ncols != m2. nrows)
2506 throw "Trying to multiply matrices of wrong sizes.";
2507 int_t K = m1. ncols;
2508 define (m1. nrows, m2. ncols);
2509 for (
int_t i = 0; i < nrows; ++ i)
2511 for (
int_t j = 0; j < ncols; ++ j)
2515 for (
int_t k = 0; k < K; ++ k)
2516 e += m1. get (i, k) * m2. get (k, j);
2523template <
class eucl
idom>
2527 for (
int_t i = 0; i < domain. size (); ++ i)
2529 for (
int_t j = 0; j < range. size (); ++ j)
2531 euclidom e = matr. get (domain. num (i),
2541template <
class eucl
idom>
2552 for (
int_t i = 0; i < cols [col]. size (); ++ i)
2555 while ((j < range. size ()) &&
2556 (range. num (j) < cols [col]. num (i)))
2562 if ((j < range. size ()) &&
2563 (range. num (j) == cols [col]. num (i)))
2569 if (-cols [col]. coef (i) == 1)
2571 else if (cols [col]. coef (i) != 1)
2572 out << cols [col]. coef (i) <<
" * ";
2586template <
class eucl
idom>
2591 show_hom_col (tout, col, range, txt);
2597template <
class eucl
idom>
2600 increaserows (numrows);
2601 increasecols (numcols);
2605template <
class eucl
idom>
2608 if (allrows >= numrows)
2612 throw "Not enough memory for matrix rows.";
2613 for (
int_t i = 0; i < nrows; ++ i)
2614 newrows [i]. take (rows [i]);
2622template <
class eucl
idom>
2625 if (allcols >= numcols)
2629 throw "Not enough memory for matrix columns.";
2630 for (
int_t i = 0; i < ncols; ++ i)
2631 newcols [i]. take (cols [i]);
2644template <
class eucl
idom>
2648 return m. showcols (out);
2660template <
class eucl
idom>
2668 chaincomplex (
int d,
int trace_generators = 0,
int trace_bases = 0);
2732 const int *level = NULL)
const;
2744 const int *level = NULL)
const;
2751 const int *level = NULL)
const;
2780 {
throw "Copy constructor not implemented "
2781 "for a chain complex.";}
2786 {
throw "Operator = not implemented "
2787 "for a chain complex.";
return *
this;}
2819template <
class eucl
idom>
2821 int trace_generators,
int trace_bases)
2824 len = (d >= 0) ? (d + 1) : 0;
2830 generators = (trace_generators && len) ?
2833 generators_initialized =
new int [len];
2835 generators_initialized = NULL;
2838 chgbases = (trace_bases && len) ?
2841 chgbases_initialized =
new int [len];
2843 chgbases_initialized = NULL;
2846 numgen = len ?
new int_t [len] : NULL;
2850 for (
int i = 0; i < len; ++ i)
2854 boundary [i]. dom_img. add (boundary [i + 1]);
2856 boundary [i]. img_dom. add (boundary [i - 1]);
2859 boundary [i]. dom_dom. add (generators [i]);
2862 boundary [i]. img_dom. add
2863 (generators [i - 1]);
2865 generators_initialized [i] = 0;
2869 boundary [i]. dom_img. add (chgbases [i]);
2872 boundary [i]. img_img. add
2875 chgbases_initialized [i] = 0;
2882template <
class eucl
idom>
2888 delete [] generators;
2893 if (generators_initialized)
2894 delete [] generators_initialized;
2895 if (chgbases_initialized)
2896 delete [] chgbases_initialized;
2900template <
class eucl
idom>
2903 if ((q < 0) || (q >= len))
2910 boundary [0]. define (0, numgen [q]);
2911 if ((q > 0) && (numgen [q - 1] >= 0))
2912 boundary [q]. define (numgen [q - 1], numgen [q]);
2913 if ((q < dim ()) && (numgen [q + 1] >= 0))
2914 boundary [q + 1]. define (numgen [q], numgen [q + 1]);
2919template <
class eucl
idom>
2923 if ((q <= 0) || (q >= len))
2924 throw "Trying to add a boundary for dimension out of range";
2926 if (numgen [q] <= n)
2928 if (numgen [q - 1] <= m)
2929 numgen [q - 1] = m + 1;
2931 boundary [q]. add (m, n, e);
2935template <
class eucl
idom>
2938 if ((q < 0) || (q >= len))
2939 throw "Boundary coefficient out of range from chain cplx.";
2941 return boundary [q]. get (row, col);
2944template <
class eucl
idom>
2948 if ((i < 0) || (i >= len))
2949 throw "Boundary matrix out of range from chain complex.";
2951 return boundary [i];
2954template <
class eucl
idom>
2957 if ((i < 0) || (i >= len))
2967template <
class eucl
idom>
2973template <
class eucl
idom>
2977 if ((q < 0) || (q >= len))
2978 throw "Level for homology generators out of range.";
2979 if (!generators || !generators_initialized [q])
2980 throw "Trying to get non-existent homology generators.";
2981 return generators [q]. getcol (i);
2984template <
class eucl
idom>
2988 if ((q < 0) || (q >= len))
2989 throw "Level for homology generators out of range.";
2990 if (!generators || !generators_initialized [q])
2991 throw "Trying to get non-existent homology generators.";
2992 return generators [q];
2995template <
class eucl
idom>
2999 if ((q < 0) || (q >= len))
3000 throw "Level for basis change matrix out of range.";
3001 if (!chgbases || !chgbases_initialized [q])
3002 throw "Trying to get non-existent basis change matrix.";
3003 return chgbases [q];
3006template <
class eucl
idom>
3015 if (!generators_initialized [which])
3016 generators [which]. identity (numgen [which]);
3017 generators_initialized [which] = 1;
3018 if ((which > 0) && (!generators_initialized [which - 1]))
3020 generators [which - 1]. identity
3021 (numgen [which - 1]);
3022 generators_initialized [which - 1] = 1;
3029 if (!chgbases_initialized [which])
3030 chgbases [which]. identity (numgen [which]);
3031 chgbases_initialized [which] = 1;
3032 if ((which > 0) && (!chgbases_initialized [which - 1]))
3034 chgbases [which - 1]. identity
3035 (numgen [which - 1]);
3036 chgbases_initialized [which - 1] = 1;
3043 int_t n = boundary [which]. getnrows ();
3045 if (other. getncols () < n)
3046 other. define (other. getnrows (), n);
3048 if (which < len - 1)
3050 int_t n = boundary [which]. getncols ();
3052 if (other. getnrows () < n)
3053 other. define (n, other. getncols ());
3057 if (!quiet && which)
3058 sout <<
"Reducing D_" << which <<
": ";
3059 boundary [which]. simple_form (quiet);
3060 if (!quiet && which)
3066template <
class eucl
idom>
3070 for (
int i = len - 1; i >= 0; -- i)
3072 if (!level || level [i] || (i && level [i - 1]))
3073 simple_form (i, quiet);
3078template <
class eucl
idom>
3082 int_t g = boundary [which]. findcol (-1, 0);
3086 if (which == dim ())
3089 e = boundary [which + 1]. get (g, -1);
3095 else if (e. delta () > 1)
3096 result. add (g, e. normalized ());
3097 g = boundary [which]. findcol (-1, g + 1);
3103template <
class eucl
idom>
3105 const int *level)
const
3116 throw "Not enough memory to create homology chains.";
3118 for (
int q = 0; q < len; ++ q)
3120 if (!level || level [q])
3121 simple_homology (result [q], q);
3127template <
class eucl
idom>
3133 for (
int q = 0; q < len; ++ q)
3134 def_gen (q, hom_chain [q]. size ());
3138template <
class eucl
idom>
3143 int max_level = len - 1;
3144 while ((max_level >= 0) && !hom [max_level]. size ())
3147 for (
int q = 0; q < max_level; ++ q)
3149 if (!level || level [q])
3151 out <<
"H_" << q <<
" = ";
3159template <
class eucl
idom>
3168template <
class eucl
idom>
3172 if (!generators || (q < 0) || (q >= len))
3174 for (
int_t i = 0; i < list. size (); ++ i)
3175 out << gethomgen (q, list. num (i)) <<
'\n';
3179template <
class eucl
idom>
3184 show_generators (tout, list, q);
3188template <
class eucl
idom>
3192 simple_form (level,
false);
3193 simple_homology (hom, level);
3198template <
class eucl
idom>
3203 compute_and_show_homology (tout, hom, level);
3210template <
class eucl
idom>
3214 out <<
"chain complex" <<
'\n';
3215 out <<
"max dimension " << c. dim () <<
'\n';
3216 out <<
"dimension 0: " << c. getnumgen (0) <<
'\n';
3217 for (
int i = 1; i <= c. dim (); ++ i)
3219 out <<
"dimension " << i <<
": " << c. getnumgen (i) <<
'\n';
3220 for (
int_t j = 0; j < c. getnumgen (i); ++ j)
3222 if (c. getboundary (i). getcol (j). size ())
3224 out <<
"\t# " << (j + 1) <<
" = " <<
3225 c. getboundary (i). getcol (j) <<
3241template <
class eucl
idom>
3281 const char *maplabel =
"f",
const char *xtxt = NULL,
3282 const char *ytxt = NULL,
const int *level = NULL)
const;
3287 std::ostream &
show (std::ostream &out,
3288 const char *maplabel =
"f",
const char *xtxt = NULL,
3289 const char *ytxt = NULL,
const int *level = NULL)
const;
3304 const char *xtxt = NULL,
const char *ytxt = NULL)
const;
3312 const int *level = NULL,
3313 const char *xtxt = NULL,
const char *ytxt = NULL)
3327template <
class eucl
idom>
3333 if (range. len < domain. len)
3342 for (
int i = 0; i < len; ++ i)
3345 map [i]. define (range. getnumgen (i),
3346 domain. getnumgen (i));
3349 domain. boundary [i]. dom_dom. add (map [i]);
3350 range. boundary [i]. dom_img. add (map [i]);
3351 if (i < domain. len - 1)
3352 domain. boundary [i + 1]. img_dom. add (map [i]);
3353 if (i < range. len - 1)
3354 range. boundary [i + 1]. img_img. add (map [i]);
3360template <
class eucl
idom>
3369 for (
int i = 0; i < len; ++ i)
3370 map [i] = c. map [i];
3375template <
class eucl
idom>
3388 for (
int i = 0; i < len; ++ i)
3389 map [i] = c. map [i];
3394template <
class eucl
idom>
3402template <
class eucl
idom>
3408template <
class eucl
idom>
3416template <
class eucl
idom>
3419 map [q]. add (m, n, e);
3423template <
class eucl
idom>
3427 if (!hom_domain || !hom_range)
3430 for (
int q = 0; q < len; ++ q)
3432 int_t dlen = hom_domain [q]. size ();
3434 int_t rlen = r. size ();
3435 map [q]. define (rlen, dlen);
3437 for (
int_t i = 0; i < dlen; ++ i)
3440 int_t x = hom_domain [q]. num (i);
3447 for (
int_t k = 0; k < img. size (); ++ k)
3450 while ((j < rlen) &&
3451 (r. num (j) < img. num (k)))
3456 (r. num (j) == img. num (k)))
3457 map [q]. add (j, i, img. coef (k));
3464template <
class eucl
idom>
3467 for (
int q = 0; q < len; ++ q)
3472template <
class eucl
idom>
3476 if ((m1. len < len) || (m2. len < len))
3477 throw "Trying to compose chain maps with too few levels.";
3478 for (
int q = 0; q < len; ++ q)
3479 map [q]. multiply (m1. map [q], m2. map [q]);
3483template <
class eucl
idom>
3485 const char *maplabel,
const char *xtxt,
const char *ytxt,
3486 const int *level)
const
3488 for (
int q = 0; q < len; ++ q)
3490 if (level && !level [q])
3492 out <<
"Dim " << q <<
":";
3493 map [q]. showmap (out, maplabel, xtxt, ytxt);
3498template <
class eucl
idom>
3500 const char *maplabel,
const char *xtxt,
const char *ytxt,
3501 const int *level)
const
3504 show (tout, maplabel, xtxt, ytxt, level);
3508template <
class eucl
idom>
3512 const char *xtxt,
const char *ytxt)
const
3514 int max_len = len - 1;
3515 while ((max_len >= 0) && !hom_domain [max_len]. size ())
3518 for (
int q = 0; q < max_len; ++ q)
3520 if (!level || level [q])
3522 out <<
"Dim " << q <<
":";
3523 int hlen = hom_domain [q]. size ();
3525 out <<
"\t0" <<
'\n';
3526 for (
int i = 0; i < hlen; ++ i)
3531 out << (i + 1) <<
") = ";
3532 map [q]. show_hom_col (out,
3533 hom_domain [q]. num (i),
3534 hom_range [q], ytxt);
3542template <
class eucl
idom>
3546 const char *xtxt,
const char *ytxt)
const
3549 show_homology (tout, hom_domain, hom_range, level, xtxt, ytxt);
3556template <
class eucl
idom>
3560 out <<
"chain map" <<
'\n';
3561 for (
int i = 0; i <= m. dim (); ++ i)
3563 out <<
"dimension " << i <<
'\n';
3564 for (
int_t j = 0; j < m [i]. getncols (); ++ j)
3566 if (m [i]. getcol (j). size ())
3568 out <<
"\t# " << (j + 1) <<
" = " <<
3569 m [i]. getcol (j) <<
'\n';
3583template <
class eucl
idom>
3587 int_t countfree = 0;
3588 bool writeplus =
false;
3589 for (
int_t i = 0; i < c. size (); ++ i)
3591 if (c. coef (i). delta () == 1)
3595 out << (writeplus ?
" + " :
"") <<
3601 if (countfree && ((i == c. size () - 1) ||
3602 (c. coef (i + 1). delta () != 1)))
3604 out << (writeplus ?
" + " :
"") <<
3607 out <<
"^" << countfree;
3622template <
class eucl
idom>
An auto_array template that mimics selected behaviors of the std::auto_ptr template,...
An auto_array template that mimics selected behaviors of the std::auto_ptr template,...
This class defines objects which represent chains as finite sequences of elements identified by integ...
chain< euclidom > & multiply(euclidom e, int_t number=-1)
Multiplies one or all the coefficients in the chain by the given number.
int_t findbest(chain< euclidom > *table=NULL) const
Finds the best element in the chain for reduction, that is, the element with minimal value of delta.
chain()
The default constructor.
chain< euclidom > & remove(int_t n)
Removes an element with the given identifier from the chain.
outputstream & show(outputstream &out, const char *label=NULL) const
Shows the chain to the output stream.
int_t findnumber(int_t n) const
Find the position of an element with the given identifier.
int_t len
The length of the list and the length of the table.
euclidom coef(int_t i) const
Returns the coefficient in front of the i-th element in the chain.
chain< euclidom > & insertpair(int_t i, int_t n, euclidom e)
Inserts one chain element at the given position.
chain< euclidom > & operator=(const chain< euclidom > &c)
The assignment operator.
int_t * _n
Identifiers of the elements of the chain (sorted).
euclidom getcoefficient(int_t n=-1) const
Finds and returns the coefficient in front of the given element.
int_t size() const
Returns the size of the chain, that is, the number of elements with non-zero coefficients.
chain< euclidom > & take(chain< euclidom > &c)
Takes data from another chain. Destroys the other chain.
chain< euclidom > & add(int_t n, euclidom e)
Adds an element algebraically to the chain.
euclidom * _e
Coefficients of the elements of the chain.
int_t num(int_t i) const
Returns the number (identifier) of the i-th element in the chain.
bool contains_non_invertible() const
Determines if the chain contains a non-invertible coefficient.
chain< euclidom > & swap(chain< euclidom > &other, int_t number=-1, int_t othernumber=-1, chain< euclidom > *table=NULL)
Swaps one chain with another.
chain< euclidom > & swapnumbers(int_t number1, int_t number2)
Swaps two numbers (identifiers) in the chain.
chain< euclidom > & removepair(int_t i)
Removes one chain element at the given position.
bool empty() const
Returns true if the chain is empty (zero), false otherwise.
This is an implementation of a chain complex over an arbitrary ring.
euclidom get(int q, int_t row, int_t col) const
Returns an element from the boundary matrix for the given dimension.
mmatrix< euclidom > * generators
Matrices which store actual combinations of generators.
chaincomplex(int d, int trace_generators=0, int trace_bases=0)
The default constructor.
const mmatrix< euclidom > & getchgbasis(int q) const
Returns the base change matrix at level q.
~chaincomplex()
The destructor.
void add(int q, int_t m, int_t n, const euclidom &e)
Adds a coefficient to the structure: D_q [m, n] += e.
outputstream & show_homology(outputstream &out, const chain< euclidom > *hom, const int *level=NULL) const
Writes the homology module of the chain complex to an output stream.
outputstream & compute_and_show_homology(outputstream &out, chain< euclidom > *&hom, const int *level=NULL)
Computes the homology and shows the result.
chaincomplex(const chaincomplex< euclidom > &m)
The copy constructor is not implemented.
int dim() const
Returns the dimension of the chain complex.
void simple_form(int which, bool quiet)
Reduces of the given boundary matrix in the chain complex for the purpose of homology computation.
int_t getnumgen(int i) const
Returns the number of generators at the given level.
mmatrix< euclidom > * chgbases
Matrices which store the change of basis to obtain the SNF.
const chain< euclidom > & gethomgen(int q, int_t i) const
Returns the given homology generator at level q.
const mmatrix< euclidom > & getboundary(int i) const
Returns a reference to the given boundary matrix.
int_t * numgen
The numbers of generators in each dimension, or -1's if not defined yet.
void take_homology(const chain< euclidom > *hom_chain)
Creates a chain complex containing exactly one generator for each homology generator.
int simple_homology(chain< euclidom > &result, int which) const
Computes the given level of homology of the chain complex, provided it has been transformed into the ...
outputstream & show_generators(outputstream &out, const chain< euclidom > &list, int q) const
Writes the homology generators of the homology module to an output stream.
mmatrix< euclidom > * boundary
The matrices of the boundary homomorphism.
int * chgbases_initialized
Have the base change tracing matrices been initialized to the identity (of suitable size each)?
int * generators_initialized
Have the generator tracing matrices been initialized to the identity (of suitable size each)?
int len
The length of the chain complex (i.e., its dimension + 1).
void def_gen(int q, int_t n)
Defines the number of generators in the given dimension.
This class defines a chain map between two chain complexes.
int dim() const
Returns the dimension of the chain map.
int len
The number of matrices (dimension of the chain map + 1).
void add(int q, int_t m, int_t n, euclidom e)
Adds a coefficient to the selected matrix of the map: M_q [m, n] += e.
chainmap< euclidom > & operator=(const chainmap< euclidom > &c)
The assignment operator.
const mmatrix< euclidom > & operator[](int i) const
Returns the matrix of the chain map at the given level.
void invert(void)
Inverts the chain map.
outputstream & show(outputstream &out, const char *maplabel="f", const char *xtxt=NULL, const char *ytxt=NULL, const int *level=NULL) const
Writes the chain map to an output stream in the text format using specified labels for the map and el...
mmatrix< euclidom > * map
The matrices in each dimension.
chainmap(const chaincomplex< euclidom > &domain, const chaincomplex< euclidom > &range)
The default constructor of a chain map between the two given chain complexes.
outputstream & show_homology(outputstream &out, const chain< euclidom > *hom_domain, const chain< euclidom > *hom_range, const int *level=NULL, const char *xtxt=NULL, const char *ytxt=NULL) const
Writes to an output stream the map induced in homology.
void take_homology(const chainmap< euclidom > &m, const chain< euclidom > *hom_domain, const chain< euclidom > *hom_range)
Creates a chain map that represents the map induced in homology by the chain map between the two give...
void compose(const chainmap< euclidom > &m1, const chainmap< euclidom > &m2)
Composes two given chain maps.
~chainmap()
The destructor.
A class for representing sparse matrices containing elements of the 'euclidom' type.
simplelist< mmatrix< euclidom > > img_img
void increaserows(int_t numrows)
Increases tables to be enough to keep the given number of rows.
const chain< euclidom > & getcol(int_t n) const
Returns a reference to the entire column stored as a chain.
outputstream & show_hom_col(outputstream &out, int_t col, const chain< euclidom > &range, const char *txt=NULL) const
Writes a column with only these coefficients which exist in 'range', and shows their positions in tha...
mmatrix()
The default constructor.
void define(int_t numrows, int_t numcols)
Defines the number of rows and columns and increases the internal tables if necessary.
simplelist< mmatrix< euclidom > > img_dom
int_t getnrows() const
Returns the number of rows in the matrix.
euclidom get(int_t row, int_t col) const
Returns the value at the desired location of the matrix.
int_t allrows
The number of allocated rows.
int_t arrange_towards_SNF(int_t *invertible_count=0)
Swaps rows and columns to make the simple form closer to SNF.
void addrow(int_t dest, int_t source, const euclidom &e)
Adds one row to another with a given coefficient.
int_t nrows
The number of rows in the matrix.
simplelist< mmatrix< euclidom > > dom_img
void addcol(int_t dest, int_t source, const euclidom &e)
Adds one column to another with a given coefficient.
outputstream & showrows(outputstream &out, int_t first=0, int_t howmany=0, const char *label="Row ") const
Writes the matrix to an output stream by its rows.
~mmatrix()
The destructor of a matrix.
void invert(void)
Inverts the matrix. Throws an error message on failure.
int_t reducerow(int_t n, int_t preferred)
Reduces the given row of the matrix and updates its columns.
void simple_form(bool quiet=false)
Transforms the matrix to a simple form (nearly SNF).
void swapcols(int_t i, int_t j)
Swaps two columns of the matrix.
void increasecols(int_t numcols)
Increases tables to be enough to keep the given number of columns.
chain< euclidom > * rows
The rows of the matrix.
int_t allcols
The number of allocated columns.
void mult_right(const int_t setRows[], const int_t setCols[], const mmatrix< euclidom > &M, const mmatrix< euclidom > &invM, bool update_linked)
Multiplies the matrix from the right by an invertible square matrix whose possibly nonzero entries ar...
int_t reducecol(int_t n, int_t preferred)
Reduces the given column of the matrix and updates its rows.
void division_SNF_correction(const euclidom &a, int_t pos1, const euclidom &b, int_t pos2)
Makes a correction of division in the "diagonal" at the given two positions, so that the entry at pos...
int_t ncols
The number of columns in the matrix.
simplelist< mmatrix< euclidom > > dom_dom
This is a list of matrices to be updated together with the changes to the columns or rows of the curr...
void swaprows(int_t i, int_t j)
Swaps two rows of the matrix.
void multiplycol(int_t n, const euclidom &e)
Multiplies the column by the given coefficient and updates rows.
outputstream & showmap(outputstream &out, const char *maplabel=NULL, const char *xlabel=NULL, const char *ylabel=NULL) const
Writes the matrix as a linear map on generators.
outputstream & showrowscols(outputstream &out, chain< euclidom > *table, int_t tablen, int_t first=0, int_t howmany=0, const char *label=NULL) const
Writes the matrix to an output stream by its rows or columns.
static void extendedGCD(const euclidom &a, const euclidom &b, euclidom &x, euclidom &y)
Extended Euclidean algorithm for the computation of the greatest common divisor, together with the co...
void increase(int_t numrows, int_t numcols)
Increases tables to be enough to keep the given number of columns and rows.
void add(int_t row, int_t col, const euclidom &e)
Adds a value to the given element of the matrix.
void multiplyrow(int_t n, const euclidom &e)
Multiplies the row by the given coefficient and updates columns.
const chain< euclidom > & getrow(int_t n) const
Returns a reference to the entire row stored as a chain.
int_t getncols() const
Returns the number of columns in the matrix.
chain< euclidom > * cols
The columns of the matrix.
outputstream & showcols(outputstream &out, int_t first=0, int_t howmany=0, const char *label="Col ") const
Writes the matrix to an output stream by its rows.
void identity(int_t size)
Defines the matrix to be the identity of the given size.
void multiply(const mmatrix< euclidom > &m1, const mmatrix< euclidom > &m2)
Computes the product of the two given matrices.
void simple_reductions(bool quiet=false)
Runs some random simple reductions.
void mult_left(const int_t setRows[], const int_t setCols[], const mmatrix< euclidom > &M, const mmatrix< euclidom > &invM, bool update_linked)
Multiplies the matrix from the left by an invertible square matrix whose possibly nonzero entries are...
int_t findrowcol(int_t req_elements, int_t start, int which) const
An internal procedure for both findrow and findcol.
int_t findrow(int_t req_elements=1, int_t start=-1) const
Finds a row containing at least the required number of nonzero elements, starting at the given row.
mmatrix< euclidom > & operator=(const mmatrix< euclidom > &s)
The assignment operator.
int_t findcol(int_t req_elements=1, int_t start=-1) const
Finds a column containing at least the required number of nonzero elements, starting at the given col...
void submatrix(const mmatrix< euclidom > &matr, const chain< euclidom > &domain, const chain< euclidom > &range)
Extracts a submatrix from the given matrix.
void simple_form_to_SNF(bool quiet=false)
Transforms the matrix from the simple form to actual SNF.
This class defines an output stream for replacing the standard 'cout'.
This class defines a simple list of pointers to objects of the given type.
simplelist()
The default constructor of an empty list.
simplelist< element > & operator=(const simplelist< element > &s)
The assignment operator is not implemented.
element * take()
A simple internal iterator of the list.
void remove(element &m)
Remove an element from the list.
void add(element &m)
Adds an element to the list.
simplelist(const simplelist< element > &s)
The copy constructor is not implemented.
int cur
The current element in the table.
element ** elem
A table of element pointers.
int num
The number of element pointers stored in the list.
~simplelist()
The destructor.
This file contains some precompiler definitions which indicate the operating system and/or compiler u...
int int_t
Index type for indexing arrays, counting cubes, etc.
const char * ringsymbol()
outputstream & show_homology(outputstream &out, const chain< euclidom > &c)
Shows a chain as a list of generators of one level of a homology module.
outputstream sout
A replacement for standard output stream, with optional logging and other features provided by the cl...
void swapelements(type &x, type &y)
A simple template for swapping two elements with the use of a temporary variable of the same type and...
std::ostream & operator<<(std::ostream &out, const bincube< Dim, twoPower > &b)
int readparenthesis(std::istream &in)
Reads an opening parenthesis from the input file.
std::istream & operator>>(std::istream &in, bincube< Dim, twoPower > &b)
outputstream scon
The console output stream to which one should put all the junk that spoils the log file,...
void ignorecomments(std::istream &in)
Ignores white characters (spaces, tabulators, CRs and LFs), as well as comments from the input text f...
void swap(mwWorkerData &data1, mwWorkerData &data2)
This namespace contains the entire CHomP library interface.
This file contains some useful functions related to the text input/output procedures.