Changeset a1ef3a2 in git for kernel/combinatorics


Ignore:
Timestamp:
Mar 27, 2021, 7:21:22 PM (3 years ago)
Author:
Karim Abou Zeid <karim23697@…>
Branches:
(u'fieker-DuVal', '117eb8c30fc9e991c4decca4832b1d19036c4c65')(u'spielwiese', 'c5facdfddea2addfd91babd8b9019161dea4b695')
Children:
80dee2b8505d045ce3d5bf4fa6bee7b4383af86c
Parents:
2daaaec2c36328eb8638fe3a6b61d9971c661dc4
git-author:
Karim Abou Zeid <karim23697@gmail.com>2021-03-27 19:21:22+01:00
git-committer:
Hans Schoenemann <hannes@mathematik.uni-kl.de>2021-03-30 00:45:51+02:00
Message:
implement kdim in kernel as vdim
Location:
kernel/combinatorics
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/combinatorics/hdegree.cc

    r2daaae ra1ef3a2  
    1919#include "kernel/combinatorics/stairc.h"
    2020#include "reporter/reporter.h"
     21
     22#ifdef HAVE_SHIFTBBA
     23#include <vector>
     24#include "Singular/libsingular.h"
     25#endif
    2126
    2227VAR int  hCo, hMu, hMu2;
     
    16681673}
    16691674
    1670 static void _lp_computeStandardWords(ideal words, int n, ideal M, int& last)
    1671 {
    1672   // assume <M> != <1>
    1673   if (n <= 0){
    1674     words->m[0] = pOne();
    1675     last = 0;
     1675// ATTENTION:
     1676//  - `words` contains the words normal modulo M of length n
     1677//  - `numberOfNormalWords` contains the number of words normal modulo M of length 0 ... n
     1678static void _lp_computeNormalWords(ideal words, int& numberOfNormalWords, int length, ideal M, int minDeg, int& last)
     1679{
     1680  if (length <= 0){
     1681    poly one = pOne();
     1682    if (p_LPDivisibleBy(M, one, currRing)) // 1 \in M => no normal words at all
     1683    {
     1684      pDelete(&one);
     1685      last = -1;
     1686      numberOfNormalWords = 0;
     1687    }
     1688    else
     1689    {
     1690      words->m[0] = one;
     1691      last = 0;
     1692      numberOfNormalWords = 1;
     1693    }
    16761694    return;
    16771695  }
    16781696
    1679   _lp_computeStandardWords(words, n - 1, M, last);
     1697  _lp_computeNormalWords(words, numberOfNormalWords, length - 1, M, minDeg, last);
    16801698
    16811699  int nVars = currRing->isLPring - currRing->LPncGenCount;
     1700  int numberOfNewNormalWords = 0;
    16821701
    16831702  for (int j = nVars - 1; j >= 0; j--)
     
    16931712        }
    16941713
    1695         int varOffset = ((n - 1) * currRing->isLPring) + 1;
     1714        int varOffset = ((length - 1) * currRing->isLPring) + 1;
    16961715        pSetExp(words->m[index], varOffset + j, 1);
    16971716        pSetm(words->m[index]);
    16981717        pTest(words->m[index]);
    16991718
    1700         if (p_LPDivisibleBy(M, words->m[index], currRing))
     1719        if (length >= minDeg && p_LPDivisibleBy(M, words->m[index], currRing))
    17011720        {
    17021721          pDelete(&words->m[index]);
    17031722          words->m[index] = NULL;
    17041723        }
     1724        else
     1725        {
     1726          numberOfNewNormalWords++;
     1727        }
    17051728      }
    17061729    }
     
    17081731
    17091732  last = nVars * last + nVars - 1;
    1710 }
    1711 
    1712 static ideal lp_computeStandardWords(int n, ideal M)
    1713 {
     1733
     1734  numberOfNormalWords += numberOfNewNormalWords;
     1735}
     1736
     1737static ideal lp_computeNormalWords(int length, ideal M)
     1738{
     1739  long minDeg = IDELEMS(M) > 0 ? pTotaldegree(M->m[0]) : 0;
     1740  for (int i = 1; i < IDELEMS(M); i++)
     1741  {
     1742    minDeg = si_min(minDeg, pTotaldegree(M->m[i]));
     1743  }
     1744
    17141745  int nVars = currRing->isLPring - currRing->LPncGenCount;
    17151746
    17161747  int maxElems = 1;
    1717   for (int i = 0; i < n; i++) // maxElems = nVars^n
     1748  for (int i = 0; i < length; i++) // maxElems = nVars^n
    17181749    maxElems *= nVars;
    17191750  ideal words = idInit(maxElems);
    1720   int last;
    1721   _lp_computeStandardWords(words, n, M, last);
     1751  int last, numberOfNormalWords;
     1752  _lp_computeNormalWords(words, numberOfNormalWords, length, M, minDeg, last);
    17221753  idSkipZeroes(words);
    17231754  return words;
     1755}
     1756
     1757static int lp_countNormalWords(int upToLength, ideal M)
     1758{
     1759  long minDeg = IDELEMS(M) > 0 ? pTotaldegree(M->m[0]) : 0;
     1760  for (int i = 1; i < IDELEMS(M); i++)
     1761  {
     1762    minDeg = si_min(minDeg, pTotaldegree(M->m[i]));
     1763  }
     1764
     1765  int nVars = currRing->isLPring - currRing->LPncGenCount;
     1766
     1767  int maxElems = 1;
     1768  for (int i = 0; i < upToLength; i++) // maxElems = nVars^n
     1769    maxElems *= nVars;
     1770  ideal words = idInit(maxElems);
     1771  int last, numberOfNormalWords;
     1772  _lp_computeNormalWords(words, numberOfNormalWords, upToLength, M, minDeg, last);
     1773  idDelete(&words);
     1774  return numberOfNormalWords;
    17241775}
    17251776
     
    17381789  int lV = currRing->isLPring;
    17391790
    1740   standardWords = lp_computeStandardWords(l, G);
     1791  standardWords = lp_computeNormalWords(l, G);
    17411792
    17421793  int n = IDELEMS(standardWords);
     
    18231874    int ncGenCount = currRing->LPncGenCount;
    18241875    if (lV - ncGenCount == 0)
     1876    {
     1877      idDelete(&G);
    18251878      return 0;
     1879    }
    18261880    if (lV - ncGenCount == 1)
     1881    {
     1882      idDelete(&G);
    18271883      return 1;
     1884    }
    18281885    if (lV - ncGenCount >= 2)
     1886    {
     1887      idDelete(&G);
    18291888      return -1;
     1889    }
    18301890  }
    18311891
     
    18401900    {
    18411901      WerrorS("GK-Dim not defined for 0-ring");
     1902      idDelete(&G);
    18421903      return -2;
    18431904    }
     
    18501911    int ncGenCount = currRing->LPncGenCount;
    18511912    if (IDELEMS(G) == lV - ncGenCount) // V = {1} no edges
     1913    {
     1914      idDelete(&G);
    18521915      return 0;
     1916    }
    18531917    if (IDELEMS(G) == lV - ncGenCount - 1) // V = {1} with loop
     1918    {
     1919      idDelete(&G);
    18541920      return 1;
     1921    }
    18551922    if (IDELEMS(G) <= lV - ncGenCount - 2) // V = {1} with more than one loop
     1923    {
     1924      idDelete(&G);
    18561925      return -1;
     1926    }
    18571927  }
    18581928
    18591929  ideal standardWords;
    18601930  intvec* UG = lp_ufnarovskiGraph(G, standardWords);
    1861   if (errorreported || UG == NULL) return -2;
    1862   return graphGrowth(UG);
     1931  if (UG == NULL)
     1932  {
     1933    idDelete(&G);
     1934    return -2;
     1935  }
     1936  if (errorreported)
     1937  {
     1938    delete UG;
     1939    idDelete(&G);
     1940    return -2;
     1941  }
     1942  int gkDim = graphGrowth(UG);
     1943  delete UG;
     1944  idDelete(&G);
     1945  return gkDim;
     1946}
     1947
     1948// converts an intvec matrix to a vector<vector<int> >
     1949static std::vector<std::vector<int> > iv2vv(intvec* M)
     1950{
     1951  int rows = M->rows();
     1952  int cols = M->cols();
     1953
     1954  std::vector<std::vector<int> > mat(rows, std::vector<int>(cols));
     1955
     1956  for (int i = 0; i < rows; i++)
     1957  {
     1958    for (int j = 0; j < cols; j++)
     1959    {
     1960      mat[i][j] = IMATELEM(*M, i + 1, j + 1);
     1961    }
     1962  }
     1963
     1964  return mat;
     1965}
     1966
     1967static void vvPrint(const std::vector<std::vector<int> >& mat)
     1968{
     1969  for (int i = 0; i < mat.size(); i++)
     1970  {
     1971    for (int j = 0; j < mat[i].size(); j++)
     1972    {
     1973      Print("%d ", mat[i][j]);
     1974    }
     1975    PrintLn();
     1976  }
     1977}
     1978
     1979static void vvTest(const std::vector<std::vector<int> >& mat)
     1980{
     1981  if (mat.size() > 0)
     1982  {
     1983    int cols = mat[0].size();
     1984    for (int i = 1; i < mat.size(); i++)
     1985    {
     1986      if (cols != mat[i].size())
     1987        WerrorS("number of cols in matrix inconsistent");
     1988    }
     1989  }
     1990}
     1991
     1992static void vvDeleteRow(std::vector<std::vector<int> >& mat, int row)
     1993{
     1994  mat.erase(mat.begin() + row);
     1995}
     1996
     1997static void vvDeleteColumn(std::vector<std::vector<int> >& mat, int col)
     1998{
     1999  for (int i = 0; i < mat.size(); i++)
     2000  {
     2001    mat[i].erase(mat[i].begin() + col);
     2002  }
     2003}
     2004
     2005static BOOLEAN vvIsRowZero(const std::vector<std::vector<int> >& mat, int row)
     2006{
     2007  for (int i = 0; i < mat[row].size(); i++)
     2008  {
     2009    if (mat[row][i] != 0)
     2010      return FALSE;
     2011  }
     2012  return TRUE;
     2013}
     2014
     2015static BOOLEAN vvIsColumnZero(const std::vector<std::vector<int> >& mat, int col)
     2016{
     2017  for (int i = 0; i < mat.size(); i++)
     2018  {
     2019    if (mat[i][col] != 0)
     2020      return FALSE;
     2021  }
     2022  return TRUE;
     2023}
     2024
     2025static BOOLEAN vvIsZero(const std::vector<std::vector<int> >& mat)
     2026{
     2027  for (int i = 0; i < mat.size(); i++)
     2028  {
     2029    if (!vvIsRowZero(mat, i))
     2030      return FALSE;
     2031  }
     2032  return TRUE;
     2033}
     2034
     2035static std::vector<std::vector<int> > vvMult(const std::vector<std::vector<int> >& a, const std::vector<std::vector<int> >& b)
     2036{
     2037  int ra = a.size();
     2038  int rb = b.size();
     2039  int ca = a.size() > 0 ? a[0].size() : 0;
     2040  int cb = b.size() > 0 ? b[0].size() : 0;
     2041
     2042  if (ca != rb)
     2043  {
     2044    WerrorS("matrix dimensions do not match");
     2045    return std::vector<std::vector<int> >();
     2046  }
     2047
     2048  std::vector<std::vector<int> > res(ra, std::vector<int>(cb));
     2049  for (int i = 0; i < ra; i++)
     2050  {
     2051    for (int j = 0; j < cb; j++)
     2052    {
     2053      int sum = 0;
     2054      for (int k = 0; k < ca; k++)
     2055        sum += a[i][k] * b[k][j];
     2056      res[i][j] = sum;
     2057    }
     2058  }
     2059  return res;
     2060}
     2061
     2062static BOOLEAN isAcyclic(const intvec* G)
     2063{
     2064  // init
     2065  int n = G->cols();
     2066  std::vector<int> path;
     2067  std::vector<BOOLEAN> visited;
     2068  std::vector<BOOLEAN> cyclic;
     2069  std::vector<int> cache;
     2070  visited.resize(n, FALSE);
     2071  cyclic.resize(n, FALSE);
     2072  cache.resize(n, -2);
     2073
     2074  for (int v = 0; v < n; v++)
     2075  {
     2076    cache = countCycles(G, v, path, visited, cyclic, cache);
     2077    // check that there are 0 cycles from v
     2078    if (cache[v] != 0)
     2079      return FALSE;
     2080  }
     2081  return TRUE;
     2082}
     2083
     2084/*
     2085 * Computation of the K-Dimension
     2086 */
     2087
     2088// -1 is infinity, -2 is error
     2089int lp_kDim(const ideal _G)
     2090{
     2091  if (rField_is_Ring(currRing)) {
     2092      WerrorS("K-Dim not implemented for rings");
     2093      return -2;
     2094  }
     2095
     2096  for (int i=IDELEMS(_G)-1;i>=0; i--)
     2097  {
     2098    if (_G->m[i] != NULL)
     2099    {
     2100      if (pGetComp(_G->m[i]) != 0)
     2101      {
     2102        WerrorS("K-Dim not implemented for modules");
     2103        return -2;
     2104      }
     2105      if (pGetNCGen(_G->m[i]) != 0)
     2106      {
     2107        WerrorS("K-Dim not implemented for bi-modules");
     2108        return -2;
     2109      }
     2110    }
     2111  }
     2112
     2113  ideal G = id_Head(_G, currRing); // G = LM(G) (and copy)
     2114  if (TEST_OPT_PROT)
     2115    Print("%d original generators\n", IDELEMS(G));
     2116  idSkipZeroes(G); // remove zeros
     2117  id_DelLmEquals(G, currRing); // remove duplicates
     2118  if (TEST_OPT_PROT)
     2119    Print("%d non-zero unique generators\n", IDELEMS(G));
     2120
     2121  // check if G is the zero ideal
     2122  if (IDELEMS(G) == 1 && G->m[0] == NULL)
     2123  {
     2124    // NOTE: this is needed because if the ideal is <0>, then idSkipZeroes keeps this element, and IDELEMS is still 1!
     2125    int lV = currRing->isLPring;
     2126    int ncGenCount = currRing->LPncGenCount;
     2127    if (lV - ncGenCount == 0)
     2128    {
     2129      idDelete(&G);
     2130      return 1;
     2131    }
     2132    if (lV - ncGenCount == 1)
     2133    {
     2134      idDelete(&G);
     2135      return -1;
     2136    }
     2137    if (lV - ncGenCount >= 2)
     2138    {
     2139      idDelete(&G);
     2140      return -1;
     2141    }
     2142  }
     2143
     2144  // get the max deg
     2145  long maxDeg = 0;
     2146  for (int i = 0; i < IDELEMS(G); i++)
     2147  {
     2148    maxDeg = si_max(maxDeg, pTotaldegree(G->m[i]));
     2149
     2150    // also check whether G = <1>
     2151    if (pIsConstantComp(G->m[i]))
     2152    {
     2153      WerrorS("K-Dim not defined for 0-ring"); // TODO is it minus infinity ?
     2154      idDelete(&G);
     2155      return -2;
     2156    }
     2157  }
     2158  if (TEST_OPT_PROT)
     2159    Print("max deg: %ld\n", maxDeg);
     2160
     2161
     2162  // for normal words of length minDeg ... maxDeg-1
     2163  // brute-force the normal words
     2164  if (TEST_OPT_PROT)
     2165    PrintS("Computing normal words normally...\n");
     2166  long numberOfNormalWords = lp_countNormalWords(maxDeg - 1, G);
     2167
     2168  if (TEST_OPT_PROT)
     2169    Print("%ld normal words up to length %ld\n", numberOfNormalWords, maxDeg - 1);
     2170
     2171  // early termination if G \subset X
     2172  if (maxDeg <= 1)
     2173  {
     2174    int lV = currRing->isLPring;
     2175    int ncGenCount = currRing->LPncGenCount;
     2176    if (IDELEMS(G) == lV - ncGenCount) // V = {1} no edges
     2177    {
     2178      idDelete(&G);
     2179      return numberOfNormalWords;
     2180    }
     2181    if (IDELEMS(G) == lV - ncGenCount - 1) // V = {1} with loop
     2182    {
     2183      idDelete(&G);
     2184      return -1;
     2185    }
     2186    if (IDELEMS(G) <= lV - ncGenCount - 2) // V = {1} with more than one loop
     2187    {
     2188      idDelete(&G);
     2189      return -1;
     2190    }
     2191  }
     2192
     2193  if (TEST_OPT_PROT)
     2194    PrintS("Computing Ufnarovski graph...\n");
     2195
     2196  ideal standardWords;
     2197  intvec* UG = lp_ufnarovskiGraph(G, standardWords);
     2198  if (UG == NULL)
     2199  {
     2200    idDelete(&G);
     2201    return -2;
     2202  }
     2203  if (errorreported)
     2204  {
     2205    delete UG;
     2206    idDelete(&G);
     2207    return -2;
     2208  }
     2209
     2210  if (TEST_OPT_PROT)
     2211    Print("Ufnarovski graph is %dx%d.\n", UG->rows(), UG->cols());
     2212
     2213  if (TEST_OPT_PROT)
     2214    PrintS("Checking whether Ufnarovski graph is acyclic...\n");
     2215
     2216  if (!isAcyclic(UG))
     2217  {
     2218    // in this case we have infinitely many normal words
     2219    return -1;
     2220  }
     2221
     2222  std::vector<std::vector<int> > vvUG = iv2vv(UG);
     2223  for (int i = 0; i < vvUG.size(); i++)
     2224  {
     2225    if (vvIsRowZero(vvUG, i) && vvIsColumnZero(vvUG, i)) // i is isolated vertex
     2226    {
     2227      vvDeleteRow(vvUG, i);
     2228      vvDeleteColumn(vvUG, i);
     2229      i--;
     2230    }
     2231  }
     2232  if (TEST_OPT_PROT)
     2233    Print("Simplified Ufnarovski graph to %ldx%ld.\n", vvUG.size(), vvUG.size());
     2234
     2235  // for normal words of length >= maxDeg
     2236  // use Ufnarovski graph
     2237  if (TEST_OPT_PROT)
     2238    PrintS("Computing normal words via Ufnarovski graph...\n");
     2239  std::vector<std::vector<int> > UGpower = vvUG;
     2240  long nUGpower = 1;
     2241  while (!vvIsZero(UGpower))
     2242  {
     2243    if (TEST_OPT_PROT)
     2244      PrintS("Start count graph entries.\n");
     2245    for (int i = 0; i < UGpower.size(); i++)
     2246    {
     2247      for (int j = 0; j < UGpower[i].size(); j++)
     2248      {
     2249        numberOfNormalWords += UGpower[i][j];
     2250      }
     2251    }
     2252
     2253    if (TEST_OPT_PROT)
     2254    {
     2255      PrintS("Done count graph entries.\n");
     2256      Print("%ld normal words up to length %ld\n", numberOfNormalWords, maxDeg - 1 + nUGpower);
     2257    }
     2258
     2259    if (TEST_OPT_PROT)
     2260      PrintS("Start mat mult.\n");
     2261    UGpower = vvMult(UGpower, vvUG); // TODO: avoid creation of new intvec
     2262    if (TEST_OPT_PROT)
     2263      PrintS("Done mat mult.\n");
     2264    nUGpower++;
     2265  }
     2266
     2267  delete UG;
     2268  idDelete(&G);
     2269  return numberOfNormalWords;
    18632270}
    18642271#endif
  • kernel/combinatorics/stairc.h

    r2daaae ra1ef3a2  
    3434#if HAVE_SHIFTBBA
    3535int lp_gkDim(const ideal G);
     36int lp_kDim(const ideal G);
    3637intvec * lp_ufnarovskiGraph(ideal G, ideal &standardWords);
    3738#endif
Note: See TracChangeset for help on using the changeset viewer.