source: git/Singular/intvec.cc @ 82716e

spielwiese
Last change on this file since 82716e was 052b762, checked in by Hans Schönemann <hannes@…>, 26 years ago
* hannes: memory check are done in mmallcb.c (intvec.cc) git-svn-id: file:///usr/local/Singular/svn/trunk@1348 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 10.2 KB
Line 
1/*****************************************
2*  Computer Algebra System SINGULAR      *
3*****************************************/
4/* $Id: intvec.cc,v 1.7 1998-04-07 17:51:50 Singular Exp $ */
5/*
6* ABSTRACT: class intvec: lists/vectors of integers
7*/
8
9#include "mod2.h"
10#include "tok.h"
11#include "febase.h"
12#include "intvec.h"
13
14/*0 implementation*/
15intvec::intvec(intvec* iv)
16{
17  row = iv->rows();
18  col = iv->cols();
19  v   = (int *)Alloc(sizeof(int)*row*col);
20  for (int i=0; i<row*col; i++)
21  {
22    v[i] = (*iv)[i];
23  }
24}
25
26intvec::intvec(int s, int e)
27{
28  int inc;
29  col = 1;
30  if (s<e)
31  {
32    row =  e-s+1;
33    inc =  1;
34  }
35  else
36  {
37    row = s-e+1;
38    inc = -1;
39  }
40  v = (int *)Alloc(sizeof(int)*row);
41  //if (v!=NULL)
42  {
43    for (int i=0; i<row; i++)
44    {
45      v[i] = s;
46      s+=inc;
47    }
48  }
49  //else
50  //{
51  //  Werror("internal error: creating intvec(%d)",row);
52  //  row=0;
53  //}
54}
55
56intvec::intvec(int r, int c, int init)
57{
58  row = r;
59  col = c;
60  int l = r*c;
61  if ((r>0) && (c>0))
62    v = (int *)Alloc(sizeof(int)*l);
63  else
64    v = NULL;
65  if (v!=NULL)
66  {
67    for (int i=0; i<l; i++)
68    {
69      v[i] = init;
70    }
71  }
72  else
73  {
74    Werror("internal error: creating intmat(%d,%d)",row,col);
75    row=0;
76  }
77}
78
79char * intvec::ivString(int mat,int spaces)
80{
81  StringSetS("");
82  if ((col == 1)&&(mat!=INTMAT_CMD))
83  {
84    for (int i=0; i<row; i++)
85    {
86      StringAppend("%d%c",v[i],i<row-1 ? ',' : ' ');
87    }
88  }
89  else
90  {
91    for (int j=0; j<row; j++)
92    {
93      if (j<row-1)
94      {
95        for (int i=0; i<col; i++)
96        {
97          StringAppend("%d%c",v[j*col+i],',');
98        }
99      }
100      else
101      {
102        for (int i=0; i<col; i++)
103        {
104          StringAppend("%d%c",v[j*col+i],i<col-1 ? ',' : ' ');
105        }
106      }
107      if (j+1<row) 
108      {
109        StringAppend("\n");
110        if (spaces>0) StringAppend("%-*.*s",spaces,spaces," ");
111      } 
112    }
113  }
114  return StringAppend("");
115}
116
117char * intvec::String()
118{
119  return mstrdup(ivString());
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/*3
312* gcd of a and b
313*/
314static int ivIntGcd(int a,int b)
315{
316  int x;
317
318  while (b!=0)
319  {
320    x = b;
321    b = a % x;
322    a = x;
323  }
324  return a;
325}
326
327/*2
328*computes a triangular matrix of the lower right submatrix
329*beginning with the field (srw,cl) by Gaussian elimination
330*/
331void ivTriangMat(intvec * imat, int srw, int cl)
332{
333  int i=srw,t,j,k,tgcd,mult1,mult2;
334
335  if ((cl>imat->cols()) || (srw>imat->rows())) return;
336  ivCancelContent(imat,srw);
337  while ((i<=imat->rows()) && (IMATELEM(*imat,i,cl)==0)) i++;
338  if ((i>srw ) && (i<=imat->rows()))
339  {
340    for (j=cl;j<=imat->cols();j++)
341    {
342      t = IMATELEM(*imat,srw,j);
343      IMATELEM(*imat,srw,j) = IMATELEM(*imat,i,j);
344      IMATELEM(*imat,i,j) = t;
345    }
346  }
347  if (i<=imat->rows())
348  {
349    for (k=srw+1;k<=imat->rows();k++)
350    {
351      if (IMATELEM(*imat,k,cl)!=0)
352      {
353        tgcd = ivIntGcd(IMATELEM(*imat,srw,cl),IMATELEM(*imat,k,cl));
354        mult1 = IMATELEM(*imat,k,cl) / tgcd;
355        mult2 = IMATELEM(*imat,srw,cl) / tgcd;
356        IMATELEM(*imat,k,cl) = 0;
357        for (j=cl+1;j<=imat->cols();j++)
358        {
359          IMATELEM(*imat,k,j) =
360              mult2*IMATELEM(*imat,k,j)-mult1*IMATELEM(*imat,srw,j);
361        }
362      }
363    }
364    srw++;
365  }
366  ivTriangMat(imat,srw,cl+1);
367  return;
368}
369
370/*2
371*returns the number of the first zero row,
372*-1 for no zero row
373*/
374int ivFirstEmptyRow(intvec * imat)
375{
376  int i,j;
377
378  for (i=1;i<=imat->rows();i++)
379  {
380    j = 1;
381    while ((j<=imat->cols()) && (IMATELEM(*imat,i,j)==0)) j++;
382    if (j>imat->cols()) return i;
383  }
384  return -1;
385}
386
387/*2
388*divide out the content for every row >= from
389*/
390void ivCancelContent(intvec * imat,int from)
391{
392  if (imat->cols()<2) return;
393  int i,j,tgcd;
394
395  for (i=from;i<=imat->rows();i++)
396  {
397    tgcd = ivIntGcd(IMATELEM(*imat,i,1),IMATELEM(*imat,i,2));
398    j = 3;
399    while ((j<=imat->cols()) && ((ABS(tgcd)>1) || (tgcd==0)))
400    {
401      tgcd = ivIntGcd(tgcd,IMATELEM(*imat,i,j));
402      j++;
403    }
404    if ((j>imat->cols()) && (ABS(tgcd)>1))
405     for (j=1;j<=imat->cols();j++) IMATELEM(*imat,i,j) /= tgcd;
406  }
407  return;
408}
409
410/*3
411*searches the independent columns of the system given by imat
412*imat is assumed to be in triangular shape
413*/
414static intvec * ivIndepCols(intvec * imat)
415{
416  intvec * result=new intvec(1,imat->cols(),0);
417  int i,j;
418
419  for (i=1;i<=imat->rows();i++)
420  {
421    j=1;
422    while ((j<=imat->cols()) && (IMATELEM(*imat,i,j)==0)) j++;
423    if (j<=imat->cols()) IMATELEM(*result,1,j)=i;
424  }
425  return result;
426}
427
428/*3
429* computes basic solutions of the system given by imat
430*/
431static intvec * ivBasicSol(intvec * imat)
432{
433  intvec * result = new intvec(2*imat->cols(),imat->cols(),0);
434  intvec * indep=ivIndepCols(imat),*actsol=new intvec(imat->cols());
435  int actPosSol=1,actNegSol=imat->cols()+1,i=imat->cols(),j,k;
436  int tgcd,tlcm;
437  BOOLEAN isNeg;
438
439  while (i>0)
440  {
441    if ((*indep)[i-1]==0)
442    {
443      for (j=0;j<actsol->length();j++) (*actsol)[j] = 0;
444      (*actsol)[i-1] = 1;
445      isNeg = FALSE;
446      j = i-1;
447      while (j>0)
448      {
449        if ((*indep)[j-1]!=0)
450        {
451          tlcm = 0;
452          for (k=0;k<i;k++)
453            tlcm += IMATELEM(*imat,(*indep)[j-1],k+1)*(*actsol)[k];
454          tgcd = ivIntGcd(tlcm,IMATELEM(*imat,(*indep)[j-1],j));
455          tlcm /= tgcd;
456          tgcd = IMATELEM(*imat,(*indep)[j-1],j) / tgcd;
457          if (tgcd<0)
458          {
459            tgcd = -tgcd;
460            tlcm = -tlcm;
461          }
462          for (k=0;k<i;k++) (*actsol)[k] *= tgcd;
463          (*actsol)[j-1] = -tlcm;
464          isNeg = isNeg || (tlcm>0);
465        }
466        j--;
467      }
468/*writes the solution into result depending on the sign*/
469      if (isNeg)
470      {
471        for (j=1;j<=imat->cols();j++)
472          IMATELEM(*result,actNegSol,j) = (*actsol)[j-1];
473        actNegSol++;
474      }
475      else
476      {
477        for (j=1;j<=imat->cols();j++)
478          IMATELEM(*result,actPosSol,j) = (*actsol)[j-1];
479        actPosSol++;
480      }
481    }
482    i--;
483  }
484  delete actsol;
485  delete indep;
486  return result;
487}
488
489/*2
490*returns an integer solution of imat which is assumed to be
491*in triangular form
492*the solution contains as many positive entrees as possible
493*/
494intvec * ivSolveIntMat(intvec * imat)
495{
496  intvec * result=new intvec(imat->cols());
497  intvec * basesol=ivBasicSol(imat);
498  int i=imat->cols(),j,k,l,t;
499
500/*adds all base solutions*/
501  for (j=1;j<=2*i;j++)
502  {
503    for (k=1;k<=i;k++)
504      (*result)[k-1] += IMATELEM(*basesol,j,k);
505  }
506/*tries to cancel negative entrees by adding positive solutions*/
507  j = 1;
508  while (j<=i)
509  {
510    if ((*result)[j-1]<0)
511    {
512      t = -1;
513      l = 0;
514      for (k=1;k<=i;k++)
515      {
516        if (IMATELEM(*basesol,k,j)>t)
517        {
518          t = IMATELEM(*basesol,k,j);
519          l = k;
520        }
521      }
522      if (t>0)
523      {
524        t = ((*result)[j-1] / t) +1;
525        for (k=1;k<=i;k++)
526        {
527          (*result)[k-1] += t*IMATELEM(*basesol,l,k);
528        }
529      }
530    }
531    j++;
532  }
533  delete basesol;
534  return result;
535}
Note: See TracBrowser for help on using the repository browser.