source: git/Singular/fglmvec.cc @ 5480da

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