source: git/Singular/fglmvec.cc @ 634dab0

spielwiese
Last change on this file since 634dab0 was 958e16, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: merged number-ops git-svn-id: file:///usr/local/Singular/svn/trunk@5035 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 11.8 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2// $Id: fglmvec.cc,v 1.15 2001-01-09 15:40:05 Singular 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 "omalloc.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 *)omAlloc( 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            omFreeSize( (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 *)omAlloc( 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
146#ifndef HAVE_EXPLICIT_CONSTR
147void
148fglmVector::mac_constr( const fglmVector & v)
149{
150    rep= v.rep->copyObject();
151}
152
153void
154fglmVector::mac_constr_i( int size )
155{
156    rep= new fglmVectorRep( size );
157}
158
159void
160fglmVector::clearelems()
161{
162    if ( rep->deleteObject() )
163      delete rep;
164}
165#endif
166
167void
168fglmVector::makeUnique()
169{
170    if ( rep->refcount() != 1 ) {
171        rep->deleteObject();
172        rep= rep->clone();
173    }
174}
175
176int
177fglmVector::size() const
178{
179    return rep->size();
180}
181
182int
183fglmVector::numNonZeroElems() const
184{
185    return rep->numNonZeroElems();
186}
187
188void
189fglmVector::nihilate( const number fac1, const number fac2, const fglmVector v )
190{
191    int i;
192    int vsize= v.size();
193    number term1, term2;
194    fglmASSERT( vsize <= rep->size(), "v has to be smaller oder equal" );
195    if ( rep->isUnique() ) {
196        for ( i= vsize; i > 0; i-- ) {
197            term1= nMult( fac1, rep->getconstelem( i ) );
198            term2= nMult( fac2, v.rep->getconstelem( i ) );
199            rep->setelem( i, nSub( term1, term2 ) );
200            nDelete( &term1 );
201            nDelete( &term2 );
202        }
203        for ( i= rep->size(); i > vsize; i-- ) {
204            rep->setelem( i, nMult( fac1, rep->getconstelem( i ) ) );
205        }
206    }
207    else
208    {
209        number* newelems;
210        newelems= (number *)omAlloc( rep->size()*sizeof( number ) );
211        for ( i= vsize; i > 0; i-- ) {
212            term1= nMult( fac1, rep->getconstelem( i ) );
213            term2= nMult( fac2, v.rep->getconstelem( i ) );
214            newelems[i-1]= nSub( term1, term2 );
215            nDelete( &term1 );
216            nDelete( &term2 );
217        }
218        for ( i= rep->size(); i > vsize; i-- ) {
219            newelems[i-1]= nMult( fac1, rep->getconstelem( i ) );
220        }
221        rep->deleteObject();
222        rep= new fglmVectorRep( rep->size(), newelems );
223    }
224}
225
226fglmVector &
227fglmVector::operator = ( const fglmVector & v )
228{
229    if ( this != &v ) {
230        if ( rep->deleteObject() )
231            delete rep;
232        rep = v.rep->copyObject();
233    }
234    return *this;
235}
236
237int
238fglmVector::operator == ( const fglmVector & v )
239{
240    if ( rep->size() == v.rep->size() ) {
241        if ( rep == v.rep ) return 1;
242        else {
243            int i;
244            for ( i= rep->size(); i > 0; i-- )
245                if ( ! nEqual( rep->getconstelem( i ), v.rep->getconstelem( i ) ) )
246                    return 0;
247            return 1;
248        }
249    }
250    return 0;
251}
252
253int
254fglmVector::operator != ( const fglmVector & v )
255{
256    return !( *this == v );
257}
258
259int
260fglmVector::isZero()
261{
262    return rep->isZero();
263}
264
265int
266fglmVector::elemIsZero( int i )
267{
268    return nIsZero( rep->getconstelem( i ) );
269}
270
271fglmVector &
272fglmVector::operator += ( const fglmVector & v )
273{
274    fglmASSERT( size() == v.size(), "incompatible vectors" );
275    // ACHTUNG : Das Verhalten hier mit gcd genau ueberpruefen!
276    int i;
277    if ( rep->isUnique() ) {
278        for ( i= rep->size(); i > 0; i-- )
279            rep->setelem( i, nAdd( rep->getconstelem( i ), v.rep->getconstelem( i ) ) );
280    }
281    else
282    {
283        int n = rep->size();
284        number* newelems;
285        newelems= (number *)omAlloc( n*sizeof( number ) );
286        for ( i= n; i > 0; i-- )
287            newelems[i-1]= nAdd( rep->getconstelem( i ), v.rep->getconstelem( i ) );
288        rep->deleteObject();
289        rep= new fglmVectorRep( n, newelems );
290    }
291    return *this;
292}
293
294fglmVector &
295fglmVector::operator -= ( const fglmVector & v )
296{
297    fglmASSERT( size() == v.size(), "incompatible vectors" );
298    int i;
299    if ( rep->isUnique() ) {
300        for ( i= rep->size(); i > 0; i-- )
301            rep->setelem( i, nSub( rep->getconstelem( i ), v.rep->getconstelem( i ) ) );
302    }
303    else
304    {
305        int n = rep->size();
306        number* newelems;
307        newelems= (number *)omAlloc( n*sizeof( number ) );
308        for ( i= n; i > 0; i-- )
309            newelems[i-1]= nSub( rep->getconstelem( i ), v.rep->getconstelem( i ) );
310        rep->deleteObject();
311        rep= new fglmVectorRep( n, newelems );
312    }
313    return *this;
314}
315
316fglmVector &
317fglmVector::operator *= ( const number & n )
318{
319    int s= rep->size();
320    int i;
321    if ( ! rep->isUnique() ) {
322        number * temp;
323        temp= (number *)omAlloc( s*sizeof( number ) );
324        for ( i= s; i > 0; i-- )
325            temp[i-1]= nMult( rep->getconstelem( i ), n );
326        rep->deleteObject();
327        rep= new fglmVectorRep( s, temp );
328    }
329    else
330    {
331        for (i= s; i > 0; i-- )
332            rep->setelem( i, nMult( rep->getconstelem( i ), n ) );
333    }
334    return *this;
335}
336
337fglmVector &
338fglmVector::operator /= ( const number & n )
339{
340    int s= rep->size();
341    int i;
342    if ( ! rep->isUnique() ) {
343        number * temp;
344        temp= (number *)omAlloc( s*sizeof( number ) );
345        for ( i= s; i > 0; i-- ) {
346            temp[i-1]= nDiv( rep->getconstelem( i ), n );
347            nNormalize( temp[i-1] );
348        }
349        rep->deleteObject();
350        rep= new fglmVectorRep( s, temp );
351    }
352    else
353    {
354        for (i= s; i > 0; i-- ) {
355            rep->setelem( i, nDiv( rep->getconstelem( i ), n ) );
356            nNormalize( rep->getelem( i ) );
357        }
358    }
359    return *this;
360}
361
362fglmVector
363operator - ( const fglmVector & v )
364{
365    fglmVector temp( v.size() );
366    int i;
367    number n ;
368    for ( i= v.size(); i > 0; i-- ) {
369        n= nCopy( v.getconstelem( i ) );
370        n= nNeg( n );
371        temp.setelem( i, n );
372    }
373    return temp;
374}
375
376fglmVector
377operator + ( const fglmVector & lhs, const fglmVector & rhs )
378{
379    fglmVector temp= lhs;
380    temp+= rhs;
381    return temp;
382}
383
384fglmVector
385operator - ( const fglmVector & lhs, const fglmVector & rhs )
386{
387    fglmVector temp= lhs;
388    temp-= rhs;
389    return temp;
390}
391
392fglmVector
393operator * ( const fglmVector & v, const number n )
394{
395    fglmVector temp= v;
396    temp*= n;
397    return temp;
398}
399
400fglmVector
401operator * ( const number n, const fglmVector & v )
402{
403    fglmVector temp= v;
404    temp*= n;
405    return temp;
406}
407
408number &
409fglmVector::getelem( int i )
410{
411    makeUnique();
412    return rep->getelem( i );
413}
414
415const number
416fglmVector::getconstelem( int i ) const
417{
418    return rep->getconstelem( i );
419}
420
421void
422fglmVector::setelem( int i, number & n )
423{
424    makeUnique();
425    rep->setelem( i, n );
426    n= nNULL;
427}
428
429number
430fglmVector::gcd() const
431{
432    int i= rep->size();
433    BOOLEAN found = FALSE;
434    BOOLEAN gcdIsOne = FALSE;
435    number theGcd;
436    number current;
437    while( i > 0 && ! found ) {
438        current= rep->getconstelem( i );
439        if ( ! nIsZero( current ) ) {
440            theGcd= nCopy( current );
441            found= TRUE;
442            if ( ! nGreaterZero( theGcd ) ) {
443                theGcd= nNeg( theGcd );
444            }
445            if ( nIsOne( theGcd ) ) gcdIsOne= TRUE;
446        }
447        i--;
448    }
449    if ( found ) {
450        while ( i > 0 && ! gcdIsOne ) {
451            current= rep->getconstelem( i );
452            if ( ! nIsZero( current ) ) {
453                number temp= nGcd( theGcd, current, currRing );
454                nDelete( &theGcd );
455                theGcd= temp;
456                if ( nIsOne( theGcd ) ) gcdIsOne= TRUE;
457            }
458            i--;
459        }
460    }
461    else
462        theGcd= nInit( 0 );
463    return theGcd;
464}
465
466number
467fglmVector::clearDenom()
468{
469    number theLcm = nInit( 1 );
470    number current;
471    BOOLEAN isZero = TRUE;
472    int i;
473    for ( i= size(); i > 0; i-- ) {
474        if ( ! nIsZero( rep->getconstelem(i) ) ) {
475            isZero= FALSE;
476            number temp= nLcm( theLcm, rep->getconstelem( i ), currRing );
477            nDelete( &theLcm );
478            theLcm= temp;
479        }
480    }
481    if ( isZero ) {
482        nDelete( &theLcm );
483        theLcm= nInit( 0 );
484    }
485    else {
486        if ( ! nIsOne( theLcm ) ) {
487            *this *= theLcm;
488            for ( i= size(); i > 0; i-- ) {
489                nNormalize( rep->getelem( i ) );
490            }
491        }
492    }
493    return theLcm;
494}
495
496#endif
497// ----------------------------------------------------------------------------
498// Local Variables: ***
499// compile-command: "make Singular" ***
500// page-delimiter: "^\\(\\|//!\\)" ***
501// fold-internal-margins: nil ***
502// End: ***
Note: See TracBrowser for help on using the repository browser.