source: git/libpolys/misc/intvec.cc @ 1628d3b

fieker-DuValspielwiese
Last change on this file since 1628d3b was 1628d3b, checked in by Mohamed Barakat <mohamed.barakat@…>, 13 years ago
- added intvec to misc - created libmisc
  • Property mode set to 100644
File size: 14.4 KB
RevLine 
[35aab3]1/*****************************************
2*  Computer Algebra System SINGULAR      *
3*****************************************/
[341696]4/* $Id$ */
[35aab3]5/*
6* ABSTRACT: class intvec: lists/vectors of integers
7*/
8#ifndef INTVEC_CC
9#define INTVEC_CC
[1628d3b]10// #include <resources/feFopen.h>
11#include <misc/intvec.h>
[b1dfaf]12#include <omalloc/omalloc.h>
[35aab3]13
14/*0 implementation*/
15
[a82adc]16// omBin intvec_bin = omGetSpecBin(sizeof(intvec));
17#if 0
[35aab3]18intvec::intvec(intvec* iv)
19{
20  row = iv->rows();
21  col = iv->cols();
22  v   = (int *)omAlloc(sizeof(int)*row*col);
23  for (int i=0; i<row*col; i++)
24  {
25    v[i] = (*iv)[i];
26  }
27}
[a82adc]28#endif
[35aab3]29
30intvec::intvec(int s, int e)
31{
32  int inc;
33  col = 1;
34  if (s<e)
35  {
36    row =  e-s+1;
37    inc =  1;
38  }
39  else
40  {
41    row = s-e+1;
42    inc = -1;
43  }
44  v = (int *)omAlloc(sizeof(int)*row);
45  for (int i=0; i<row; i++)
46  {
47    v[i] = s;
48    s+=inc;
49  }
50}
51
52intvec::intvec(int r, int c, int init)
53{
54  row = r;
55  col = c;
56  int l = r*c;
[9b4a332]57  if (l>0) /*(r>0) && (c>0) */
[35aab3]58    v = (int *)omAlloc(sizeof(int)*l);
59  else
60    v = NULL;
61  for (int i=0; i<l; i++)
62  {
63    v[i] = init;
64  }
65}
66
[e3915e]67char * intvec::ivString(int not_mat,int spaces, int dim) const
[35aab3]68{
[11120fd]69  //Print("ivString:this=%x,v=%x,row=%d\n",this,v,row);
[e3915e]70#ifndef OM_NDEBUG
71  omCheckAddr((void *)this);
[9b4a332]72  if (v!=NULL) omCheckAddr((void *)v);
[e3915e]73#endif
[35aab3]74  StringSetS("");
75  if ((col == 1)&&(not_mat))
76  {
77    int i=0;
78    for (; i<row-1; i++)
79    {
80      StringAppend("%d,",v[i]);
81    }
82    if (i<row)
83    {
84      StringAppend("%d",v[i]);
85    }
86  }
87  else
88  {
89    for (int j=0; j<row; j++)
90    {
91      if (j<row-1)
92      {
93        for (int i=0; i<col; i++)
94        {
95          StringAppend("%d%c",v[j*col+i],',');
96        }
97      }
98      else
99      {
100        for (int i=0; i<col; i++)
101        {
102          StringAppend("%d%c",v[j*col+i],i<col-1 ? ',' : ' ');
103        }
104      }
105      if (j+1<row)
106      {
107        if (dim > 1) StringAppendS("\n");
108        if (spaces>0) StringAppend("%-*.*s",spaces,spaces," ");
109      }
110    }
111  }
112  return StringAppendS("");
113}
114
115void intvec::resize(int new_length)
116{
117  assume(new_length > 0 && col == 1);
118  v = (int*) omRealloc0Size(v, row*sizeof(int), new_length*sizeof(int));
119  row = new_length;
120}
121
[e3915e]122char * intvec::String(int dim) const
[35aab3]123{
124  return omStrDup(ivString(1, 0, dim));
125}
126
[ddbc22]127#ifndef NDEBUG
128// debug only
[e9c3b2]129void intvec::view () const
130{
131  Print ("intvec: {rows: %d, cols: %d, length: %d, Values: \n", rows(), cols(), length());
132
133  for (int i = 0; i < rows(); i++)
134  {
135    Print ("Row[%3d]:", i);
136    for (int j = 0; j < cols(); j++)
137      Print (" %5d", this->operator[]((i)*cols()+j) );
138    PrintLn ();
139  }
140  PrintS ("}\n");
141}
[ddbc22]142#endif
[e9c3b2]143
[e3915e]144void intvec::show(int notmat,int spaces) const
[35aab3]145{
146  if (spaces>0)
[058624]147  {
148    PrintNSpaces(spaces);
149    PrintS(ivString(notmat,spaces));
150  }
[35aab3]151  else
152    PrintS(ivString(notmat,0));
153}
154
155void intvec::operator+=(int intop)
156{
157  for (int i=0; i<row*col; i++) { v[i] += intop; }
158}
159
160void intvec::operator-=(int intop)
161{
162  for (int i=0; i<row*col; i++) { v[i] -= intop; }
163}
164
165void intvec::operator*=(int intop)
166{
167  for (int i=0; i<row*col; i++) { v[i] *= intop; }
168}
169
170void intvec::operator/=(int intop)
171{
172  if (intop == 0) return;
173  int bb=ABS(intop);
174  for (int i=0; i<row*col; i++)
175  {
176    int r=v[i];
177    int c=r%bb;
178    if (c<0) c+=bb;
179    r=(r-c)/intop;
180    v[i]=r;
181  }
182}
183
184void intvec::operator%=(int intop)
185{
186  if (intop == 0) return;
187  int bb=ABS(intop);
188  for (int i=0; i<row*col; i++)
189  {
190    int r=v[i];
191    int c=r%bb;
192    if (c<0) c+=bb;
193    v[i]=c;
194  }
195}
196
[cd2d90]197int intvec::compare(const intvec* op) const
[35aab3]198{
199  if ((col!=1) ||(op->cols()!=1))
200  {
201    if((col!=op->cols())
202    || (row!=op->rows()))
203      return -2;
204  }
205  int i;
206  for (i=0; i<si_min(length(),op->length()); i++)
207  {
208    if (v[i] > (*op)[i])
209      return 1;
210    if (v[i] < (*op)[i])
211      return -1;
212  }
213  // this can only happen for intvec: (i.e. col==1)
214  for (; i<row; i++)
215  {
216    if (v[i] > 0)
217      return 1;
218    if (v[i] < 0)
219      return -1;
220  }
221  for (; i<op->rows(); i++)
222  {
223    if (0 > (*op)[i])
224      return 1;
225    if (0 < (*op)[i])
226      return -1;
227  }
228  return 0;
229}
[cd2d90]230int intvec::compare(int o) const
[35aab3]231{
232  for (int i=0; i<row*col; i++)
233  {
234    if (v[i] <o) return -1;
235    if (v[i] >o) return 1;
236  }
237  return 0;
238}
239
[a82adc]240#if 0
[35aab3]241intvec * ivCopy(intvec * o)
242{
243  intvec * iv=new intvec(o);
244  return iv;
245}
[a82adc]246#endif
[35aab3]247
248intvec * ivAdd(intvec * a, intvec * b)
249{
250  intvec * iv;
251  int mn, ma, i;
252  if (a->cols() != b->cols()) return NULL;
253  mn = si_min(a->rows(),b->rows());
254  ma = si_max(a->rows(),b->rows());
255  if (a->cols() == 1)
256  {
257    iv = new intvec(ma);
258    for (i=0; i<mn; i++) (*iv)[i] = (*a)[i] + (*b)[i];
259    if (ma > mn)
260    {
261      if (ma == a->rows())
262      {
263        for(i=mn; i<ma; i++) (*iv)[i] = (*a)[i];
264      }
265      else
266      {
267        for(i=mn; i<ma; i++) (*iv)[i] = (*b)[i];
268      }
269    }
270    return iv;
271  }
272  if (mn != ma) return NULL;
273  iv = new intvec(a);
274  for (i=0; i<mn*a->cols(); i++) { (*iv)[i] += (*b)[i]; }
275  return iv;
276}
277
278intvec * ivSub(intvec * a, intvec * b)
279{
280  intvec * iv;
281  int mn, ma, i;
282  if (a->cols() != b->cols()) return NULL;
283  mn = si_min(a->rows(),b->rows());
284  ma = si_max(a->rows(),b->rows());
285  if (a->cols() == 1)
286  {
287    iv = new intvec(ma);
288    for (i=0; i<mn; i++) (*iv)[i] = (*a)[i] - (*b)[i];
289    if (ma > mn)
290    {
291      if (ma == a->rows())
292      {
293        for(i=mn; i<ma; i++) (*iv)[i] = (*a)[i];
294      }
295      else
296      {
297        for(i=mn; i<ma; i++) (*iv)[i] = -(*b)[i];
298      }
299    }
300    return iv;
301  }
302  if (mn != ma) return NULL;
303  iv = new intvec(a);
304  for (i=0; i<mn*a->cols(); i++) { (*iv)[i] -= (*b)[i]; }
305  return iv;
306}
307
308intvec * ivTranp(intvec * o)
309{
310  int i, j, r = o->rows(), c = o->cols();
311  intvec * iv= new intvec(c, r, 0);
312  for (i=0; i<r; i++)
313  {
314    for (j=0; j<c; j++)
315      (*iv)[j*r+i] = (*o)[i*c+j];
316  }
317  return iv;
318}
319
320int ivTrace(intvec * o)
321{
322  int i, s = 0, m = si_min(o->rows(),o->cols()), c = o->cols();
323  for (i=0; i<m; i++)
324  {
325    s += (*o)[i*c+i];
326  }
327  return s;
328}
329
330intvec * ivMult(intvec * a, intvec * b)
331{
332  int i, j, k, sum,
333      ra = a->rows(), ca = a->cols(),
334      rb = b->rows(), cb = b->cols();
335  intvec * iv;
336  if (ca != rb) return NULL;
337  iv = new intvec(ra, cb, 0);
338  for (i=0; i<ra; i++)
339  {
340    for (j=0; j<cb; j++)
341    {
342      sum = 0;
343      for (k=0; k<ca; k++)
344        sum += (*a)[i*ca+k]*(*b)[k*cb+j];
345      (*iv)[i*cb+j] = sum;
346    }
347  }
348  return iv;
349}
350
351/*2
352*computes a triangular matrix
353*/
354//void ivTriangMat(intvec * imat)
355//{
356//  int i=0,j=imat->rows(),k=j*imat->cols()-1;
357//
358//  ivTriangIntern(imat,i,j);
359//  i *= imat->cols();
360//  for(j=k;j>=i;j--)
361//    (*imat)[j] = 0;
362//}
363
364/* def. internals */
365static int ivColPivot(intvec *, int, int, int, int);
366static void ivNegRow(intvec *, int);
367static void ivSaveRow(intvec *, int);
368static void ivSetRow(intvec *, int, int);
369static void ivFreeRow(intvec *, int, int);
370static void ivReduce(intvec *, int, int, int, int);
371static void ivZeroElim(intvec *,int, int, int &);
372static void ivRowContent(intvec *, int, int);
373static void ivKernFromRow(intvec *, intvec *, intvec *,
374                          int, int, int);
375static intvec * ivOptimizeKern(intvec *);
376static int ivGcd(int, int);
377static void ivOptRecursive(intvec *, intvec *, intvec *,
378                          int &, int &, int);
379static void ivOptSolve(intvec *, intvec *, int &, int &);
380static void ivContent(intvec *);
381static int ivL1Norm(intvec *);
382static int ivCondNumber(intvec *, int); 
383
384/* Triangulierung in intmat.cc */
385void ivTriangIntern(intvec *imat, int &ready, int &all)
386{
387  int rpiv, colpos=0, rowpos=0;
388  int ia=ready, ie=all;
389
390  do
391  {
392    rowpos++;
393    do
394    {
395      colpos++;
396      rpiv = ivColPivot(imat, colpos, rowpos, ia, ie);
397    } while (rpiv==0);
398    if (rpiv>ia)
399    {
400      if (rowpos!=rpiv)
401      {
402        ivSaveRow(imat, rpiv);
403        ivFreeRow(imat, rowpos, rpiv);
404        ivSetRow(imat, rowpos, colpos);
405        rpiv = rowpos;
406      }
407      ia++;
408      if (ia==imat->cols())
409      {
410        ready = ia;
411        all = ie;
412        return;
413      }
414    }
415    ivReduce(imat, rpiv, colpos, ia, ie);
416    ivZeroElim(imat, colpos, ia, ie);
417  } while (ie>ia);
418  ready = ia;
419  all = ie;
420}
421
422/* Kernberechnung in intmat.cc */
423intvec * ivSolveKern(intvec *imat, int dimtr)
424{
425  int d=imat->cols();
426  int kdim=d-dimtr;
427  intvec *perm = new intvec(dimtr+1);
428  intvec *kern = new intvec(kdim,d,0);
429  intvec *res;
430  int c, cp, r, t;
431
432  t = kdim;
433  c = 1;
434  for (r=1;r<=dimtr;r++)
435  {
436    while (IMATELEM(*imat,r,c)==0) c++;
437    (*perm)[r] = c;
438    c++;
439  }
440  c = d;
441  for (r=dimtr;r>0;r--)
442  {
443    cp = (*perm)[r];
444    if (cp!=c)
445    {
446      ivKernFromRow(kern, imat, perm, t, r, c);
447      t -= (c-cp);
448      if (t==0)
449        break;
450      c = cp-1;
451    }
452    else
453      c--;
454  }
455  if (kdim>1)
456    res = ivOptimizeKern(kern);
457  else
458    res = ivTranp(kern);
459  delete kern;
460  delete perm;
461  return res;
462}
463
464/* internals */
465static int ivColPivot(intvec *imat, int colpos, int rowpos, int ready, int all)
466{
467  int rpiv;
468
469  if (IMATELEM(*imat,rowpos,colpos)!=0)
470    return rowpos;
471  for (rpiv=ready+1;rpiv<=all;rpiv++)
472  {
473    if (IMATELEM(*imat,rpiv,colpos)!=0)
474      return rpiv;
475  }
476  return 0;
477}
478
479static void ivNegRow(intvec *imat, int rpiv)
480{
481  int i;
482  for (i=imat->cols();i!=0;i--)
483    IMATELEM(*imat,rpiv,i) = -(IMATELEM(*imat,rpiv,i));
484}
485
486static void ivSaveRow(intvec *imat, int rpiv)
487{
488  int i, j=imat->rows();
489
490  for (i=imat->cols();i!=0;i--)
491    IMATELEM(*imat,j,i) = IMATELEM(*imat,rpiv,i);
492}
493
494static void ivSetRow(intvec *imat, int rowpos, int colpos)
495{
496  int i, j=imat->rows();
497
498  for (i=imat->cols();i!=0;i--)
499    IMATELEM(*imat,rowpos,i) = IMATELEM(*imat,j,i);
500  ivRowContent(imat, rowpos, colpos);
501}
502
503static void ivFreeRow(intvec *imat, int rowpos, int rpiv)
504{
505  int i, j;
506
507  for (j=rpiv-1;j>=rowpos;j--)
508  {
509    for (i=imat->cols();i!=0;i--)
510      IMATELEM(*imat,j+1,i) = IMATELEM(*imat,j,i);
511  }
512}
513
514static void ivReduce(intvec *imat, int rpiv, int colpos,
515                     int ready, int all)
516{
517  int tgcd, ce, m1, m2, j, i;
518  int piv = IMATELEM(*imat,rpiv,colpos);
519
520  for (j=all;j>ready;j--)
521  {
522    ce = IMATELEM(*imat,j,colpos);
523    if (ce!=0)
524    {
525      IMATELEM(*imat,j,colpos) = 0;
526      m1 = piv;
527      m2 = ce;
528      tgcd = ivGcd(m1, m2);
529      if (tgcd != 1)
530      {
531        m1 /= tgcd;
532        m2 /= tgcd;
533      }
534      for (i=imat->cols();i>colpos;i--)
535      {
536        IMATELEM(*imat,j,i) = IMATELEM(*imat,j,i)*m1-
537                              IMATELEM(*imat,rpiv,i)*m2;
538      }
539      ivRowContent(imat, j, colpos+1);
540    }
541  }
542}
543
544static void ivZeroElim(intvec *imat, int colpos,
545                     int ready, int &all)
546{
547  int j, i, k, l;
548
549  k = ready;
550  for (j=ready+1;j<=all;j++)
551  {
552    for (i=imat->cols();i>colpos;i--)
553    {
554      if (IMATELEM(*imat,j,i)!=0)
555      {
556        k++;
557        if (k<j)
558        {
559          for (l=imat->cols();l>colpos;l--)
560            IMATELEM(*imat,k,l) = IMATELEM(*imat,j,l);
561        }
562        break;
563      }
564    }
565  }
566  all = k;
567}
568
569static void ivRowContent(intvec *imat, int rowpos, int colpos)
570{
571  int tgcd, m;
572  int i=imat->cols();
573
574  loop
575  {
576    tgcd = IMATELEM(*imat,rowpos,i--);
577    if (tgcd!=0) break;
578    if (i<colpos) return;
579  }
580  if (tgcd<0) tgcd = -tgcd;
581  if (tgcd==1) return;
582  loop
583  {
584    m = IMATELEM(*imat,rowpos,i--);
585    if (m!=0) tgcd= ivGcd(tgcd, m);
586    if (tgcd==1) return;
587    if (i<colpos) break;
588  }
589  for (i=imat->cols();i>=colpos;i--)
590    IMATELEM(*imat,rowpos,i) /= tgcd;
591}
592
593static void ivKernFromRow(intvec *kern, intvec *imat,
594                          intvec *perm, int pos, int r, int c)
595{
596  int piv, cp, g, i, j, k, s;
597
598  for (i=c;i>(*perm)[r];i--)
599  {
600    IMATELEM(*kern,pos,i) = 1;
601    for (j=r;j!=0;j--)
602    {
603      cp = (*perm)[j];
604      s=0;
605      for(k=c;k>cp;k--)
606        s += IMATELEM(*imat,j,k)*IMATELEM(*kern,pos,k);
607      if (s!=0)
608      {
609        piv = IMATELEM(*imat,j,cp);
610        g = ivGcd(piv,s);
611        if (g!=1)
612        {
613          s /= g;
614          piv /= g;
615        }
616        for(k=c;k>cp;k--)
617          IMATELEM(*kern,pos,k) *= piv;
618        IMATELEM(*kern,pos,cp) = -s;
619        ivRowContent(kern,pos,cp);
620      }
621    }
622    if (IMATELEM(*kern,pos,i)<0)
623      ivNegRow(kern,pos);
624    pos--;
625  }
626}
627
628static int ivGcd(int a,int b)
629{
630  int x;
631
632  if (a<0) a=-a;
633  if (b<0) b=-b;
634  if (b>a)
635  {
636    x=b;
637    b=a;
638    a=x;
639  }
640  while (b!=0)
641  {
642    x = a % b;
643    a = b;
644    b = x;
645  }
646  return a;
647}
648
649static intvec * ivOptimizeKern(intvec *kern)
650{
651  int i,l,j,c=kern->cols(),r=kern->rows();
652  intvec *res=new intvec(c);
653
[1628d3b]654  //if (TEST_OPT_PROT)
655  //  Warn(" %d linear independent solutions\n",r);
[35aab3]656  for (i=r;i>1;i--)
657  {
658    for (j=c;j>0;j--)
659    {
660      (*res)[j-1] += IMATELEM(*kern,i,j);
661    }
662  }
663  ivContent(res);
664  if (r<11)
665  {
666    l = ivCondNumber(res,-c);
667    j = ivL1Norm(res);
668    ivOptRecursive(res, NULL, kern, l, j, r);
669  }
670  return res;
671}
672
673static void ivOptRecursive(intvec *res, intvec *w, intvec *kern,
674                          int &l, int &j, int pos)
675{
676  int m, k, d;
677  intvec *h;
678
679  d=kern->rows();
680  d=96/(d*d);
681  if (d<3) d=3;
682  if (w!=0)
683    h = new intvec(w);
684  else
685    h = new intvec(res->rows());
686  for (m=d;m>0;m--)
687  {
688    for(k=h->rows()-1;k>=0;k--)
689      (*h)[k] += IMATELEM(*kern,pos,k+1);
690    if(pos>1)
691      ivOptRecursive(res, h, kern, l, j, pos-1);
692    else
693      ivOptSolve(res, h, l, j);
694  }
695  delete h;
696  if (pos>1)
697    ivOptRecursive(res, w, kern, l, j, pos-1);
698  else if (w!=NULL)
699    ivOptSolve(res, w, l, j);
700}
701
702static void ivOptSolve(intvec *res, intvec *w, int &l, int &j)
703{
704  int l0, j0, k;
705
706  l0 = ivCondNumber(w, l);
707  if (l0==l)
708  {
709    ivContent(w);
710    j0 = ivL1Norm(w);
711    if(j0<j)
712    {
713      j = j0;
714      for(k=w->rows()-1;k>=0;k--)
715        (*res)[k] = (*w)[k];
716    }
717    return;
718  }
719  if(l0>l)
720  {
721    l = l0;
722    ivContent(w);
723    j = ivL1Norm(w);
724    for(k=w->rows()-1;k>=0;k--)
725      (*res)[k] = (*w)[k];
726  } 
727}
728
729static int ivL1Norm(intvec *w)
730{
731  int i, j, s = 0;
732
733  for (i=w->rows()-1;i>=0;i--)
734  {
735    j = (*w)[i];
736    if (j>0)
737      s += j;
738    else
739      s -= j;
740  }
741  return s;
742}
743
744static int ivCondNumber(intvec *w, int l)
745{
746  int l0=0, i;
747
748  if (l<0)
749  {
750    for (i=w->rows()-1;i>=0;i--)
751    {
752      if ((*w)[i]<0) l0--;
753    }
754    if (l0==0)
755    {
756      for (i=w->rows()-1;i>=0;i--)
757      {
758        if ((*w)[i]>0) l0++;
759      }
760    }
761    return l0;
762  }
763  else
764  {
765    for (i=w->rows()-1;i>=0;i--)
766    {
767      if ((*w)[i]<0) return -1;
768    }
769    for (i=w->rows()-1;i>=0;i--)
770    {
771      if ((*w)[i]>0) l0++;
772    }
773    return l0;
774  }
775}
776
777static void ivContent(intvec *w)
778{
779  int tgcd, m;
780  int i=w->rows()-1;
781
782  loop
783  {
784    tgcd = (*w)[i--];
785    if (tgcd!=0) break;
786    if (i<0) return;
787  }
788  if (tgcd<0) tgcd = -tgcd;
789  if (tgcd==1) return;
790  loop
791  {
792    m = (*w)[i--];
793    if (m!=0) tgcd= ivGcd(tgcd, m);
794    if (tgcd==1) return;
795    if (i<0) break;
796  }
797  for (i=w->rows()-1;i>=0;i--)
798    (*w)[i] /= tgcd;
799}
800
801#endif
Note: See TracBrowser for help on using the repository browser.