source: git/Singular/fglmvec.cc @ ad42cac

fieker-DuValspielwiese
Last change on this file since ad42cac was 0e1846, checked in by Olaf Bachmann <obachman@…>, 27 years ago
This commit was generated by cvs2svn to compensate for changes in r59, which included commits to RCS files with non-trunk default branches. git-svn-id: file:///usr/local/Singular/svn/trunk@60 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 14.0 KB
Line 
1// emacs edit mode for this file is -*- C++ -*-
2// $Id: fglmvec.cc,v 1.1.1.1 1997-03-19 13:18:45 obachman Exp $
3
4#include <assert.h>
5#include <counted.h>
6#include <fglmvec.h>
7#include "fglm.h"
8#include "numbers.h"
9
10class fglmVectorRep : public CountedObject
11{
12private:
13    int N;
14    number * elems;
15public:
16    fglmVectorRep() : N(0), elems(0) {}
17    fglmVectorRep( int n, number * e ) : N(n), elems(e) {}
18    fglmVectorRep( int n ) : N(n) 
19    {
20        ASSERT( N >= 0, "illegal Vector representation" );
21        if ( N == 0 ) 
22            elems= 0;
23        else {
24            elems= (number *)Alloc( N*sizeof( number ) );
25            for ( int i= N-1; i >= 0; i-- )
26                elems[i]= nInit( 0 );
27        }
28    }
29    ~fglmVectorRep()
30    {
31        for ( int i= N-1; i>=0; i-- )
32            nDelete( elems + i );
33        Free( (ADDRESS)elems, N*sizeof( number ) );
34    }
35
36    fglmVectorRep* clone() const
37    {
38        if ( N > 0 ) {
39            number * elems_clone;
40            elems_clone= (number *)Alloc( N*sizeof( number ) );
41            for ( int i= N-1; i >= 0; i-- )
42                elems_clone[i] = nCopy( elems[i] );
43            return new fglmVectorRep( N, elems_clone );
44        } else
45            return new fglmVectorRep( N, 0 );
46    }
47    int size() const { return N; }
48    int numNonZeroElems() const 
49    {
50        int num = 0;
51        for ( int k = N; k > 0; k-- )
52            if ( ! nIsZero( getconstelem(k) ) ) num++;
53        return num;
54    }
55    void setelem( int i, number n )
56    {
57        nDelete( elems + i-1 );
58        elems[i-1]= n;
59    }
60    number & getelem( int i )
61    {
62        return elems[i-1];
63    }
64    const number getconstelem( int i) const
65    {
66        return elems[i-1];
67    }
68    void print( ostream & s ) const
69    {
70        if ( N == 0 )
71            s << "( )";
72        else {
73            s << "( ";
74            StringSet( "" );
75            nWrite( elems[0] );
76            s << StringAppend( "" );
77            for ( int i = 1; i < N; i++ ) {
78                s << ", ";
79                StringSet( "" );
80                nWrite( elems[i] );
81                s << StringAppend( "" );
82            }
83            s << " )";
84        }
85        s << "[" << refcount() << "]";
86    }
87    friend class fglmVector;
88    friend class subFglmVector;
89};
90
91
92///--------------------------------------------------------------------------------
93/// Implementation of class fglmVector
94///--------------------------------------------------------------------------------
95
96fglmVector::fglmVector( fglmVectorRep * r ) : rep(r) {}
97
98fglmVector::fglmVector() : rep( new fglmVectorRep() ) {}
99
100fglmVector::fglmVector( int size ) : rep( new fglmVectorRep( size ) ) {}
101
102fglmVector::fglmVector( int size, int basis ) : rep( new fglmVectorRep( size ) )
103{
104    rep->setelem( basis, nInit( 1 ) );
105}
106
107fglmVector::fglmVector( const fglmVector & v )
108{
109    rep= (fglmVectorRep*)v.rep->copyObject();
110}
111
112fglmVector::~fglmVector()
113{
114    if ( rep->deleteObject() )
115        delete rep;
116}
117
118void 
119fglmVector::makeUnique()
120{
121    if ( rep->refcount() != 1 ) {
122        rep->deleteObject();
123        rep= rep->clone();
124    }
125}
126
127int 
128fglmVector::size() const
129{
130    return rep->size();
131}
132
133int
134fglmVector::numNonZeroElems() const
135{
136    return rep->numNonZeroElems();
137}
138
139fglmVector & 
140fglmVector::operator = ( const fglmVector & v )
141{
142    if ( this != &v ) {
143        if ( rep->deleteObject() )
144            delete rep;
145        rep = (fglmVectorRep*)v.rep->copyObject();
146    }
147    return *this;
148}
149
150subFglmVector
151fglmVector::operator () ( int min, int max )
152{
153    ASSERT( min > 0 && max >= min && max <= rep->size(), "illegal index" );
154    makeUnique();
155    return subFglmVector( min, max, rep );
156}
157
158const subFglmVector
159fglmVector::operator () ( int min, int max ) const
160{
161    ASSERT( min > 0 && max >= min && max <= rep->size(), "illegal index" );
162    return subFglmVector( min, max, rep );
163}
164
165int
166fglmVector::operator == ( const fglmVector & v )
167{
168    if ( rep->size() == v.rep->size() ) {
169        if ( rep == v.rep ) return 1;
170        else {
171            int i;
172            for ( i= rep->size(); i > 0; i-- )
173                if ( ! nEqual( rep->getconstelem( i ), v.rep->getconstelem( i ) ) )
174                    return 0;
175            return 1;
176        }
177    }
178    return 0;
179}
180
181int
182fglmVector::operator != ( const fglmVector & v )
183{
184    return !( *this == v );
185}
186
187int 
188fglmVector::isZero()
189{
190    int i;
191    for ( i= rep->size(); i > 0; i-- )
192        if ( ! nIsZero( rep->getconstelem( i ) ) )
193            return 0;
194    return 1;
195}
196
197fglmVector &
198fglmVector::operator += ( const fglmVector & v )
199{
200    ASSERT( size() == v.size(), "incompatible vectors" );
201    // ACHTUNG : Das Verhalten hier mit gcd genau ueberpruefen!
202    int i;
203    if ( rep->isUnique() ) {
204        for ( i= rep->size(); i > 0; i-- ) 
205            rep->setelem( i, nAdd( rep->getconstelem( i ), v.rep->getconstelem( i ) ) );
206    }
207    else 
208    {
209        int n = rep->size();
210        number* newelems;
211        newelems= (number *)Alloc( n*sizeof( number ) );
212        for ( i= n; i > 0; i-- )
213            newelems[i-1]= nAdd( rep->getconstelem( i ), v.rep->getconstelem( i ) );
214        rep->deleteObject();
215        rep= new fglmVectorRep( n, newelems );
216    }
217    return *this;
218}
219
220fglmVector &
221fglmVector::operator -= ( const fglmVector & v )
222{
223    ASSERT( size() == v.size(), "incompatible vectors" );
224    int i;
225    if ( rep->isUnique() ) {
226        for ( i= rep->size(); i > 0; i-- ) 
227            rep->setelem( i, nSub( rep->getconstelem( i ), v.rep->getconstelem( i ) ) );
228    }
229    else 
230    {
231        int n = rep->size();
232        number* newelems;
233        newelems= (number *)Alloc( n*sizeof( number ) );
234        for ( i= n; i > 0; i-- )
235            newelems[i-1]= nSub( rep->getconstelem( i ), v.rep->getconstelem( i ) );
236        rep->deleteObject();
237        rep= new fglmVectorRep( n, newelems );
238    }
239    return *this;
240}
241
242fglmVector &
243fglmVector::operator *= ( const number & n )
244{
245    int s= rep->size();
246    int i;
247    if ( ! rep->isUnique() ) {
248        number * temp;
249        temp= (number *)Alloc( s*sizeof( number ) );
250        for ( i= s; i > 0; i-- ) 
251            temp[i-1]= nMult( rep->getconstelem( i ), n );
252        rep->deleteObject();
253        rep= new fglmVectorRep( s, temp );
254    }
255    else 
256    {
257        for (i= s; i > 0; i-- ) 
258            rep->setelem( i, nMult( rep->getconstelem( i ), n ) );
259    }
260    return *this;
261}
262
263fglmVector &
264fglmVector::operator /= ( const number & n )
265{
266    int s= rep->size();
267    int i;
268    if ( ! rep->isUnique() ) {
269        number * temp;
270        temp= (number *)Alloc( s*sizeof( number ) );
271        for ( i= s; i > 0; i-- ) {
272            temp[i-1]= nDiv( rep->getconstelem( i ), n );
273            nNormalize( temp[i-1] );
274        }
275        rep->deleteObject();
276        rep= new fglmVectorRep( s, temp );
277    }
278    else 
279    {
280        for (i= s; i > 0; i-- ) {
281            rep->setelem( i, nDiv( rep->getconstelem( i ), n ) );
282            nNormalize( rep->getelem( i ) );
283        }
284    }
285    return *this;
286}
287
288fglmVector &
289fglmVector::operator *= ( const Mat & M ) 
290{
291    return *this;
292}
293
294fglmVector
295operator - ( const fglmVector & v ) 
296{
297    fglmVector temp( v.size() );
298    int i;
299    number n ;
300    for ( i= v.size(); i > 0; i-- ) {
301        n= nCopy( v.getconstelem( i ) );
302        n= nNeg( n );
303        temp.setelem( i, n );
304    }
305    return temp;
306}
307
308fglmVector
309operator + ( const fglmVector & lhs, const fglmVector & rhs ) 
310{
311    fglmVector temp= lhs;
312    temp+= rhs;
313    return temp;
314}
315
316fglmVector
317operator - ( const fglmVector & lhs, const fglmVector & rhs )
318{
319    fglmVector temp= lhs;
320    temp-= rhs;
321    return temp;
322}
323
324fglmVector
325operator * ( const fglmVector & v, const number n )
326{
327    fglmVector temp= v;
328    temp*= n;
329    return temp;
330}
331
332fglmVector
333operator * ( const number n, const fglmVector & v )
334{
335    fglmVector temp= v;
336    temp*= n;
337    return temp;
338}
339
340fglmVector
341operator * ( const Mat & M, const fglmVector & v )
342{
343    fglmVector temp= v;
344    temp*= M;
345    return temp;
346}
347
348number &
349fglmVector::getelem( int i )
350{
351    makeUnique();
352    return rep->getelem( i );
353}
354
355const number
356fglmVector::getconstelem( int i ) const
357{
358    return rep->getconstelem( i );
359}
360
361void
362fglmVector::setelem( int i, number & n )
363{
364    makeUnique();
365    rep->setelem( i, n );
366    n= nNULL;
367}
368
369number
370fglmVector::gcd() const
371{ 
372    int i= rep->size();
373    bool found = false;
374    bool gcdIsOne = false;
375    number theGcd;
376    number current;
377    //. einen Eintrag ungleich Null finden:
378    while( i > 0 && ! found ) {
379        current= rep->getconstelem( i );
380        if ( ! nIsZero( current ) ) {
381            theGcd= nCopy( current );
382            found= true;
383            //. positiv machen und ueberpruefen, ob gcd=1:
384            if ( ! nGreaterZero( theGcd ) ) {
385                theGcd= nNeg( theGcd );
386            }
387            if ( nIsOne( theGcd ) ) gcdIsOne= true;
388        }
389        i--;  //. i auf jeden Fall runterzaehlen.
390    }
391    if ( found ) {
392        while ( i > 0 && ! gcdIsOne ) {
393            current= rep->getconstelem( i );
394            if ( ! nIsZero( current ) ) {
395                // Hier gehe ich davon aus, dass nGcd seine Argumente nicht loescht!
396                number temp= nGcd( theGcd, current );
397                nDelete( &theGcd );
398                theGcd= temp;
399                if ( nIsOne( theGcd ) ) gcdIsOne= true;
400            }
401            i--;
402        }
403    }
404    else 
405        theGcd= nInit( 0 );
406    return theGcd;
407}
408
409number
410fglmVector::clearDenom() 
411{
412    number theLcm = nInit( 1 );
413    number current;
414    bool isZero = true;
415    int i;
416    for ( i= size(); i > 0; i-- ) {
417//      current= rep->getconstelem( i );
418//      if ( ! nIsZero( current ) ) {
419        if ( ! nIsZero( rep->getconstelem(i) ) ) {
420            isZero= false;
421//          number temp= nLcm( theLcm, current );
422            number temp= nLcm( theLcm, rep->getconstelem( i ) );
423            nDelete( &theLcm );
424            theLcm= temp;
425        }
426    }
427    if ( isZero ) {
428        nDelete( &theLcm );
429        theLcm= nInit( 0 );
430    }
431    else {
432        if ( ! nIsOne( theLcm ) ) {
433            *this *= theLcm;
434            for ( i= size(); i > 0; i-- ) {
435                nNormalize( rep->getelem( i ) );
436            }
437        }
438    }
439    return theLcm;
440}
441
442void 
443fglmVector::print( ostream & s ) const
444{
445    rep->print( s );
446}
447
448#ifdef FGLM_DEBUG
449void
450fglmVector::test() const
451{
452    int i;
453    BOOLEAN dummy;
454    for ( i= 1; i <= size(); i++ ) {
455        dummy= nTest( rep->getconstelem( i ) );
456    }
457}
458#endif
459
460///--------------------------------------------------------------------------------
461/// Implementation of class subFglmVector
462///--------------------------------------------------------------------------------
463
464subFglmVector::subFglmVector( int min, int max, fglmVectorRep * repr ) : minelem(min), maxelem(max), rep(repr) {}
465
466subFglmVector::subFglmVector( const subFglmVector & v ) : minelem(v.minelem), maxelem(v.maxelem), rep(v.rep) {}
467
468subFglmVector & 
469subFglmVector::operator = ( const subFglmVector & v )
470{
471    if ( this != &v ) {
472        ASSERT( maxelem-minelem == v.maxelem-v.minelem, "incompatible subFglmVectors" );
473        int n = maxelem - minelem;
474        int i;
475        if ( rep == v.rep ) {
476            // --> copy blocks of the same fglmVector
477            if ( minelem < v.minelem )
478                for ( i = 0; i <= n; i++ ) 
479                    rep->setelem( minelem + i, nCopy( rep->getconstelem( v.minelem + i ) ) );
480            else if ( minelem > v.minelem )
481                for ( i = n; i >= 0; i-- ) 
482                    rep->setelem( minelem + i, nCopy( rep->getconstelem( v.minelem + i ) ) );
483        }   
484        else {
485            for ( i = 0; i <= n; i++ ) 
486                rep->setelem( minelem + i , nCopy( v.rep->getconstelem( v.minelem + i ) ) );
487        }
488    }
489    return *this;
490}
491
492subFglmVector & 
493subFglmVector::operator = ( const fglmVector & v )
494{
495    number newelem;
496    ASSERT( maxelem-minelem+1 == v.size(), "incompatible subFglmVectors" );
497    if ( rep != v.rep ) {
498        int n = v.size();
499        int i;
500        for ( i = 0; i < n; i++ ) 
501            rep->setelem( minelem + i, nCopy( v.rep->getconstelem( 1 + i ) ) );
502    }
503    return *this;
504}
505
506// T &
507// subFglmVector::operator[] ( int i )
508// {
509//     ASSERT( minelem <= i && i <= maxelem, "illegal index" );
510//     return rep->elem( i );
511// }
512
513// const number &
514// subFglmVector::operator [] ( int i ) const
515// {
516//     return rep->getelem( i );
517// }   
518
519subFglmVector &
520subFglmVector::operator += ( const fglmVector & v )
521{
522    ASSERT( maxelem-minelem+1 == v.size(), "incompatible Vectors" );
523    ASSERT( rep->isUnique(), "this should never happen" );
524    int i;
525    for ( i= v.size()-1; i >= 0; i-- )
526        rep->setelem( minelem + i, nAdd( rep->getconstelem( minelem + i ), v.rep->getconstelem( 1 + i ) ) );
527    return *this;
528}
529
530subFglmVector &
531subFglmVector::operator += ( const subFglmVector & v )
532{
533    ASSERT( maxelem-minelem == v.maxelem-v.minelem, "incompatible SubVectors" );
534    ASSERT( rep->isUnique(), "this should never happen" );
535    int i;
536    int n= maxelem-minelem;
537    if ( rep == v.rep ) {
538        if ( minelem >= v.minelem )
539            for ( i= n; i >= 0; i-- ) 
540                rep->setelem( minelem + i, nAdd( rep->getconstelem( minelem + i ), rep->getconstelem( v.minelem + i ) ) );
541        else 
542            for ( i= 0; i<= n; i++ ) 
543                rep->setelem( minelem + i, nAdd( rep->getconstelem( minelem + i ), rep->getconstelem( v.minelem + i ) ) );
544    }
545    else
546        for ( i= maxelem-minelem; i >= 0; i-- )
547            rep->setelem( minelem + i, nAdd( rep->getconstelem( minelem + i ), v.rep->getconstelem( v.minelem + i ) ) );
548    return *this;
549}
550
551subFglmVector &
552subFglmVector::operator -= ( const fglmVector & v )
553{
554    ASSERT( maxelem-minelem+1 == v.size(), "incompaitble Vectors" );
555    ASSERT( rep->isUnique(), "this should never happen" );
556    int i;
557    for ( i= v.size()-1; i >= 0; i-- ) 
558        rep->setelem( minelem + i, nSub( rep->getconstelem( minelem + i ), v.rep->getconstelem( 1 + i ) ) );
559    return *this;
560}
561
562subFglmVector &
563subFglmVector::operator -= ( const subFglmVector & v )
564{
565    ASSERT( maxelem-minelem == v.maxelem-v.minelem, "incompatible SubVectors" );
566    ASSERT( rep->isUnique(), "this should never happen" );
567    int i;
568    int n = maxelem - minelem;
569    if ( rep == v.rep ) {
570        if ( minelem == v.minelem )
571            for ( i= n; i >= 0; i-- ) rep->setelem( minelem + i, nInit(0) );
572        else if ( minelem > v.minelem )
573            for ( i= n; i >= 0; i-- ) 
574                rep->setelem( minelem + i, nSub( rep->getconstelem( minelem + i ), rep->getconstelem( v.minelem + i ) ) );
575        else 
576            for ( i= 0; i<= n; i++ ) 
577                rep->setelem( minelem + i, nSub( rep->getconstelem( minelem + i ), rep->getconstelem( v.minelem + i ) ) );
578    }
579    else
580        for ( i= n; i >= 0; i-- )
581            rep->setelem( minelem + i, nSub( rep->getconstelem( minelem + i ), v.rep->getconstelem( minelem + i ) ) );
582    return *this;
583}
584
585subFglmVector&
586subFglmVector::operator *= ( const number & n )
587{
588    ASSERT( rep->isUnique(), "this should never happen" );
589    int i;
590    for ( i= minelem; i <= maxelem; i++ )
591        rep->setelem( i, nMult( rep->getconstelem( i ), n ) );
592    return *this;
593}
594
595subFglmVector::operator fglmVector() const
596{
597    if ( minelem == 1 && maxelem == rep->size() )
598        return fglmVector( (fglmVectorRep*)rep->copyObject() );
599    else {
600        int n = maxelem-minelem+1;
601        int i;
602        number * newelems;
603        newelems= (number *)Alloc( n*sizeof( number ) );
604
605        for ( i= 0; i < n; i++ )
606            newelems[i] = nCopy( rep->getconstelem( minelem + i ) );
607        return fglmVector( new fglmVectorRep( n, newelems ) );
608    }
609}
610
611
Note: See TracBrowser for help on using the repository browser.