source: git/Singular/intvec.cc @ 584f84d

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