Ignore:
Timestamp:
Jun 4, 2019, 2:33:32 PM (5 years ago)
Author:
Karim Abou Zeid <karim23697@…>
Branches:
(u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
Children:
d4cec6ab781a81162945ff680935242fcccc952a
Parents:
56ff8efc45f5392a6e465782a66a5df5a54180f01708fac9cfbd392cceea00167eaa2746d291cd98
Message:
Merge branch 'spielwiese' into stable
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Singular/dyn_modules/freealgebra/freealgebra.cc

    r1708fa rd906dc  
    11#include "Singular/libsingular.h"
     2#include <vector>
    23
    34#ifdef HAVE_SHIFTBBA
     
    8081}
    8182
     83static BOOLEAN p_LPDivisibleBy(ideal I, poly p, ring r)
     84{
     85  for(int i = 0; i < IDELEMS(I); i++)
     86  {
     87    if (p_LPDivisibleBy(I->m[i], p, r))
     88    {
     89      return TRUE;
     90    }
     91  }
     92  return FALSE;
     93}
     94
    8295static BOOLEAN lpLmDivides(leftv res, leftv h)
    8396{
     
    97110    poly q=(poly)h->next->Data();
    98111    res->rtyp = INT_CMD;
    99     for(int i=0;i<IDELEMS(I);i++)
    100     {
    101       if (p_LPDivisibleBy(I->m[i],q, currRing))
    102       {
    103         res->data=(void*)(long)1;
    104         return FALSE;
    105       }
    106     }
    107     res->data=(void*)(long)0;
     112    res->data=(void*)(long) p_LPDivisibleBy(I, q, currRing);
    108113    return FALSE;
    109114  }
     
    124129  else return TRUE;
    125130}
     131
     132static void _computeStandardWords(ideal words, int n, ideal M, int& last)
     133{
     134  if (n <= 0){
     135    words->m[0] = pOne();
     136    last = 0;
     137    return;
     138  }
     139
     140  _computeStandardWords(words, n - 1, M, last);
     141
     142  int nVars = currRing->isLPring;
     143
     144  for (int j = nVars - 1; j >= 0; j--)
     145  {
     146    for (int i = last; i >= 0; i--)
     147    {
     148      int index = (j * (last + 1)) + i;
     149
     150      if (words->m[i] != NULL)
     151      {
     152        if (j > 0) {
     153          words->m[index] = pCopy(words->m[i]);
     154        }
     155
     156        int varOffset = ((n - 1) * nVars) + 1;
     157        pSetExp(words->m[index], varOffset + j, 1);
     158        pSetm(words->m[index]);
     159        pTest(words->m[index]);
     160
     161        if (p_LPDivisibleBy(M, words->m[index], currRing))
     162        {
     163          pDelete(&words->m[index]);
     164          words->m[index] = NULL;
     165        }
     166      }
     167    }
     168  }
     169
     170  last = nVars * last + nVars - 1;
     171}
     172
     173static ideal computeStandardWords(int n, ideal M)
     174{
     175  int nVars = currRing->isLPring;
     176
     177  int maxElems = 1;
     178  for (int i = 0; i < n; i++) // maxElems = nVars^n
     179    maxElems *= nVars;
     180  ideal words = idInit(maxElems);
     181  int last;
     182  _computeStandardWords(words, n, M, last);
     183  idSkipZeroes(words);
     184  return words;
     185}
     186
     187// NULL if graph is undefined
     188static intvec* ufnarovskiGraph(ideal G)
     189{
     190  long l = 0;
     191  for (int i = 0; i < IDELEMS(G); i++)
     192    l = si_max(pTotaldegree(G->m[i]), l);
     193  l--;
     194  if (l <= 0)
     195  {
     196    WerrorS("Ufnarovski graph not implemented for l <= 0");
     197    return NULL;
     198  }
     199  int lV = currRing->isLPring;
     200
     201  ideal standardWords = computeStandardWords(l, G);
     202
     203  int n = IDELEMS(standardWords);
     204  intvec* UG = new intvec(n, n, 0);
     205  for (int i = 0; i < n; i++)
     206  {
     207    for (int j = 0; j < n; j++)
     208    {
     209      poly v = standardWords->m[i];
     210      poly w = standardWords->m[j];
     211
     212      // check whether v*x1 = x2*w (overlap)
     213      bool overlap = true;
     214      for (int k = 1; k <= (l - 1) * lV; k++)
     215      {
     216        if (pGetExp(v, k + lV) != pGetExp(w, k)) {
     217          overlap = false;
     218          break;
     219        }
     220      }
     221
     222      if (overlap)
     223      {
     224        // create the overlap
     225        poly p = pMult(pCopy(v), p_LPVarAt(w, l, currRing));
     226
     227        // check whether the overlap is normal
     228        bool normal = true;
     229        for (int k = 0; k < IDELEMS(G); k++)
     230        {
     231          if (p_LPDivisibleBy(G->m[k], p, currRing))
     232          {
     233            normal = false;
     234            break;
     235          }
     236        }
     237
     238        if (normal)
     239        {
     240          IMATELEM(*UG, i + 1, j + 1) = 1;
     241        }
     242      }
     243    }
     244  }
     245  return UG;
     246}
     247
     248static std::vector<int> countCycles(const intvec* _G, int v, std::vector<int> path, std::vector<BOOLEAN> visited, std::vector<BOOLEAN> cyclic, std::vector<int> cache)
     249{
     250  intvec* G = ivCopy(_G); // modifications must be local
     251
     252  if (cache[v] != -2) return cache; // value is already cached
     253
     254  visited[v] = TRUE;
     255  path.push_back(v);
     256
     257  int cycles = 0;
     258  for (int w = 0; w < G->cols(); w++)
     259  {
     260    if (IMATELEM(*G, v + 1, w + 1)) // edge v -> w exists in G
     261    {
     262      if (!visited[w])
     263      { // continue with w
     264        cache = countCycles(G, w, path, visited, cyclic, cache);
     265        if (cache[w] == -1)
     266        {
     267          cache[v] = -1;
     268          return cache;
     269        }
     270        cycles = si_max(cycles, cache[w]);
     271      }
     272      else
     273      { // found new cycle
     274        int pathIndexOfW = -1;
     275        for (int i = path.size() - 1; i >= 0; i--) {
     276          if (cyclic[path[i]] == 1) { // found an already cyclic vertex
     277            cache[v] = -1;
     278            return cache;
     279          }
     280          cyclic[path[i]] = TRUE;
     281
     282          if (path[i] == w) { // end of the cycle
     283            assume(IMATELEM(*G, v + 1, w + 1) != 0);
     284            IMATELEM(*G, v + 1, w + 1) = 0; // remove edge v -> w
     285            pathIndexOfW = i;
     286            break;
     287          } else {
     288            assume(IMATELEM(*G, path[i - 1] + 1, path[i] + 1) != 0);
     289            IMATELEM(*G, path[i - 1] + 1, path[i] + 1) = 0; // remove edge vi-1 -> vi
     290          }
     291        }
     292        assume(pathIndexOfW != -1); // should never happen
     293        for (int i = path.size() - 1; i >= pathIndexOfW; i--) {
     294          cache = countCycles(G, path[i], path, visited, cyclic, cache);
     295          if (cache[path[i]] == -1)
     296          {
     297            cache[v] = -1;
     298            return cache;
     299          }
     300          cycles = si_max(cycles, cache[path[i]] + 1);
     301        }
     302      }
     303    }
     304  }
     305  cache[v] = cycles;
     306
     307  delete G;
     308  return cache;
     309}
     310
     311// -1 is infinity
     312static int graphGrowth(const intvec* G)
     313{
     314  // init
     315  int n = G->cols();
     316  std::vector<int> path;
     317  std::vector<BOOLEAN> visited;
     318  std::vector<BOOLEAN> cyclic;
     319  std::vector<int> cache;
     320  visited.resize(n, FALSE);
     321  cyclic.resize(n, FALSE);
     322  cache.resize(n, -2);
     323
     324  // get max number of cycles
     325  int cycles = 0;
     326  for (int v = 0; v < n; v++)
     327  {
     328    cache = countCycles(G, v, path, visited, cyclic, cache);
     329    if (cache[v] == -1)
     330      return -1;
     331    cycles = si_max(cycles, cache[v]);
     332  }
     333  return cycles;
     334}
     335
     336// -1 is infinity, -2 is error
     337static int gkDim(const ideal _G)
     338{
     339  if (rField_is_Ring(currRing)) {
     340      WerrorS("GK-Dim not implemented for rings");
     341      return -2;
     342  }
     343
     344  for (int i=IDELEMS(_G)-1;i>=0; i--)
     345  {
     346    if (pGetComp(_G->m[i]) != 0)
     347    {
     348      WerrorS("GK-Dim not implemented for modules");
     349      return -2;
     350    }
     351  }
     352
     353  ideal G = id_Head(_G, currRing); // G = LM(G) (and copy)
     354  idSkipZeroes(G); // remove zeros
     355  id_DelLmEquals(G, currRing); // remove duplicates
     356
     357  // get the max deg
     358  long maxDeg = 0;
     359  for (int i = 0; i < IDELEMS(G); i++)
     360  {
     361    maxDeg = si_max(maxDeg, pTotaldegree(G->m[i]));
     362
     363    // also check whether G = <1>
     364    if (pIsConstantComp(G->m[i]))
     365    {
     366      WerrorS("GK-Dim not defined for 0-ring");
     367      return -2;
     368    }
     369  }
     370
     371  // early termination if G \subset X
     372  if (maxDeg <= 1)
     373  {
     374    int lV = currRing->isLPring;
     375    if (IDELEMS(G) == lV) // V = {1} no edges
     376      return 0;
     377    if (IDELEMS(G) == lV - 1) // V = {1} with loop
     378      return 1;
     379    if (IDELEMS(G) <= lV - 2) // V = {1} with more than one loop
     380      return -1;
     381  }
     382
     383  intvec* UG = ufnarovskiGraph(G);
     384  if (errorreported || UG == NULL) return -2;
     385  return graphGrowth(UG);
     386}
     387
     388
     389static BOOLEAN lpGkDim(leftv res, leftv h)
     390{
     391  const short t[]={1,IDEAL_CMD};
     392  if (iiCheckTypes(h,t,1))
     393  {
     394    assumeStdFlag(h);
     395    ideal G = (ideal) h->Data();
     396    res->rtyp = INT_CMD;
     397    res->data = (void*)(long) gkDim(G);
     398    if (errorreported) return TRUE;
     399    return FALSE;
     400  }
     401  else return TRUE;
     402}
    126403#endif
    127404
     
    134411  p->iiAddCproc("freealgebra.so","lpLmDivides",FALSE,lpLmDivides);
    135412  p->iiAddCproc("freealgebra.so","lpVarAt",FALSE,lpVarAt);
     413  p->iiAddCproc("freealgebra.so","lpGkDim",FALSE,lpGkDim);
     414
    136415  p->iiAddCproc("freealgebra.so","stest",TRUE,stest);
    137416  p->iiAddCproc("freealgebra.so","btest",TRUE,btest);
Note: See TracChangeset for help on using the changeset viewer.