source: git/Singular/fglmvec.cc @ 18dd47

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