Changeset 4ed84fc in git


Ignore:
Timestamp:
Apr 24, 2019, 6:24:28 PM (5 years ago)
Author:
Karim Abou Zeid <karim23697@…>
Branches:
(u'spielwiese', '2a584933abf2a2d3082034c7586d38bb6de1a30a')
Children:
e8c12867734cd226cc02891d399506d4e198eb8f
Parents:
51b5853275964eb90183d3490cd0f77df75505c1
Message:
Move lpGkDim to dynamic module
Location:
Singular
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • Singular/LIB/fpaprops.lib

    r51b585 r4ed84fc  
    877877}
    878878
    879 proc lpGkDim(ideal G)
     879proc lpGkDim_lib(ideal G)
    880880"USAGE: lpGkDim(G); G an ideal in a letterplace ring
    881881RETURN: int
  • Singular/dyn_modules/freealgebra/freealgebra.cc

    r51b585 r4ed84fc  
    11#include "Singular/libsingular.h"
     2#include <vector>
    23
    34#ifdef HAVE_SHIFTBBA
     
    124125  else return TRUE;
    125126}
     127
     128static intvec ufnarovskiGraph(ideal G)
     129{
     130  long l = 0;
     131  for (int i = 0; i < IDELEMS(G); i++)
     132    l = si_max(pTotaldegree(G->m[i]), l);
     133  l--;
     134  if (l <= 0)
     135    WerrorS("Ufnarovski graph not implemented for l <= 0");
     136  int lV = currRing->isLPring;
     137
     138  ideal words = idMaxIdeal(l);
     139  ideal standardWords = kNF(G, currRing->qideal, words);
     140  idSkipZeroes(standardWords);
     141
     142  int n = IDELEMS(standardWords);
     143  intvec UG(n, n, 0);
     144  for (int i = 0; i < n; i++)
     145  {
     146    for (int j = 0; j < n; j++)
     147    {
     148      poly v = standardWords->m[i];
     149      poly w = standardWords->m[j];
     150
     151      // check whether v*x1 = x2*w (overlap)
     152      bool overlap = true;
     153      for (int k = 1; k <= (l - 1) * lV; k++)
     154      {
     155        if (pGetExp(v, k + lV) != pGetExp(w, k)) {
     156          overlap = false;
     157          break;
     158        }
     159      }
     160
     161      if (overlap)
     162      {
     163        // create the overlap
     164        poly p = pMult(pCopy(v), p_LPVarAt(w, l, currRing));
     165
     166        // check whether the overlap is normal
     167        bool normal = true;
     168        for (int k = 0; k < IDELEMS(G); k++)
     169        {
     170          if (p_LPDivisibleBy(G->m[k], p, currRing))
     171          {
     172            normal = false;
     173            break;
     174          }
     175        }
     176
     177        if (normal)
     178        {
     179          IMATELEM(UG, i + 1, j + 1) = 1;
     180        }
     181      }
     182    }
     183  }
     184  return UG;
     185}
     186
     187static 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)
     188{
     189  intvec* G = ivCopy(_G); // modifications must be local
     190
     191  if (cache[v] != -2) return cache; // value is already cached
     192
     193  visited[v] = TRUE;
     194  path.push_back(v);
     195
     196  int cycles = 0;
     197  for (int w = 0; w < G->cols(); w++)
     198  {
     199    if (IMATELEM(*G, v + 1, w + 1)) // edge v -> w exists in G
     200    {
     201      if (!visited[w])
     202      { // continue with w
     203        cache = countCycles(G, w, path, visited, cyclic, cache);
     204        if (cache[w] == -1)
     205        {
     206          cache[v] = -1;
     207          return cache;
     208        }
     209        cycles = si_max(cycles, cache[w]);
     210      }
     211      else
     212      { // found new cycle
     213        int pathIndexOfW = -1;
     214        for (int i = path.size() - 1; i >= 0; i--) {
     215          if (cyclic[path[i]] == 1) { // found an already cyclic vertex
     216            cache[v] = -1;
     217            return cache;
     218          }
     219          cyclic[path[i]] = TRUE;
     220
     221          if (path[i] == w) { // end of the cycle
     222            assume(IMATELEM(*G, v + 1, w + 1) != 0);
     223            IMATELEM(*G, v + 1, w + 1) = 0; // remove edge v -> w
     224            pathIndexOfW = i;
     225            break;
     226          } else {
     227            assume(IMATELEM(*G, path[i - 1] + 1, path[i] + 1) != 0);
     228            IMATELEM(*G, path[i - 1] + 1, path[i] + 1) = 0; // remove edge vi-1 -> vi
     229          }
     230        }
     231        assume(pathIndexOfW != -1); // should never happen
     232        for (int i = path.size() - 1; i >= pathIndexOfW; i--) {
     233          cache = countCycles(G, path[i], path, visited, cyclic, cache);
     234          if (cache[path[i]] == -1)
     235          {
     236            cache[v] = -1;
     237            return cache;
     238          }
     239          cycles = si_max(cycles, cache[path[i]] + 1);
     240        }
     241      }
     242    }
     243  }
     244  cache[v] = cycles;
     245
     246  delete G;
     247  return cache;
     248}
     249
     250// -1 is infinity
     251static int graphGrowth(intvec G)
     252{
     253  // init
     254  int n = G.cols();
     255  std::vector<int> path;
     256  std::vector<BOOLEAN> visited;
     257  std::vector<BOOLEAN> cyclic;
     258  std::vector<int> cache;
     259  visited.resize(n, FALSE);
     260  cyclic.resize(n, FALSE);
     261  cache.resize(n, -2);
     262
     263  // get max number of cycles
     264  int cycles = 0;
     265  for (int v = 0; v < n; v++)
     266  {
     267    cache = countCycles(&G, v, path, visited, cyclic, cache);
     268    if (cache[v] == -1)
     269      return -1;
     270    cycles = si_max(cycles, cache[v]);
     271  }
     272  return cycles;
     273}
     274
     275// -1 is infinity, -2 is error
     276static int id_LPGkDim(ideal G)
     277{
     278  if (rField_is_Ring(currRing)) {
     279      WerrorS("GK-Dim not implemented for rings");
     280      return -2;
     281  }
     282
     283  idSkipZeroes(G); // remove zeros
     284  for (int i=IDELEMS(G)-1;i>=0; i--)
     285  {
     286    G->m[i]->next = NULL; // G = LM(G)
     287    if (pGetComp(G->m[i]) != 0)
     288    {
     289      WerrorS("GK-Dim not implemented for modules");
     290      return -2;
     291    }
     292  }
     293  id_DelLmEquals(G, currRing); // remove duplicates
     294
     295  // get the max deg
     296  long maxDeg = 0;
     297  for (int i = 0; i < IDELEMS(G); i++)
     298  {
     299    maxDeg = si_max(maxDeg, pTotaldegree(G->m[i]));
     300
     301    // also check whether G = <1>
     302    if (pIsConstantComp(G->m[i]))
     303    {
     304      WerrorS("GK-Dim not defined for 0-ring");
     305      return -2;
     306    }
     307  }
     308
     309  // early termination if G \subset X
     310  if (maxDeg <= 1)
     311  {
     312    int lV = currRing->isLPring;
     313    if (IDELEMS(G) == lV) // V = {1} no edges
     314      return 0;
     315    if (IDELEMS(G) == lV - 1) // V = {1} with loop
     316      return 1;
     317    if (IDELEMS(G) <= lV - 2) // V = {1} with more than one loop
     318      return -1;
     319  }
     320
     321  intvec UG = ufnarovskiGraph(G);
     322  return graphGrowth(UG);
     323}
     324
     325
     326static BOOLEAN lpGkDim(leftv res, leftv h)
     327{
     328  const short t[]={1,IDEAL_CMD};
     329  if (iiCheckTypes(h,t,1))
     330  {
     331    assumeStdFlag(h);
     332    ideal G=(ideal)h->Data();
     333    res->rtyp = INT_CMD;
     334    res->data = (void*)(long) id_LPGkDim(G);
     335    if (errorreported) return TRUE;
     336    return FALSE;
     337  }
     338  else return TRUE;
     339}
    126340#endif
    127341
     
    134348  p->iiAddCproc("freealgebra.so","lpLmDivides",FALSE,lpLmDivides);
    135349  p->iiAddCproc("freealgebra.so","lpVarAt",FALSE,lpVarAt);
     350  p->iiAddCproc("freealgebra.so","lpGkDim",FALSE,lpGkDim);
     351
    136352  p->iiAddCproc("freealgebra.so","stest",TRUE,stest);
    137353  p->iiAddCproc("freealgebra.so","btest",TRUE,btest);
Note: See TracChangeset for help on using the changeset viewer.