source: git/kernel/fglmvec.cc @ ba5e9e

spielwiese
Last change on this file since ba5e9e was ba5e9e, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Changed configure-scripts to generate individual public config files for each package: resources, libpolys, singular (main) fix: sources should include correct corresponding config headers.
  • Property mode set to 100644
File size: 10.9 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2
3/****************************************
4*  Computer Algebra System SINGULAR     *
5****************************************/
6/*
7* ABSTRACT - The FGLM-Algorithm
8*   Implementation of number-vectors for the fglm algorithm.
9*   (See fglm.cc). Based on a letter-envelope implementation, mainly
10*   written to be used by the fglm algorithm. Hence they are
11*   specialized for this purpose.
12*/
13
14#ifdef HAVE_CONFIG_H
15#include "singularconfig.h"
16#endif /* HAVE_CONFIG_H */
17#include <kernel/mod2.h>
18
19#ifdef HAVE_FACTORY
20#include <omalloc/omalloc.h>
21#include <kernel/structs.h>
22#include <coeffs/numbers.h>
23#include <kernel/fglm.h>
24#include <kernel/fglmvec.h>
25
26#define PROT(msg)
27#define STICKYPROT(msg) if (BTEST1(OPT_PROT)) Print(msg)
28#define PROT2(msg,arg)
29#define STICKYPROT2(msg,arg) if (BTEST1(OPT_PROT)) Print(msg,arg)
30#define fglmASSERT(ignore1,ignore2)
31
32class fglmVectorRep
33{
34private:
35  int ref_count;
36  int N;
37  number *elems;
38public:
39    fglmVectorRep ():ref_count (1), N (0), elems (0)
40  {
41  }
42  fglmVectorRep (int n, number * e):ref_count (1), N (n), elems (e)
43  {
44  }
45  fglmVectorRep (int n):ref_count (1), N (n)
46  {
47    fglmASSERT (N >= 0, "illegal Vector representation");
48    if(N == 0)
49      elems = 0;
50    else
51    {
52      elems = (number *) omAlloc (N * sizeof (number));
53      for(int i = N - 1; i >= 0; i--)
54        elems[i] = nInit (0);
55    }
56  }
57  ~fglmVectorRep ()
58  {
59    if(N > 0)
60    {
61      for(int i = N - 1; i >= 0; i--)
62        nDelete (elems + i);
63      omFreeSize ((ADDRESS) elems, N * sizeof (number));
64    }
65  }
66
67  fglmVectorRep *clone () const
68  {
69    if(N > 0)
70    {
71      number *elems_clone;
72        elems_clone = (number *) omAlloc (N * sizeof (number));
73      for(int i = N - 1; i >= 0; i--)
74          elems_clone[i] = nCopy (elems[i]);
75        return new fglmVectorRep (N, elems_clone);
76    }
77    else
78        return new fglmVectorRep (N, 0);
79  }
80  BOOLEAN deleteObject ()
81  {
82    return --ref_count == 0;
83  }
84  fglmVectorRep *copyObject ()
85  {
86    ref_count++;
87    return this;
88  }
89  int refcount () const
90  {
91    return ref_count;
92  }
93  BOOLEAN isUnique () const
94  {
95    return ref_count == 1;
96  }
97
98  int size () const
99  {
100    return N;
101  }
102  int isZero () const
103  {
104    int k;
105    for(k = N; k > 0; k--)
106      if(!nIsZero (getconstelem (k)))
107          return 0;
108      return 1;
109  }
110  int numNonZeroElems () const
111  {
112    int num = 0;
113    int k;
114    for(k = N; k > 0; k--)
115      if(!nIsZero (getconstelem (k)))
116          num++;
117      return num;
118  }
119  void setelem (int i, number n)
120  {
121    fglmASSERT (0 < i && i <= N, "setelem: wrong index");
122    nDelete (elems + i - 1);
123    elems[i - 1] = n;
124  }
125  number ejectelem (int i, number n)
126  {
127    fglmASSERT (isUnique (), "should only be called if unique!");
128    number temp = elems[i - 1];
129    elems[i - 1] = n;
130    return temp;
131  }
132  number & getelem (int i)
133  {
134    fglmASSERT (0 < i && i <= N, "getelem: wrong index");
135    return elems[i - 1];
136  }
137  number getconstelem (int i) const
138  {
139    fglmASSERT (0 < i && i <= N, "getconstelem: wrong index");
140    return elems[i - 1];
141  }
142  friend class fglmVector;
143};
144
145
146///--------------------------------------------------------------------------------
147/// Implementation of class fglmVector
148///--------------------------------------------------------------------------------
149
150fglmVector::fglmVector (fglmVectorRep * r):rep (r)
151{
152}
153
154fglmVector::fglmVector ():rep (new fglmVectorRep ())
155{
156}
157
158fglmVector::fglmVector (int size):rep (new fglmVectorRep (size))
159{
160}
161
162fglmVector::fglmVector (int size, int basis):rep (new fglmVectorRep (size))
163{
164  rep->setelem (basis, nInit (1));
165}
166
167fglmVector::fglmVector (const fglmVector & v)
168{
169  rep = v.rep->copyObject ();
170}
171
172fglmVector::~fglmVector ()
173{
174  if(rep->deleteObject ())
175    delete rep;
176}
177
178#ifndef HAVE_EXPLICIT_CONSTR
179void fglmVector::mac_constr (const fglmVector & v)
180{
181  rep = v.rep->copyObject ();
182}
183
184void fglmVector::mac_constr_i (int size)
185{
186  rep = new fglmVectorRep (size);
187}
188
189void fglmVector::clearelems ()
190{
191  if(rep->deleteObject ())
192    delete rep;
193}
194#endif
195
196void fglmVector::makeUnique ()
197{
198  if(rep->refcount () != 1)
199  {
200    rep->deleteObject ();
201    rep = rep->clone ();
202  }
203}
204
205int fglmVector::size () const
206{
207  return rep->size ();
208}
209
210int fglmVector::numNonZeroElems () const
211{
212  return rep->numNonZeroElems ();
213}
214
215void
216  fglmVector::nihilate (const number fac1, const number fac2,
217                        const fglmVector v)
218{
219  int i;
220  int vsize = v.size ();
221  number term1, term2;
222  fglmASSERT (vsize <= rep->size (), "v has to be smaller oder equal");
223  if(rep->isUnique ())
224  {
225    for(i = vsize; i > 0; i--)
226    {
227      term1 = nMult (fac1, rep->getconstelem (i));
228      term2 = nMult (fac2, v.rep->getconstelem (i));
229      rep->setelem (i, nSub (term1, term2));
230      nDelete (&term1);
231      nDelete (&term2);
232    }
233    for(i = rep->size (); i > vsize; i--)
234    {
235      rep->setelem (i, nMult (fac1, rep->getconstelem (i)));
236    }
237  }
238  else
239  {
240    number *newelems;
241    newelems = (number *) omAlloc (rep->size () * sizeof (number));
242    for(i = vsize; i > 0; i--)
243    {
244      term1 = nMult (fac1, rep->getconstelem (i));
245      term2 = nMult (fac2, v.rep->getconstelem (i));
246      newelems[i - 1] = nSub (term1, term2);
247      nDelete (&term1);
248      nDelete (&term2);
249    }
250    for(i = rep->size (); i > vsize; i--)
251    {
252      newelems[i - 1] = nMult (fac1, rep->getconstelem (i));
253    }
254    rep->deleteObject ();
255    rep = new fglmVectorRep (rep->size (), newelems);
256  }
257}
258
259fglmVector & fglmVector::operator = (const fglmVector & v)
260{
261  if(this != &v)
262  {
263    if(rep->deleteObject ())
264      delete rep;
265    rep = v.rep->copyObject ();
266  }
267  return *this;
268}
269
270int fglmVector::operator == (const fglmVector & v)
271{
272  if(rep->size () == v.rep->size ())
273  {
274    if(rep == v.rep)
275      return 1;
276    else
277    {
278      int i;
279      for(i = rep->size (); i > 0; i--)
280        if(!nEqual (rep->getconstelem (i), v.rep->getconstelem (i)))
281          return 0;
282      return 1;
283    }
284  }
285  return 0;
286}
287
288int fglmVector::operator != (const fglmVector & v)
289{
290  return !(*this == v);
291}
292
293int fglmVector::isZero ()
294{
295  return rep->isZero ();
296}
297
298int fglmVector::elemIsZero (int i)
299{
300  return nIsZero (rep->getconstelem (i));
301}
302
303fglmVector & fglmVector::operator += (const fglmVector & v)
304{
305  fglmASSERT (size () == v.size (), "incompatible vectors");
306  // ACHTUNG : Das Verhalten hier mit gcd genau ueberpruefen!
307  int i;
308  if(rep->isUnique ())
309  {
310    for(i = rep->size (); i > 0; i--)
311      rep->setelem (i, nAdd (rep->getconstelem (i), v.rep->getconstelem (i)));
312  }
313  else
314  {
315    int n = rep->size ();
316    number *newelems;
317    newelems = (number *) omAlloc (n * sizeof (number));
318    for(i = n; i > 0; i--)
319      newelems[i - 1] = nAdd (rep->getconstelem (i), v.rep->getconstelem (i));
320    rep->deleteObject ();
321    rep = new fglmVectorRep (n, newelems);
322  }
323  return *this;
324}
325
326fglmVector & fglmVector::operator -= (const fglmVector & v)
327{
328  fglmASSERT (size () == v.size (), "incompatible vectors");
329  int i;
330  if(rep->isUnique ())
331  {
332    for(i = rep->size (); i > 0; i--)
333      rep->setelem (i, nSub (rep->getconstelem (i), v.rep->getconstelem (i)));
334  }
335  else
336  {
337    int n = rep->size ();
338    number *newelems;
339    newelems = (number *) omAlloc (n * sizeof (number));
340    for(i = n; i > 0; i--)
341      newelems[i - 1] = nSub (rep->getconstelem (i), v.rep->getconstelem (i));
342    rep->deleteObject ();
343    rep = new fglmVectorRep (n, newelems);
344  }
345  return *this;
346}
347
348fglmVector & fglmVector::operator *= (const number & n)
349{
350  int s = rep->size ();
351  int i;
352  if(!rep->isUnique ())
353  {
354    number *temp;
355    temp = (number *) omAlloc (s * sizeof (number));
356    for(i = s; i > 0; i--)
357      temp[i - 1] = nMult (rep->getconstelem (i), n);
358    rep->deleteObject ();
359    rep = new fglmVectorRep (s, temp);
360  }
361  else
362  {
363    for(i = s; i > 0; i--)
364      rep->setelem (i, nMult (rep->getconstelem (i), n));
365  }
366  return *this;
367}
368
369fglmVector & fglmVector::operator /= (const number & n)
370{
371  int s = rep->size ();
372  int i;
373  if(!rep->isUnique ())
374  {
375    number *temp;
376    temp = (number *) omAlloc (s * sizeof (number));
377    for(i = s; i > 0; i--)
378    {
379      temp[i - 1] = nDiv (rep->getconstelem (i), n);
380      nNormalize (temp[i - 1]);
381    }
382    rep->deleteObject ();
383    rep = new fglmVectorRep (s, temp);
384  }
385  else
386  {
387    for(i = s; i > 0; i--)
388    {
389      rep->setelem (i, nDiv (rep->getconstelem (i), n));
390      nNormalize (rep->getelem (i));
391    }
392  }
393  return *this;
394}
395
396fglmVector operator - (const fglmVector & v)
397{
398  fglmVector temp (v.size ());
399  int i;
400  number n;
401  for(i = v.size (); i > 0; i--)
402  {
403    n = nCopy (v.getconstelem (i));
404    n = nNeg (n);
405    temp.setelem (i, n);
406  }
407  return temp;
408}
409
410fglmVector operator + (const fglmVector & lhs, const fglmVector & rhs)
411{
412  fglmVector temp = lhs;
413  temp += rhs;
414  return temp;
415}
416
417fglmVector operator - (const fglmVector & lhs, const fglmVector & rhs)
418{
419  fglmVector temp = lhs;
420  temp -= rhs;
421  return temp;
422}
423
424fglmVector operator * (const fglmVector & v, const number n)
425{
426  fglmVector temp = v;
427  temp *= n;
428  return temp;
429}
430
431fglmVector operator * (const number n, const fglmVector & v)
432{
433  fglmVector temp = v;
434  temp *= n;
435  return temp;
436}
437
438number & fglmVector::getelem (int i)
439{
440  makeUnique ();
441  return rep->getelem (i);
442}
443
444number fglmVector::getconstelem (int i) const
445{
446  return rep->getconstelem (i);
447}
448
449void fglmVector::setelem (int i, number & n)
450{
451  makeUnique ();
452  rep->setelem (i, n);
453  n = n_Init (0, currRing->cf);
454}
455
456number fglmVector::gcd () const
457{
458  int i = rep->size ();
459  BOOLEAN found = FALSE;
460  BOOLEAN gcdIsOne = FALSE;
461  number theGcd;
462  number current;
463  while(i > 0 && !found)
464  {
465    current = rep->getconstelem (i);
466    if(!nIsZero (current))
467    {
468      theGcd = nCopy (current);
469      found = TRUE;
470      if(!nGreaterZero (theGcd))
471      {
472        theGcd = nNeg (theGcd);
473      }
474      if(nIsOne (theGcd))
475        gcdIsOne = TRUE;
476    }
477    i--;
478  }
479  if(found)
480  {
481    while(i > 0 && !gcdIsOne)
482    {
483      current = rep->getconstelem (i);
484      if(!nIsZero (current))
485      {
486        number temp = nGcd (theGcd, current, currRing);
487        nDelete (&theGcd);
488        theGcd = temp;
489        if(nIsOne (theGcd))
490          gcdIsOne = TRUE;
491      }
492      i--;
493    }
494  }
495  else
496    theGcd = nInit (0);
497  return theGcd;
498}
499
500number fglmVector::clearDenom ()
501{
502  number theLcm = nInit (1);
503  BOOLEAN isZero = TRUE;
504  int i;
505  for(i = size (); i > 0; i--)
506  {
507    if(!nIsZero (rep->getconstelem (i)))
508    {
509      isZero = FALSE;
510      number temp = n_Lcm (theLcm, rep->getconstelem (i), currRing->cf);
511      nDelete (&theLcm);
512      theLcm = temp;
513    }
514  }
515  if(isZero)
516  {
517    nDelete (&theLcm);
518    theLcm = nInit (0);
519  }
520  else
521  {
522    if(!nIsOne (theLcm))
523    {
524      *this *= theLcm;
525      for(i = size (); i > 0; i--)
526      {
527        nNormalize (rep->getelem (i));
528      }
529    }
530  }
531  return theLcm;
532}
533
534#endif
535// ----------------------------------------------------------------------------
536// Local Variables: ***
537// compile-command: "make Singular" ***
538// page-delimiter: "^\\(\\|//!\\)" ***
539// fold-internal-margins: nil ***
540// End: ***
Note: See TracBrowser for help on using the repository browser.