source: git/factory/int_poly.cc @ 7d9585

spielwiese
Last change on this file since 7d9585 was 7d9585, checked in by Jens Schmidt <schmidt@…>, 26 years ago
* int_poly.cc: doc fix git-svn-id: file:///usr/local/Singular/svn/trunk@996 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 32.0 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: int_poly.cc,v 1.9 1997-12-17 14:15:06 schmidt Exp $ */
3
4#include <config.h>
5
6#ifndef NOSTREAMIO
7#include <string.h>
8#ifdef WINNT
9#include <strstrea.h>
10#else
11#include <strstream.h>
12#endif
13#endif /* NOSTREAMIO */
14
15#include "assert.h"
16
17#include "cf_defs.h"
18#include "cf_factory.h"
19#include "int_cf.h"
20#include "int_poly.h"
21#include "canonicalform.h"
22#include "variable.h"
23#include "imm.h"
24
25
26InternalPoly::InternalPoly( termList first, termList last, const Variable & v )
27{
28    firstTerm = first;
29    lastTerm = last;
30    var = v;
31}
32
33InternalPoly::InternalPoly()
34{
35    ASSERT( 0, "ups, why do you initialize an empty poly" );
36}
37
38InternalPoly::InternalPoly( const Variable & v, const int e, const CanonicalForm& c )
39{
40    var = v;
41    firstTerm = new term( 0, c, e );
42    lastTerm = firstTerm;
43}
44
45InternalPoly::InternalPoly( const InternalPoly& )
46{
47    ASSERT( 0, "ups there is something wrong in your code" );
48};
49
50InternalPoly::~InternalPoly()
51{
52    freeTermList( firstTerm );
53}
54
55InternalCF*
56InternalPoly::deepCopyObject() const
57{
58    termList first, last;
59    first = deepCopyTermList( firstTerm, last );
60    return new InternalPoly( first, last, var );
61}
62
63InternalCF*
64InternalPoly::genZero()
65{
66    return firstTerm->coeff.genZero().getval();
67}
68
69InternalCF*
70InternalPoly::genOne()
71{
72    return firstTerm->coeff.genOne().getval();
73}
74
75bool
76InternalPoly::isUnivariate() const
77{
78    termList cursor = firstTerm;
79    while ( cursor ) {
80        if ( ! cursor->coeff.inCoeffDomain() )
81            return false;
82        cursor = cursor->next;
83    }
84    return true;
85}
86
87//{{{ int InternalPoly::degree ()
88// docu: see CanonicalForm::sign ()
89int
90InternalPoly::degree ()
91{
92    return firstTerm->exp;
93}
94//}}}
95
96//{{{ int InternalPoly::sign () const
97// docu: see CanonicalForm::sign()
98int
99InternalPoly::sign () const
100{
101    return firstTerm->coeff.sign();
102}
103//}}}
104
105//{{{ CanonicalForm InternalPoly::lc (), Lc (), LC ()
106// docu: see CanonicalForm::lc(), Lc(), LC()
107CanonicalForm
108InternalPoly::lc ()
109{
110    return firstTerm->coeff.lc();
111}
112
113CanonicalForm
114InternalPoly::Lc ()
115{
116    return firstTerm->coeff.Lc();
117}
118
119CanonicalForm
120InternalPoly::LC ()
121{
122    return firstTerm->coeff;
123}
124//}}}
125
126//{{{ CanonicalForm InternalPoly::tailcoeff (), int InternalPoly::taildegree ()
127// docu: see CanonicalForm::tailcoeff(), taildegree()
128CanonicalForm
129InternalPoly::tailcoeff ()
130{
131    return lastTerm->coeff;
132}
133
134int
135InternalPoly::taildegree ()
136{
137    return lastTerm->exp;
138}
139//}}}
140
141//{{{ CanonicalForm InternalPoly::coeff ( int i )
142// docu: see CanonicalForm::operator []()
143CanonicalForm
144InternalPoly::coeff ( int i )
145{
146    termList theCursor = firstTerm;
147    while ( theCursor ) {
148        if ( theCursor->exp == i )
149            return theCursor->coeff;
150        else if ( theCursor->exp < i )
151            return CanonicalForm( 0 );
152        else
153            theCursor = theCursor->next;
154    }
155    return CanonicalForm( 0 );
156}
157//}}}
158
159#ifndef NOSTREAMIO
160void
161InternalPoly::print(ostream &aStream, char * aString )
162{
163    if ( ! firstTerm )
164        aStream << 0 << aString;
165    else {
166        char * theString;
167        termList theCursor = firstTerm;
168        while ( theCursor ) {
169            ostrstream theStream;
170            if ( theCursor->exp == 0 )
171                theCursor->coeff.print( aStream, aString );
172            else  if ( theCursor->coeff.isOne() ) {
173                aStream << var;
174                if ( theCursor->exp != 1 )
175                    aStream << '^' << theCursor->exp << aString;
176                else
177                    aStream << aString;
178            }
179            else  if ( theCursor->coeff.sign() < 0 && (-theCursor->coeff).isOne() ) {
180                aStream << '-' << var;
181                if ( theCursor->exp != 1 )
182                    aStream << '^' << theCursor->exp << aString;
183                else
184                    aStream << aString;
185            }
186            else {
187                theStream << '*' << var;
188                if ( theCursor->exp != 1 )
189                    theStream << '^' << theCursor->exp << aString << ends;
190                else
191                    theStream << aString << ends; // results from error in GNU strstream
192                theString = theStream.str();
193                theCursor->coeff.print( aStream, theString );
194                delete [] theString;
195            }
196            theCursor = theCursor->next;
197            if ( theCursor && ( theCursor->coeff.sign() >= 0 ) )
198                aStream << '+';
199        }
200    }
201}
202#endif /* NOSTREAMIO */
203
204InternalCF*
205InternalPoly::neg()
206{
207    if ( getRefCount() == 1 ) {
208        negateTermList( firstTerm );
209        return this;
210    }
211    else {
212        decRefCount();
213        termList last, first = copyTermList( firstTerm, last, true );
214        return new InternalPoly( first, last, var );
215    }
216}
217
218InternalCF*
219InternalPoly::invert()
220{
221    if ( inExtension() && getReduce( var ) ) {
222        setReduce( var, false );
223        CanonicalForm a( this->copyObject() );
224        CanonicalForm b = getMipo( var );
225        CanonicalForm u, v;
226        CanonicalForm g = extgcd( a, b, u, v );
227        setReduce( var, true );
228        return u.getval();
229    }
230    else
231        return CFFactory::basic( 0 );
232}
233
234InternalCF*
235InternalPoly::addsame( InternalCF* aCoeff )
236{
237    InternalPoly * aPoly = (InternalPoly*)aCoeff;
238    if ( getRefCount() == 1 ) {
239        firstTerm = addTermList( firstTerm, aPoly->firstTerm, lastTerm, false );
240        if ( firstTerm && firstTerm->exp != 0 )
241            return this;
242        else  if ( firstTerm ) {
243            InternalCF * res = firstTerm->coeff.getval();
244            delete this;
245            return res;
246        }
247        else {
248            delete this;
249            return CFFactory::basic( 0 );
250        }
251    }
252    else {
253        decRefCount();
254        termList last, first = copyTermList( firstTerm, last );
255        first = addTermList( first, aPoly->firstTerm, last, false );
256        if ( first && first->exp != 0 )
257            return new InternalPoly( first, last, var );
258        else  if ( first ) {
259            InternalCF * res = first->coeff.getval();
260            delete first;
261            return res;
262        }
263        else
264            return CFFactory::basic( 0 );
265
266    }
267}
268
269InternalCF*
270InternalPoly::subsame( InternalCF* aCoeff )
271{
272    InternalPoly * aPoly = (InternalPoly*)aCoeff;
273    if ( getRefCount() == 1 ) {
274        firstTerm = addTermList( firstTerm, aPoly->firstTerm, lastTerm, true );
275        if ( firstTerm && firstTerm->exp != 0 )
276            return this;
277        else  if ( firstTerm ) {
278            InternalCF * res = firstTerm->coeff.getval();
279            delete this;
280            return res;
281        }
282        else {
283            delete this;
284            return CFFactory::basic( 0 );
285        }
286    }
287    else {
288        decRefCount();
289        termList last, first = copyTermList( firstTerm, last );
290        first = addTermList( first, aPoly->firstTerm, last, true );
291        if ( first && first->exp != 0 )
292            return new InternalPoly( first, last, var );
293        else  if ( first ) {
294            InternalCF * res = first->coeff.getval();
295            delete first;
296            return res;
297        }
298        else
299            return CFFactory::basic( 0 );
300
301    }
302}
303
304InternalCF*
305InternalPoly::mulsame( InternalCF* aCoeff )
306{
307    InternalPoly *aPoly = (InternalPoly*)aCoeff;
308    termList resultFirst = 0, resultLast = 0;
309    termList theCursor = firstTerm;
310
311    while ( theCursor ) {
312        resultFirst = mulAddTermList( resultFirst, aPoly->firstTerm, theCursor->coeff, theCursor->exp, resultLast, false );
313        theCursor = theCursor->next;
314    }
315    if ( inExtension() && getReduce( var ) ) {
316        resultFirst = reduceTermList( resultFirst, (getInternalMipo( var ))->firstTerm, resultLast );
317        if ( resultFirst == 0 )
318            if ( getRefCount() == 1 ) {
319                delete this;
320                return CFFactory::basic(0);
321            }
322            else {
323                decRefCount();
324                return CFFactory::basic(0);
325            }
326        else  if ( resultFirst->exp == 0 )
327            if ( getRefCount() == 1 ) {
328                InternalCF * res = resultFirst->coeff.getval();
329                delete resultFirst;
330                delete this;
331                return res;
332            }
333            else {
334                decRefCount();
335                InternalCF * res = resultFirst->coeff.getval();
336                delete resultFirst;
337                return res;
338            }
339    }
340    if ( getRefCount() == 1 ) {
341        freeTermList( firstTerm );
342        firstTerm = resultFirst;
343        lastTerm = resultLast;
344        return this;
345    }
346    else {
347        decRefCount();
348        return new InternalPoly( resultFirst, resultLast, var );
349    }
350}
351
352InternalCF*
353InternalPoly::dividesame( InternalCF* aCoeff )
354{
355    return divsame( aCoeff );
356}
357
358
359InternalCF*
360InternalPoly::divsame( InternalCF* aCoeff )
361{
362    if ( inExtension() && getReduce( var ) ) {
363        InternalCF * dummy = aCoeff->invert();
364        dummy = dummy->mulsame( this );
365        if ( getRefCount() == 1 ) {
366             delete this;
367             return dummy;
368        }
369        else {
370            decRefCount();
371            return dummy;
372        }
373    }
374    InternalPoly *aPoly = (InternalPoly*)aCoeff;
375    termList dummy, first, last, resultfirst = 0, resultlast = 0;
376    CanonicalForm coeff, newcoeff;
377    int exp, newexp;
378    bool singleObject;
379
380    if ( getRefCount() == 1 ) {
381        first = firstTerm; last = lastTerm; singleObject = true;
382    }
383    else {
384        first = copyTermList( firstTerm, last ); singleObject = false;
385        decRefCount();
386    }
387    coeff = aPoly->firstTerm->coeff;
388    exp = aPoly->firstTerm->exp;
389    while (first && ( first->exp >= exp ) ) {
390        newcoeff = first->coeff / coeff;
391        newexp = first->exp - exp;
392        dummy = first;
393        first = mulAddTermList( first->next, aPoly->firstTerm->next, newcoeff, newexp, last, true );
394        delete dummy;
395        appendTermList( resultfirst, resultlast, newcoeff, newexp );
396    }
397    freeTermList( first );
398    if ( singleObject ) {
399        if ( resultfirst && resultfirst->exp != 0 ) {
400            firstTerm = resultfirst;
401            lastTerm = resultlast;
402            return this;
403        }
404        else  if ( resultfirst ) {
405            InternalCF * res = resultfirst->coeff.getval();
406            delete resultfirst;
407            firstTerm = 0;
408            delete this;
409            return res;
410        }
411        else {
412            // this should not happen (evtl use assertion)
413            ASSERT( 0, "FATAL ERROR, PLEASE INFORM THE AUTHOR" );
414            firstTerm = 0;
415            delete this;
416            return CFFactory::basic( 0 );
417        }
418    }
419    else {
420        if ( resultfirst && resultfirst->exp != 0 )
421            return new InternalPoly( resultfirst, resultlast, var );
422        else  if ( resultfirst ) {
423            InternalCF * res = resultfirst->coeff.getval();
424            delete resultfirst;
425            return res;
426        }
427        else
428            return CFFactory::basic( 0 );
429    }
430}
431
432InternalCF*
433InternalPoly::modulosame( InternalCF* aCoeff )
434{
435    return modsame( aCoeff );
436}
437
438InternalCF*
439InternalPoly::modsame( InternalCF* aCoeff )
440{
441    if ( inExtension() && getReduce( var ) ) {
442        if ( deleteObject() ) delete this;
443        return CFFactory::basic( 0 );
444    }
445    InternalPoly *aPoly = (InternalPoly*)aCoeff;
446    termList dummy, first, last;
447    CanonicalForm coeff, newcoeff;
448    int exp, newexp;
449    bool singleObject;
450
451    if ( getRefCount() == 1 ) {
452        first = firstTerm; last = lastTerm; singleObject = true;
453    }
454    else {
455        first = copyTermList( firstTerm, last ); singleObject = false;
456        decRefCount();
457    }
458    coeff = aPoly->firstTerm->coeff;
459    exp = aPoly->firstTerm->exp;
460    while (first && ( first->exp >= exp ) ) {
461        newcoeff = first->coeff / coeff;
462        newexp = first->exp - exp;
463        dummy = first;
464        first = mulAddTermList( first->next, aPoly->firstTerm->next, newcoeff, newexp, last, true );
465        delete dummy;
466    }
467    if ( singleObject ) {
468        if ( first && first->exp != 0 ) {
469            firstTerm = first;
470            lastTerm = last;
471            return this;
472        }
473        else  if ( first ) {
474            InternalCF * res = first->coeff.getval();
475            delete first;
476            firstTerm = 0;
477            delete this;
478            return res;
479        }
480        else {
481            firstTerm = 0;
482            delete this;
483            return CFFactory::basic( 0 );
484        }
485    }
486    else {
487        if ( first && first->exp != 0 )
488            return new InternalPoly( first, last, var );
489        else  if ( first ) {
490            InternalCF * res = first->coeff.getval();
491            delete first;
492            return res;
493        }
494        else
495            return CFFactory::basic( 0 );
496    }
497}
498
499
500void
501InternalPoly::divremsame( InternalCF* acoeff, InternalCF*& quot, InternalCF*& rem )
502{
503    if ( inExtension() && getReduce( var ) ) {
504        InternalCF * dummy = acoeff->invert();
505        quot = dummy->mulsame( this );
506        rem = CFFactory::basic( 0 );
507    }
508    else {
509        InternalPoly *aPoly = (InternalPoly*)acoeff;
510        termList dummy, first, last, resultfirst = 0, resultlast = 0;
511        CanonicalForm coeff, newcoeff;
512        int exp, newexp;
513
514        first = copyTermList( firstTerm, last );
515
516        coeff = aPoly->firstTerm->coeff;
517        exp = aPoly->firstTerm->exp;
518        while (first && ( first->exp >= exp ) ) {
519            newcoeff = first->coeff / coeff;
520            newexp = first->exp - exp;
521            dummy = first;
522            first = mulAddTermList( first->next, aPoly->firstTerm->next, newcoeff, newexp, last, true );
523            delete dummy;
524            appendTermList( resultfirst, resultlast, newcoeff, newexp );
525        }
526        if ( resultfirst )
527            if ( resultfirst->exp == 0 ) {
528                quot = resultfirst->coeff.getval();
529                delete resultfirst;
530            }
531            else
532                quot = new InternalPoly( resultfirst, resultlast, var );
533        else
534            quot = CFFactory::basic( 0 );
535        if ( first )
536            if ( first->exp == 0 ) {
537                rem = first->coeff.getval();
538                delete first;
539            }
540            else
541                rem = new InternalPoly( first, last, var );
542        else
543            rem = CFFactory::basic( 0 );
544    }
545}
546
547
548bool
549InternalPoly::divremsamet( InternalCF* acoeff, InternalCF*& quot, InternalCF*& rem )
550{
551    if ( inExtension() && getReduce( var ) ) {
552        divremsame( acoeff, quot, rem );
553        return true;
554    }
555    InternalPoly *aPoly = (InternalPoly*)acoeff;
556    termList dummy, first, last, resultfirst = 0, resultlast = 0;
557    CanonicalForm coeff, newcoeff, dummycoeff;
558    int exp, newexp;
559    bool divideok = true;
560
561//    if ( ! ::divremt( lastTerm->coeff, aPoly->lastTerm->coeff, newcoeff, dummycoeff ) )
562//      return false;
563
564    first = copyTermList( firstTerm, last );
565
566    coeff = aPoly->firstTerm->coeff;
567    exp = aPoly->firstTerm->exp;
568    while (first && ( first->exp >= exp ) && divideok ) {
569        divideok = ::divremt( first->coeff, coeff, newcoeff, dummycoeff );
570        if ( divideok && dummycoeff.isZero() ) {
571            newexp = first->exp - exp;
572            dummy = first;
573            first = mulAddTermList( first->next, aPoly->firstTerm->next, newcoeff, newexp, last, true );
574            delete dummy;
575            appendTermList( resultfirst, resultlast, newcoeff, newexp );
576        }
577        else
578            divideok = false;
579    }
580    if ( divideok ) {
581        if ( resultfirst )
582            if ( resultfirst->exp == 0 ) {
583                quot = resultfirst->coeff.getval();
584                delete resultfirst;
585            }
586            else
587                quot = new InternalPoly( resultfirst, resultlast, var );
588        else
589            quot = CFFactory::basic( 0 );
590        if ( first )
591            if ( first->exp == 0 ) {
592                rem = first->coeff.getval();
593                delete first;
594            }
595            else
596                rem = new InternalPoly( first, last, var );
597        else
598            rem = CFFactory::basic( 0 );
599    }
600    else {
601        freeTermList( resultfirst );
602        freeTermList( first );
603    }
604    return divideok;
605}
606
607//{{{ int InternalPoly::comparesame, comparecoeff ( InternalCF * acoeff )
608//{{{ docu
609//
610// comparesame(), comparecoeff() - compare with an
611//   InternalPoly.
612//
613// comparecoeff() always returns 1 since CO is defined to be
614// larger than anything which is a coefficient w.r.t. CO.
615//
616// comparesame() compares the coefficient vectors of f=CO and
617// g=acoeff w.r.t to a lexicographic order in the following way:
618// f < g iff there exists an 0 <= i <= max(deg(f),deg(g)) s.t.
619// i) f[j] = g[j] for all i < j <= max(deg(f),deg(g)) and
620// ii) g[i] occurs in g (i.e. is not equal to zero) and
621//     f[i] does not occur in f or f[i] < g[i] if f[i] occurs
622// where f[i] denotes the coefficient to the power x^i of f.
623//
624// As usual, comparesame() returns 1 if CO is larger than c, 0 if
625// CO equals c, and -1 if CO is less than c.  However, this
626// function is optimized to test on equality since this is its
627// most important and frequent usage.
628//
629// See the respective `CanonicalForm'-methods for an explanation
630// why we define such a strange (but total) ordering on
631// polynomials.
632//
633// See also: CanonicalForm::operator <(), CanonicalForm::operator ==()
634//
635//}}}
636int
637InternalPoly::comparesame ( InternalCF * acoeff )
638{
639    ASSERT( ! ::is_imm( acoeff ) && acoeff->level() > LEVELBASE, "incompatible base coefficients" );
640    InternalPoly* apoly = (InternalPoly*)acoeff;
641    // check on triviality
642    if ( this == apoly )
643        return 0;
644    else {
645        termList cursor1 = firstTerm;
646        termList cursor2 = apoly->firstTerm;
647        for ( ; cursor1 && cursor2; cursor1 = cursor1->next, cursor2 = cursor2->next )
648            // we test on inequality of coefficients at this
649            // point instead of testing on "less than" at the
650            // last `else' in the enclosed `if' statement since a
651            // test on inequaltiy in general is cheaper
652            if ( (cursor1->exp != cursor2->exp) || (cursor1->coeff != cursor2->coeff) )
653                if ( cursor1->exp > cursor2->exp )
654                    return 1;
655                else  if ( cursor1->exp < cursor2->exp )
656                    return -1;
657                else  if ( cursor1->coeff > cursor2->coeff )
658                    return 1;
659                else
660                    return -1;
661        // check trailing terms
662        if ( cursor1 == cursor2 )
663            return 0;
664        else if ( cursor1 != 0 )
665            return 1;
666        else
667            return -1;
668    }
669}
670
671int
672InternalPoly::comparecoeff ( InternalCF * )
673{
674    return 1;
675}
676//}}}
677
678InternalCF*
679InternalPoly::addcoeff( InternalCF* cc )
680{
681    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
682    if ( c.isZero() )
683        return this;
684    else {
685        if ( getRefCount() == 1 ) {
686            if ( lastTerm->exp == 0 ) {
687                lastTerm->coeff += c;
688                if ( lastTerm->coeff.isZero() ) {
689                    termList cursor = firstTerm;
690                    while ( cursor->next != lastTerm )
691                        cursor = cursor->next;
692                    delete lastTerm;
693                    cursor->next = 0;
694                    lastTerm = cursor;
695                }
696            }
697            else {
698                lastTerm->next = new term( 0, c, 0 );
699                lastTerm = lastTerm->next;
700            }
701            return this;
702        }
703        else {
704            decRefCount();
705            termList last, first = copyTermList( firstTerm, last, false );
706            if ( last->exp == 0 ) {
707                last->coeff += c;
708                if ( last->coeff.isZero() ) {
709                    termList cursor = first;
710                    while ( cursor->next != last )
711                        cursor = cursor->next;
712                    delete last;
713                    cursor->next = 0;
714                    last = cursor;
715                }
716            }
717            else {
718                last->next = new term( 0, c, 0 );
719                last = last->next;
720            }
721            return new InternalPoly( first, last, var );
722        }
723    }
724}
725
726InternalCF*
727InternalPoly::subcoeff( InternalCF* cc, bool negate )
728{
729    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
730    if ( c.isZero() )
731        if ( getRefCount() > 1 ) {
732            decRefCount();
733            termList last, first = copyTermList( firstTerm, last, negate );
734            return new InternalPoly( first, last, var );
735        }
736        else {
737            if ( negate )
738                negateTermList( firstTerm );
739            return this;
740        }
741    else {
742        if ( getRefCount() == 1 ) {
743            if ( lastTerm->exp == 0 ) {
744                if ( negate ) {
745                    negateTermList( firstTerm );
746                    lastTerm->coeff += c;
747                }
748                else
749                    lastTerm->coeff -= c;
750                if ( lastTerm->coeff.isZero() ) {
751                    termList cursor = firstTerm;
752                    while ( cursor->next != lastTerm )
753                        cursor = cursor->next;
754                    delete lastTerm;
755                    cursor->next = 0;
756                    lastTerm = cursor;
757                }
758            }
759            else {
760                if ( negate ) {
761                    negateTermList( firstTerm );
762                    lastTerm->next = new term( 0, c, 0 );
763                }
764                else
765                    lastTerm->next = new term( 0, -c, 0 );
766                lastTerm = lastTerm->next;
767            }
768            return this;
769        }
770        else {
771            decRefCount();
772            termList last, first = copyTermList( firstTerm, last, negate );
773            if ( last->exp == 0 ) {
774                if ( negate )
775                    last->coeff += c;
776                else
777                    last->coeff -= c;
778                if ( last->coeff.isZero() ) {
779                    termList cursor = first;
780                    while ( cursor->next != last )
781                        cursor = cursor->next;
782                    delete last;
783                    cursor->next = 0;
784                    last = cursor;
785                }
786            }
787            else {
788                if ( negate )
789                    last->next = new term( 0, c, 0 );
790                else
791                    last->next = new term( 0, -c, 0 );
792                last = last->next;
793            }
794            return new InternalPoly( first, last, var );
795        }
796    }
797}
798
799InternalCF*
800InternalPoly::mulcoeff( InternalCF* cc )
801{
802    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
803    if ( c.isZero() ) {
804        if ( getRefCount() == 1 ) {
805            delete this;
806            return CFFactory::basic( 0 );
807        }
808        else {
809            decRefCount();
810            return CFFactory::basic( 0 );
811        }
812    }
813    else  if ( c.isOne() )
814        return this;
815    else {
816        if ( getRefCount() == 1 ) {
817            mulTermList( firstTerm, c, 0 );
818            return this;
819        }
820        else {
821            decRefCount();
822            termList last, first = copyTermList( firstTerm, last );
823            mulTermList( first, c, 0 );
824            return new InternalPoly( first, last, var );
825        }
826    }
827}
828
829InternalCF*
830InternalPoly::dividecoeff( InternalCF* c, bool invert )
831{
832    return divcoeff( c, invert );
833}
834
835InternalCF*
836InternalPoly::divcoeff( InternalCF* cc, bool invert )
837{
838    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
839    if ( inExtension() && getReduce( var ) && invert ) {
840        InternalCF * dummy;
841        dummy = this->invert();
842        dummy = dummy->mulcoeff( cc );
843        if ( getRefCount() == 1 ) {
844            delete this;
845            return dummy;
846        }
847        else {
848            decRefCount();
849            return dummy;
850        }
851    }
852    if ( invert )
853        if ( getRefCount() == 1 ) {
854            delete this;
855            return CFFactory::basic( 0 );
856        }
857        else {
858            decRefCount();
859            return CFFactory::basic( 0 );
860        }
861    if ( c.isOne() )
862        return this;
863    else {
864        if ( getRefCount() == 1 ) {
865            firstTerm = divTermList( firstTerm, c, lastTerm );
866            if ( firstTerm && firstTerm->exp != 0 )
867                return this;
868            else  if ( firstTerm ) {
869                InternalCF * res = firstTerm->coeff.getval();
870                delete this;
871                return res;
872            }
873            else {
874                delete this;
875                return CFFactory::basic( 0 );
876            }
877        }
878        else {
879            decRefCount();
880            termList last, first = copyTermList( firstTerm, last );
881            first = divTermList( first, c, last );
882            if ( first && first->exp != 0 )
883                return new InternalPoly( first, last, var );
884            else  if ( first ) {
885                InternalCF * res = first->coeff.getval();
886                delete first;
887                return res;
888            }
889            else {
890                delete first;
891                return CFFactory::basic( 0 );
892            }
893        }
894    }
895}
896
897InternalCF*
898InternalPoly::modulocoeff( InternalCF* cc, bool invert )
899{
900    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
901    if ( invert ) {
902        if ( deleteObject() ) delete this;
903        return c.getval();
904    }
905    ASSERT( ! c.isZero(), "divide by zero!" );
906    if ( deleteObject() ) delete this;
907    return CFFactory::basic( 0 );
908}
909
910InternalCF*
911InternalPoly::modcoeff( InternalCF* cc, bool invert )
912{
913    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
914    if ( invert ) {
915        if ( deleteObject() ) delete this;
916        return c.getval();
917    }
918    ASSERT( ! c.isZero(), "divide by zero!" );
919    if ( c.isOne() ) {
920        if ( getRefCount() == 1 ) {
921            delete this;
922            return CFFactory::basic( 0 );
923        }
924        else {
925            decRefCount();
926            return CFFactory::basic( 0 );
927        }
928    }
929    else {
930        if ( getRefCount() == 1 ) {
931            firstTerm = modTermList( firstTerm, c, lastTerm );
932            if ( firstTerm && firstTerm->exp != 0 )
933                return this;
934            else  if ( firstTerm ) {
935                InternalCF * res = firstTerm->coeff.getval();
936                delete this;
937                return res;
938            }
939            else {
940                delete this;
941                return CFFactory::basic( 0 );
942            }
943        }
944        else {
945            decRefCount();
946            termList last, first = copyTermList( firstTerm, last );
947            first = modTermList( first, c, last );
948            if ( first && first->exp != 0 )
949                return new InternalPoly( first, last, var );
950            else  if ( first ) {
951                InternalCF * res = first->coeff.getval();
952                delete first;
953                return res;
954            }
955            else {
956                delete first;
957                return CFFactory::basic( 0 );
958            }
959        }
960    }
961}
962
963void
964InternalPoly::divremcoeff( InternalCF* cc, InternalCF*& quot, InternalCF*& rem, bool invert )
965{
966    if ( inExtension() && getReduce( var ) ) {
967        quot = copyObject();
968        quot = quot->dividecoeff( cc, invert );
969        rem = CFFactory::basic( 0 );
970    }
971    else  if ( invert ) {
972        if ( is_imm( cc ) )
973            rem = cc;
974        else
975            rem = cc->copyObject();
976        quot = CFFactory::basic( 0 );
977    }
978    else {
979        CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
980        ASSERT( ! c.isZero(), "divide by zero!" );
981        termList quotlast, quotfirst = copyTermList( firstTerm, quotlast );
982        quotfirst = divTermList( quotfirst, c, quotlast );
983        if ( quotfirst )
984            if ( quotfirst->exp == 0 ) {
985                quot = quotfirst->coeff.getval();
986                delete quotfirst;
987            }
988            else
989                quot = new InternalPoly( quotfirst, quotlast, var );
990        else
991            quot = CFFactory::basic( 0 );
992        rem = CFFactory::basic( 0 );
993    }
994}
995
996bool
997InternalPoly::divremcoefft( InternalCF* cc, InternalCF*& quot, InternalCF*& rem, bool invert )
998{
999    if ( inExtension() && getReduce( var ) ) {
1000        quot = copyObject();
1001        quot = quot->dividecoeff( cc, invert );
1002        rem = CFFactory::basic( 0 );
1003        return true;
1004    }
1005    else  if ( invert ) {
1006        if ( is_imm( cc ) )
1007            rem = cc;
1008        else
1009            rem = cc->copyObject();
1010        quot = CFFactory::basic( 0 );
1011        return true;
1012    }
1013    CanonicalForm c( is_imm(cc) ? cc : cc->copyObject() );
1014    ASSERT( ! c.isZero(), "divide by zero!" );
1015    termList quotfirst, quotcursor;
1016    termList cursor;
1017    CanonicalForm cquot, crem;
1018    bool divideok = true;
1019
1020    cursor = firstTerm;
1021    quotcursor = quotfirst = new term;
1022
1023    while ( cursor && divideok ) {
1024        divideok = ::divremt( cursor->coeff, c, cquot, crem );
1025        divideok = divideok && crem.isZero();
1026        if ( divideok ) {
1027            if ( ! cquot.isZero() ) {
1028                quotcursor->next = new term( 0, cquot, cursor->exp );
1029                quotcursor = quotcursor->next;
1030            }
1031            cursor = cursor->next;
1032        }
1033    }
1034    quotcursor->next = 0;
1035    if ( divideok ) {
1036        cursor = quotfirst; quotfirst = quotfirst->next; delete cursor;
1037        if ( quotfirst )
1038            if ( quotfirst->exp == 0 ) {
1039                quot = quotfirst->coeff.getval();
1040                delete quotfirst;
1041            }
1042            else
1043                quot = new InternalPoly( quotfirst, quotcursor, var );
1044        else
1045            quot = CFFactory::basic( 0 );
1046        rem = CFFactory::basic( 0 );
1047    }
1048    else {
1049        freeTermList( quotfirst );
1050    }
1051    return divideok;
1052}
1053
1054// static functions
1055
1056termList
1057InternalPoly::copyTermList ( termList aTermList, termList& theLastTerm, bool negate )
1058{
1059    if ( aTermList == 0 )
1060        return 0;
1061    else  if ( negate ) {
1062        termList sourceCursor = aTermList;
1063        termList dummy = new term;
1064        termList targetCursor = dummy;
1065
1066        while ( sourceCursor ) {
1067            targetCursor->next = new term( 0, -sourceCursor->coeff, sourceCursor->exp );
1068            targetCursor = targetCursor->next;
1069            sourceCursor = sourceCursor->next;
1070        }
1071        targetCursor->next = 0;
1072        theLastTerm = targetCursor;
1073        targetCursor = dummy->next;
1074        delete dummy;
1075        return targetCursor;
1076    }
1077    else {
1078        termList sourceCursor = aTermList;
1079        termList dummy = new term;
1080        termList targetCursor = dummy;
1081
1082        while ( sourceCursor ) {
1083            targetCursor->next = new term( 0, sourceCursor->coeff, sourceCursor->exp );
1084            targetCursor = targetCursor->next;
1085            sourceCursor = sourceCursor->next;
1086        }
1087        targetCursor->next = 0;
1088        theLastTerm = targetCursor;
1089        targetCursor = dummy->next;
1090        delete dummy;
1091        return targetCursor;
1092    }
1093}
1094
1095termList
1096InternalPoly::deepCopyTermList ( termList aTermList, termList& theLastTerm )
1097{
1098    if ( aTermList == 0 )
1099        return 0;
1100    else {
1101        termList sourceCursor = aTermList;
1102        termList dummy = new term;
1103        termList targetCursor = dummy;
1104
1105        while ( sourceCursor ) {
1106            targetCursor->next = new term( 0, sourceCursor->coeff.deepCopy(), sourceCursor->exp );
1107            targetCursor = targetCursor->next;
1108            sourceCursor = sourceCursor->next;
1109        }
1110        targetCursor->next = 0;
1111        theLastTerm = targetCursor;
1112        targetCursor = dummy->next;
1113        delete dummy;
1114        return targetCursor;
1115    }
1116}
1117
1118void
1119InternalPoly::freeTermList ( termList aTermList )
1120{
1121    termList cursor = aTermList;
1122
1123    while ( cursor ) {
1124        cursor = cursor->next;
1125        delete aTermList;
1126        aTermList = cursor;
1127    }
1128}
1129
1130void
1131InternalPoly::negateTermList ( termList terms )
1132{
1133    termList cursor = terms;
1134    while ( cursor ) {
1135        cursor->coeff = -cursor->coeff;
1136        cursor = cursor->next;
1137    }
1138}
1139
1140termList
1141InternalPoly::addTermList ( termList theList, termList aList, termList& lastTerm, bool negate )
1142{
1143    termList theCursor = theList;
1144    termList aCursor = aList;
1145    termList predCursor = 0;
1146
1147    while ( theCursor && aCursor ) {
1148        if ( theCursor->exp == aCursor->exp ) {
1149            if ( negate )
1150                theCursor->coeff -= aCursor->coeff;
1151            else
1152                theCursor->coeff += aCursor->coeff;
1153            if ( theCursor->coeff.isZero() ) {
1154                if ( predCursor ) {
1155                    predCursor->next = theCursor->next;
1156                    delete theCursor;
1157                    theCursor = predCursor->next;
1158                }
1159                else {
1160                    theList = theList->next;
1161                    delete theCursor;
1162                    theCursor = theList;
1163                }
1164            }
1165            else {
1166                predCursor = theCursor;
1167                theCursor = theCursor->next;
1168            }
1169            aCursor = aCursor->next;
1170        }
1171        else if ( theCursor->exp < aCursor->exp ) {
1172            if ( negate )
1173                if ( predCursor ) {
1174                    predCursor->next = new term( theCursor, -aCursor->coeff, aCursor->exp );
1175                    predCursor = predCursor->next;
1176                }
1177                else {
1178                    theList = new term( theCursor, -aCursor->coeff, aCursor->exp );
1179                    predCursor = theList;
1180                }
1181            else
1182                if ( predCursor ) {
1183                    predCursor->next = new term( theCursor, aCursor->coeff, aCursor->exp );
1184                    predCursor = predCursor->next;
1185                }
1186                else {
1187                    theList = new term( theCursor, aCursor->coeff, aCursor->exp );
1188                    predCursor = theList;
1189                }
1190            aCursor = aCursor->next;
1191        }
1192        else {
1193            predCursor = theCursor;
1194            theCursor = theCursor->next;
1195        }
1196    }
1197    if ( aCursor ) {
1198        if ( predCursor )
1199            predCursor->next = copyTermList( aCursor, lastTerm, negate );
1200        else
1201            theList = copyTermList( aCursor, lastTerm, negate );
1202    }
1203    else if ( ! theCursor )
1204        lastTerm = predCursor;
1205
1206    return theList;
1207}
1208
1209void
1210InternalPoly::mulTermList ( termList theCursor, const CanonicalForm& coeff, const int exp )
1211{
1212    while ( theCursor ) {
1213        theCursor->coeff *= coeff;
1214        theCursor->exp += exp;
1215        theCursor = theCursor->next;
1216    }
1217}
1218
1219termList
1220InternalPoly::divTermList ( termList firstTerm, const CanonicalForm& coeff, termList& lastTerm )
1221{
1222    termList theCursor = firstTerm;
1223    lastTerm = 0;
1224    termList dummy;
1225
1226    while ( theCursor ) {
1227        theCursor->coeff /= coeff;
1228        if ( theCursor->coeff.isZero() ) {
1229            if ( theCursor == firstTerm )
1230                firstTerm = theCursor->next;
1231            else
1232                lastTerm->next = theCursor->next;
1233            dummy = theCursor;
1234            theCursor = theCursor->next;
1235            delete dummy;
1236        }
1237        else {
1238            lastTerm = theCursor;
1239            theCursor = theCursor->next;
1240        }
1241    }
1242    return firstTerm;
1243}
1244
1245termList
1246InternalPoly::modTermList ( termList firstTerm, const CanonicalForm& coeff, termList& lastTerm )
1247{
1248    termList theCursor = firstTerm;
1249    lastTerm = 0;
1250    termList dummy;
1251
1252    while ( theCursor ) {
1253        theCursor->coeff.mod( coeff );
1254        if ( theCursor->coeff.isZero() ) {
1255            if ( theCursor == firstTerm )
1256                firstTerm = theCursor->next;
1257            else
1258                lastTerm->next = theCursor->next;
1259            dummy = theCursor;
1260            theCursor = theCursor-> next;
1261            delete dummy;
1262        }
1263        else {
1264            lastTerm = theCursor;
1265            theCursor = theCursor->next;
1266        }
1267    }
1268    return firstTerm;
1269}
1270
1271void
1272InternalPoly::appendTermList ( termList& first, termList& last, const CanonicalForm& coeff, const int exp )
1273{
1274    if ( last ) {
1275        last->next = new term( 0, coeff, exp );
1276        last = last->next;
1277    }
1278    else {
1279        first = new term( 0, coeff, exp );
1280        last = first;
1281    }
1282}
1283
1284termList
1285InternalPoly::mulAddTermList ( termList theList, termList aList, const CanonicalForm & c, const int exp, termList & lastTerm, bool negate )
1286{
1287    termList theCursor = theList;
1288    termList aCursor = aList;
1289    termList predCursor = 0;
1290    CanonicalForm coeff;
1291
1292    if ( negate )
1293        coeff = -c;
1294    else
1295        coeff = c;
1296
1297    while ( theCursor && aCursor ) {
1298        if ( theCursor->exp == aCursor->exp + exp ) {
1299            theCursor->coeff += aCursor->coeff * coeff;
1300            if ( theCursor->coeff.isZero() ) {
1301                if ( predCursor ) {
1302                    predCursor->next = theCursor->next;
1303                    delete theCursor;
1304                    theCursor = predCursor->next;
1305                }
1306                else {
1307                    theList = theList->next;
1308                    delete theCursor;
1309                    theCursor = theList;
1310                }
1311            }
1312            else {
1313                predCursor = theCursor;
1314                theCursor = theCursor->next;
1315            }
1316            aCursor = aCursor->next;
1317        }
1318        else if ( theCursor->exp < aCursor->exp + exp ) {
1319            if ( predCursor ) {
1320                predCursor->next = new term( theCursor, aCursor->coeff * coeff, aCursor->exp + exp );
1321                predCursor = predCursor->next;
1322            }
1323            else {
1324                theList = new term( theCursor, aCursor->coeff * coeff, aCursor->exp + exp );
1325                predCursor = theList;
1326            }
1327            aCursor = aCursor->next;
1328        }
1329        else {
1330            predCursor = theCursor;
1331            theCursor = theCursor->next;
1332        }
1333    }
1334    if ( aCursor ) {
1335        if ( predCursor ) {
1336            predCursor->next = copyTermList( aCursor, lastTerm );
1337            predCursor = predCursor->next;
1338        }
1339        else {
1340            theList = copyTermList( aCursor, lastTerm );
1341            predCursor = theList;
1342        }
1343        while ( predCursor ) {
1344            predCursor->exp += exp;
1345            predCursor->coeff *= coeff;
1346            predCursor = predCursor->next;
1347        }
1348    }
1349    else if ( ! theCursor )
1350        lastTerm = predCursor;
1351    return theList;
1352}
1353
1354termList
1355InternalPoly::reduceTermList ( termList first, termList redterms, termList & last )
1356{
1357    CanonicalForm coeff = redterms->coeff;
1358    CanonicalForm newcoeff;
1359    int newexp;
1360    int exp = redterms->exp;
1361    termList dummy;
1362    while ( first && ( first->exp >= exp ) ) {
1363        newcoeff = first->coeff / coeff;
1364        newexp = first->exp - exp;
1365        dummy = first;
1366        first = mulAddTermList( first->next, redterms->next, newcoeff, newexp, last, true );
1367        delete dummy;
1368    }
1369    return first;
1370}
Note: See TracBrowser for help on using the repository browser.