source: git/factory/canonicalform.cc @ dd08e72

spielwiese
Last change on this file since dd08e72 was dd08e72, checked in by Jens Schmidt <schmidt@…>, 27 years ago
* canonicalform.cc (sqrt): sqrt(0) works now (sqrt): assertion added (sqrt): 'int h' changed to 'long long h'. Casts added. git-svn-id: file:///usr/local/Singular/svn/trunk@584 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 31.2 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: canonicalform.cc,v 1.12 1997-07-30 15:06:33 schmidt Exp $ */
3
4#include <config.h>
5
6#include "assert.h"
7
8#include "cf_defs.h"
9#include "cf_globals.h"
10#include "canonicalform.h"
11#include "cf_iter.h"
12#include "int_cf.h"
13#include "cf_factory.h"
14#include "imm.h"
15#include "gfops.h"
16#include "cf_binom.h"
17#if defined (USE_MEMUTIL) && ! defined (USE_OLD_MEMMAN)
18#include "memman.h"
19#endif
20
21#ifndef NOSTREAMIO
22CanonicalForm readCF( istream& );
23#endif /* NOSTREAMIO */
24
25CanonicalForm::CanonicalForm() : value( CFFactory::basic( (int)0 ) )
26{
27}
28
29CanonicalForm::CanonicalForm( const int i ) : value( CFFactory::basic( i ) )
30{
31}
32
33CanonicalForm::CanonicalForm( const CanonicalForm & cf ) : value( is_imm( cf.value ) ? cf.value : cf.value->copyObject() )
34{
35}
36
37CanonicalForm::CanonicalForm( InternalCF * cf ) : value( cf )
38{
39}
40
41CanonicalForm::CanonicalForm( const Variable & v ) : value( CFFactory::poly( v ) )
42{
43}
44
45CanonicalForm::CanonicalForm( const Variable & v, int e ) : value( CFFactory::poly( v, e ) )
46{
47}
48
49CanonicalForm::CanonicalForm( const char * str ) : value( CFFactory::basic( str ) )
50{
51}
52
53CanonicalForm::~CanonicalForm()
54{
55    if ( (! is_imm( value )) && value->deleteObject() )
56        delete value;
57}
58
59InternalCF*
60CanonicalForm::getval() const
61{
62    if ( is_imm( value ) )
63        return value;
64    else
65        return value->copyObject();
66}
67
68bool
69CanonicalForm::isOne() const
70{
71    if ( is_imm( value ) == FFMARK )
72        return imm_isone_p( value );
73    else  if ( is_imm( value ) == GFMARK )
74        return imm_isone_gf( value );
75    else  if ( is_imm( value ) )
76        return imm_isone( value );
77    else
78        return value->isOne();
79}
80
81bool
82CanonicalForm::isZero() const
83{
84    if ( is_imm( value ) == FFMARK )
85        return imm_iszero_p( value );
86    else  if ( is_imm( value ) == GFMARK )
87        return imm_iszero_gf( value );
88    else  if ( is_imm( value ) )
89        return imm_iszero( value );
90    else
91        return value->isZero();
92}
93
94bool
95CanonicalForm::isImm() const
96{
97    return is_imm( value );
98}
99
100bool
101CanonicalForm::inZ() const
102{
103    if ( is_imm( value ) == INTMARK )
104        return true;
105    else if ( is_imm( value ) )
106        return false;
107    else
108        return value->levelcoeff() == IntegerDomain;
109}
110
111bool
112CanonicalForm::inQ() const
113{
114    if ( is_imm( value ) == INTMARK )
115        return true;
116    else if ( is_imm( value ) )
117        return false;
118    else
119        return value->levelcoeff() == IntegerDomain ||
120            value->levelcoeff() == RationalDomain;
121}
122
123bool
124CanonicalForm::inFF() const
125{
126    return is_imm( value ) == FFMARK;
127}
128
129bool
130CanonicalForm::inGF() const
131{
132    return is_imm( value ) == GFMARK;
133}
134
135bool
136CanonicalForm::inPP() const
137{
138    return ! is_imm( value ) && ( value->levelcoeff() == PrimePowerDomain );
139}
140
141bool
142CanonicalForm::inBaseDomain() const
143{
144    if ( is_imm( value ) )
145        return true;
146    else
147        return value->inBaseDomain();
148}
149
150bool
151CanonicalForm::inExtension() const
152{
153    if ( is_imm( value ) )
154        return false;
155    else
156        return value->inExtension();
157}
158
159bool
160CanonicalForm::inCoeffDomain() const
161{
162    if ( is_imm( value ) )
163        return true;
164    else
165        return value->inCoeffDomain();
166}
167
168bool
169CanonicalForm::inPolyDomain() const
170{
171    if ( is_imm( value ) )
172        return false;
173    else
174        return value->inPolyDomain();
175}
176
177bool
178CanonicalForm::inQuotDomain() const
179{
180    if ( is_imm( value ) )
181        return false;
182    else
183        return value->inQuotDomain();
184}
185
186int
187CanonicalForm::intval() const
188{
189    if ( is_imm( value ) )
190        return imm_intval( value );
191    else
192        return value->intval();
193}
194
195CanonicalForm
196CanonicalForm::lc() const
197{
198    if ( is_imm( value ) )
199        return *this;
200    else
201        return value->lc();
202}
203
204CanonicalForm
205CanonicalForm::LC() const
206{
207    if ( inBaseDomain() )
208        return *this;
209    else
210        return value->LC();
211}
212
213CanonicalForm
214CanonicalForm::LC( const Variable & v ) const
215{
216    if ( inBaseDomain() )
217        return *this;
218    else  if ( v == mvar() )
219        return value->LC();
220    else {
221        CanonicalForm f = swapvar( *this, v, mvar() );
222        if ( f.mvar() == mvar() )
223            return swapvar( f.value->LC(), v, mvar() );
224        else
225            return *this;
226    }
227}
228
229//{{{ int CanonicalForm::degree() const
230//{{{ docu
231//
232// degree() - return degree in main variable.
233//
234// Returns -1 for the zero polynomial.
235//
236//}}}
237int
238CanonicalForm::degree() const
239{
240    if ( isZero() )
241        return -1;
242    else  if ( is_imm( value ) )
243        return 0;
244    else
245        return value->degree();
246}
247//}}}
248
249//{{{ int CanonicalForm::degree( const Variable & v ) const
250//{{{ docu
251//
252// degree() - return degree in variable v.
253//
254// Returns -1 for the zero polynomial.
255//
256// Note: If v is less than the main variable of CO we have to swap
257// variables which may be quite expensive.  Calculating the degree in
258// respect to an algebraic variable may fail.
259//
260//}}}
261int
262CanonicalForm::degree( const Variable & v ) const
263{
264    if ( isZero() )
265        return -1;
266    else  if ( is_imm( value ) )
267        return 0;
268    else  if ( inBaseDomain() )
269        return 0;
270    else  if ( v == mvar() )
271        return value->degree();
272    else  if ( v > mvar() )
273        // relatively to v, f is in a coefficient ring
274        return 0;
275    else {
276        // v < mvar(), make v main variable
277        CanonicalForm f = swapvar( *this, v, mvar() );
278        if ( f.mvar() == mvar() )
279            return f.value->degree();
280        else
281            // in this case, we lost our main variable because
282            // v did not occur in CO
283            return 0;
284    }
285}
286//}}}
287
288int
289CanonicalForm::taildegree() const
290{
291    if ( isZero() )
292        return -1;
293    else  if ( is_imm( value ) )
294        return 0;
295    else
296        return value->taildegree();
297}
298
299CanonicalForm
300CanonicalForm::tailcoeff() const
301{
302    if ( inCoeffDomain() )
303        return *this;
304    else
305        return value->tailcoeff();
306}
307
308int
309CanonicalForm::level() const
310{
311    if ( is_imm( value ) )
312        return LEVELBASE;
313    else
314        return value->level();
315}
316
317Variable
318CanonicalForm::mvar() const
319{
320    if ( is_imm( value ) || value->inBaseDomain() )
321        return Variable();
322    else
323        return value->variable();
324}
325
326CanonicalForm
327CanonicalForm::num() const
328{
329    if ( is_imm( value ) )
330        return *this;
331    else
332        return CanonicalForm( value->num() );
333}
334
335CanonicalForm
336CanonicalForm::den() const
337{
338    if ( is_imm( value ) )
339        return 1;
340    else
341        return CanonicalForm( value->den() );
342}
343
344CanonicalForm
345CanonicalForm::deepCopy() const
346{
347    if ( is_imm( value ) )
348        return *this;
349    else
350        return CanonicalForm( value->deepCopyObject() );
351}
352
353CanonicalForm
354CanonicalForm::gcd( const CanonicalForm & ) const
355{
356//    return ::gcd( *this, f );
357    return 1;
358}
359
360CanonicalForm
361CanonicalForm::deriv() const
362{
363    if ( inCoeffDomain() )
364        return 0;
365    else {
366        CanonicalForm res = 0;
367        Variable x = mvar();
368        for ( CFIterator i = *this; i.hasTerms(); i++ )
369            if ( i.exp() > 0 )
370                res += power( x, i.exp()-1 ) * i.coeff() * i.exp();
371        return res;
372    }
373}
374
375CanonicalForm
376CanonicalForm::deriv( const Variable & x ) const
377{
378    if ( inCoeffDomain() )
379        return 0;
380    else {
381        CanonicalForm res = 0;
382        Variable y = mvar();
383        for ( CFIterator i = (y==x) ? *this : swapvar( *this, x, y ); i.hasTerms(); i++ )
384            if ( i.exp() > 0 )
385                res += power( y, i.exp()-1 ) * i.coeff() * i.exp();
386        return (y==x) ? res : swapvar( res, x, y );
387    }
388}
389
390CanonicalForm
391CanonicalForm::genCoeff( int type, int i )
392{
393    return CanonicalForm( CFFactory::basic( type, i ) );
394}
395
396CanonicalForm
397CanonicalForm::genZero() const
398{
399    int what = is_imm( value );
400    if ( what == FFMARK )
401        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 0 ) );
402    else  if ( what == GFMARK )
403        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 0 ) );
404    else  if ( what )
405        return CanonicalForm( CFFactory::basic( IntegerDomain, 0 ) );
406    else
407        return CanonicalForm( value->genZero() );
408}
409
410CanonicalForm
411CanonicalForm::genOne() const
412{
413    int what = is_imm( value );
414    if ( what == FFMARK )
415        return CanonicalForm( CFFactory::basic( FiniteFieldDomain, 1 ) );
416    else  if ( what == GFMARK )
417        return CanonicalForm( CFFactory::basic( GaloisFieldDomain, 1 ) );
418    else  if ( what )
419        return CanonicalForm( CFFactory::basic( IntegerDomain, 1 ) );
420    else
421        return CanonicalForm( value->genOne() );
422}
423
424bool
425CanonicalForm::isUnivariate() const
426{
427    if ( is_imm( value ) )
428        return false;
429    else
430        return value->isUnivariate();
431}
432
433#ifndef NOSTREAMIO
434void
435CanonicalForm::print( ostream & os, char * str ) const
436{
437    if ( is_imm( value ) )
438        imm_print( os, value, str );
439    else
440        value->print( os, str );
441}
442#endif /* NOSTREAMIO */
443
444bool
445operator == ( const CanonicalForm & lhs, const CanonicalForm & rhs )
446{
447    int what = is_imm( lhs.value );
448    if ( what )
449        if ( what == is_imm( rhs.value ) )
450            return lhs.value == rhs.value;
451        else
452            return false;
453    else  if ( is_imm( rhs.value ) )
454        return false;
455    else  if ( lhs.level() == rhs.level() )
456        if ( lhs.value->levelcoeff() >= rhs.value->levelcoeff() )
457            return lhs.value->comparesame( rhs.value ) == 0;
458        else
459            return rhs.value->comparesame( lhs.value ) == 0;
460    else
461        return false;
462}
463
464bool
465operator != ( const CanonicalForm & lhs, const CanonicalForm & rhs )
466{
467    int what = is_imm( lhs.value );
468    if ( what )
469        if ( what == is_imm( rhs.value ) )
470            return lhs.value != rhs.value;
471        else
472            return true;
473    else  if ( is_imm( rhs.value ) )
474        return true;
475    else  if ( lhs.level() == rhs.level() )
476        if ( lhs.value->levelcoeff() >= rhs.value->levelcoeff() )
477            return lhs.value->comparesame( rhs.value ) != 0;
478        else
479            return rhs.value->comparesame( lhs.value ) != 0;
480    else
481        return true;
482}
483
484bool
485operator > ( const CanonicalForm & lhs, const CanonicalForm & rhs )
486{
487    int what = is_imm( lhs.value );
488    if ( what ) {
489        ASSERT ( ! is_imm( rhs.value ) || (what==is_imm( rhs.value )), "illegal base coefficients" );
490        if ( what == INTMARK ) {
491            if ( what == is_imm( rhs.value ) )
492                return imm_cmp( lhs.value, rhs.value ) > 0;
493            else
494                return rhs.value->comparecoeff( lhs.value ) < 0;
495        }
496        else  if ( what == FFMARK ) {
497            if ( what == is_imm( rhs.value ) )
498                return imm_cmp_p( lhs.value, rhs.value ) > 0;
499            else
500                return rhs.value->comparecoeff( lhs.value ) < 0;
501        }
502        else {
503            if ( what == is_imm( rhs.value ) )
504                return imm_cmp_gf( lhs.value, rhs.value ) > 0;
505            else
506                return rhs.value->comparecoeff( lhs.value ) < 0;
507        }
508    }
509    else  if ( is_imm( rhs.value ) )
510        return lhs.value->comparecoeff( rhs.value ) > 0;
511    else  if ( lhs.level() == rhs.level() )
512        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
513            return lhs.value->comparesame( rhs.value ) > 0;
514        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
515            return lhs.value->comparecoeff( lhs.value ) > 0;
516        else
517            return rhs.value->comparecoeff( lhs.value ) < 0;
518    else
519        return lhs.value->level() > rhs.value->level();
520}
521
522bool
523operator < ( const CanonicalForm & lhs, const CanonicalForm & rhs )
524{
525    int what = is_imm( lhs.value );
526    if ( what ) {
527        ASSERT ( ! is_imm( rhs.value ) || (what==is_imm( rhs.value )), "illegal base coefficients" );
528        if ( what == INTMARK ) {
529            if ( what == is_imm( rhs.value ) )
530                return imm_cmp( lhs.value, rhs.value ) < 0;
531            else
532                return rhs.value->comparecoeff( lhs.value ) > 0;
533        }
534        else  if ( what == FFMARK ) {
535            if ( what == is_imm( rhs.value ) )
536                return imm_cmp( lhs.value, rhs.value ) < 0;
537            else
538                return rhs.value->comparecoeff( lhs.value ) > 0;
539        }
540        else {
541            if ( what == is_imm( rhs.value ) )
542                return imm_cmp( lhs.value, rhs.value ) < 0;
543            else
544                return rhs.value->comparecoeff( lhs.value ) > 0;
545        }
546    }
547    else  if ( is_imm( rhs.value ) )
548        return lhs.value->comparecoeff( rhs.value ) < 0;
549    else  if ( lhs.level() == rhs.level() )
550        if ( lhs.value->levelcoeff() == rhs.value->levelcoeff() )
551            return lhs.value->comparesame( rhs.value ) < 0;
552        else  if ( lhs.value->levelcoeff() > rhs.value->levelcoeff() )
553            return lhs.value->comparecoeff( lhs.value ) < 0;
554        else
555            return rhs.value->comparecoeff( lhs.value ) > 0;
556    else
557        return lhs.value->level() < rhs.value->level();
558}
559
560CanonicalForm&
561CanonicalForm::operator = ( const CanonicalForm & cf )
562{
563    if ( this != &cf ) {
564        if ( (! is_imm( value )) && value->deleteObject() )
565            delete value;
566        value = (is_imm( cf.value )) ? cf.value : cf.value->copyObject();
567    }
568    return *this;
569}
570
571CanonicalForm&
572CanonicalForm::operator = ( const int cf )
573{
574    if ( (! is_imm( value )) && value->deleteObject() )
575        delete value;
576    value = CFFactory::basic( cf );
577    return *this;
578}
579
580CanonicalForm&
581CanonicalForm::operator += ( const CanonicalForm & cf )
582{
583    int what = is_imm( value );
584    if ( what ) {
585        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
586        if ( (what = is_imm( cf.value )) == FFMARK )
587            value = imm_add_p( value, cf.value );
588        else  if ( what == GFMARK )
589            value = imm_add_gf( value, cf.value );
590        else  if ( what )
591            value = imm_add( value, cf.value );
592        else {
593            InternalCF * dummy = cf.value->copyObject();
594            value = dummy->addcoeff( value );
595        }
596    }
597    else  if ( is_imm( cf.value ) )
598        value = value->addcoeff( cf.value );
599    else  if ( value->level() == cf.value->level() ) {
600        if ( value->levelcoeff() == cf.value->levelcoeff() )
601            value = value->addsame( cf.value );
602        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
603            value = value->addcoeff( cf.value );
604        else {
605            InternalCF * dummy = cf.value->copyObject();
606            dummy = dummy->addcoeff( value );
607            if ( value->deleteObject() ) delete value;
608            value = dummy;
609        }
610    }
611    else  if ( level() > cf.level() )
612        value = value->addcoeff( cf.value );
613    else {
614        InternalCF * dummy = cf.value->copyObject();
615        dummy = dummy->addcoeff( value );
616        if ( value->deleteObject() ) delete value;
617        value = dummy;
618    }
619    return *this;
620}
621
622CanonicalForm&
623CanonicalForm::operator -= ( const CanonicalForm & cf )
624{
625    int what = is_imm( value );
626    if ( what ) {
627        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
628        if ( (what = is_imm( cf.value )) == FFMARK )
629            value = imm_sub_p( value, cf.value );
630        else  if ( what == GFMARK )
631            value = imm_sub_gf( value, cf.value );
632        else  if ( what )
633            value = imm_sub( value, cf.value );
634        else {
635            InternalCF * dummy = cf.value->copyObject();
636            value = dummy->subcoeff( value, true );
637        }
638    }
639    else  if ( is_imm( cf.value ) )
640        value = value->subcoeff( cf.value, false );
641    else  if ( value->level() == cf.value->level() ) {
642        if ( value->levelcoeff() == cf.value->levelcoeff() )
643            value = value->subsame( cf.value );
644        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
645            value = value->subcoeff( cf.value, false );
646        else {
647            InternalCF * dummy = cf.value->copyObject();
648            dummy = dummy->subcoeff( value, true );
649            if ( value->deleteObject() ) delete value;
650            value = dummy;
651        }
652    }
653    else  if ( level() > cf.level() )
654        value = value->subcoeff( cf.value, false );
655    else {
656        InternalCF * dummy = cf.value->copyObject();
657        dummy = dummy->subcoeff( value, true );
658        if ( value->deleteObject() ) delete value;
659        value = dummy;
660    }
661    return *this;
662}
663
664CanonicalForm&
665CanonicalForm::operator *= ( const CanonicalForm & cf )
666{
667    int what = is_imm( value );
668    if ( what ) {
669        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
670        if ( (what = is_imm( cf.value )) == FFMARK )
671            value = imm_mul_p( value, cf.value );
672        else  if ( what == GFMARK )
673            value = imm_mul_gf( value, cf.value );
674        else  if ( what )
675            value = imm_mul( value, cf.value );
676        else {
677            InternalCF * dummy = cf.value->copyObject();
678            value = dummy->mulcoeff( value );
679        }
680    }
681    else  if ( is_imm( cf.value ) )
682        value = value->mulcoeff( cf.value );
683    else  if ( value->level() == cf.value->level() ) {
684        if ( value->levelcoeff() == cf.value->levelcoeff() )
685            value = value->mulsame( cf.value );
686        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
687            value = value->mulcoeff( cf.value );
688        else {
689            InternalCF * dummy = cf.value->copyObject();
690            dummy = dummy->mulcoeff( value );
691            if ( value->deleteObject() ) delete value;
692            value = dummy;
693        }
694    }
695    else  if ( level() > cf.level() )
696        value = value->mulcoeff( cf.value );
697    else {
698        InternalCF * dummy = cf.value->copyObject();
699        dummy = dummy->mulcoeff( value );
700        if ( value->deleteObject() ) delete value;
701        value = dummy;
702    }
703    return *this;
704}
705
706CanonicalForm&
707CanonicalForm::operator /= ( const CanonicalForm & cf )
708{
709    int what = is_imm( value );
710    if ( what ) {
711        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
712        if ( (what = is_imm( cf.value )) == FFMARK )
713            value = imm_div_p( value, cf.value );
714        else  if ( what == GFMARK )
715            value = imm_div_gf( value, cf.value );
716        else  if ( what )
717            value = imm_divrat( value, cf.value );
718        else {
719            InternalCF * dummy = cf.value->copyObject();
720            value = dummy->dividecoeff( value, true );
721        }
722    }
723    else  if ( is_imm( cf.value ) )
724        value = value->dividecoeff( cf.value, false );
725    else  if ( value->level() == cf.value->level() ) {
726        if ( value->levelcoeff() == cf.value->levelcoeff() )
727            value = value->dividesame( cf.value );
728        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
729            value = value->dividecoeff( cf.value, false );
730        else {
731            InternalCF * dummy = cf.value->copyObject();
732            dummy = dummy->dividecoeff( value, true );
733            if ( value->deleteObject() ) delete value;
734            value = dummy;
735        }
736    }
737    else  if ( level() > cf.level() )
738        value = value->dividecoeff( cf.value, false );
739    else {
740        InternalCF * dummy = cf.value->copyObject();
741        dummy = dummy->dividecoeff( value, true );
742        if ( value->deleteObject() ) delete value;
743        value = dummy;
744    }
745    return *this;
746}
747
748CanonicalForm&
749CanonicalForm::div ( const CanonicalForm & cf )
750{
751    int what = is_imm( value );
752    if ( what ) {
753        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
754        if ( (what = is_imm( cf.value )) == FFMARK )
755            value = imm_div_p( value, cf.value );
756        else  if ( what == GFMARK )
757            value = imm_div_gf( value, cf.value );
758        else  if ( what )
759            value = imm_div( value, cf.value );
760        else {
761            InternalCF * dummy = cf.value->copyObject();
762            value = dummy->divcoeff( value, true );
763        }
764    }
765    else  if ( is_imm( cf.value ) )
766        value = value->divcoeff( cf.value, false );
767    else  if ( value->level() == cf.value->level() ) {
768        if ( value->levelcoeff() == cf.value->levelcoeff() )
769            value = value->divsame( cf.value );
770        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
771            value = value->divcoeff( cf.value, false );
772        else {
773            InternalCF * dummy = cf.value->copyObject();
774            dummy = dummy->divcoeff( value, true );
775            if ( value->deleteObject() ) delete value;
776            value = dummy;
777        }
778    }
779    else  if ( level() > cf.level() )
780        value = value->divcoeff( cf.value, false );
781    else {
782        InternalCF * dummy = cf.value->copyObject();
783        dummy = dummy->divcoeff( value, true );
784        if ( value->deleteObject() ) delete value;
785        value = dummy;
786    }
787    return *this;
788}
789
790CanonicalForm&
791CanonicalForm::operator %= ( const CanonicalForm& cf )
792{
793    int what = is_imm( value );
794    if ( what ) {
795        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
796        if ( (what = is_imm( cf.value )) == FFMARK )
797            value = imm_mod_p( value, cf.value );
798        else  if ( what == GFMARK )
799            value = imm_mod_gf( value, cf.value );
800        else  if ( what )
801            value = imm_mod( value, cf.value );
802        else {
803            InternalCF * dummy = cf.value->copyObject();
804            value = dummy->modulocoeff( value, true );
805        }
806    }
807    else  if ( is_imm( cf.value ) )
808        value = value->modulocoeff( cf.value, false );
809    else  if ( value->level() == cf.value->level() ) {
810        if ( value->levelcoeff() == cf.value->levelcoeff() )
811            value = value->modulosame( cf.value );
812        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
813            value = value->modulocoeff( cf.value, false );
814        else {
815            InternalCF * dummy = cf.value->copyObject();
816            dummy = dummy->modulocoeff( value, true );
817            if ( value->deleteObject() ) delete value;
818            value = dummy;
819        }
820    }
821    else  if ( level() > cf.level() )
822        value = value->modulocoeff( cf.value, false );
823    else {
824        InternalCF * dummy = cf.value->copyObject();
825        dummy = dummy->modulocoeff( value, true );
826        if ( value->deleteObject() ) delete value;
827        value = dummy;
828    }
829    return *this;
830}
831
832CanonicalForm&
833CanonicalForm::mod( const CanonicalForm & cf )
834{
835    int what = is_imm( value );
836    if ( what ) {
837        ASSERT ( ! is_imm( cf.value ) || (what==is_imm( cf.value )), "illegal base coefficients" );
838        if ( (what = is_imm( cf.value )) == FFMARK )
839            value = imm_mod_p( value, cf.value );
840        else  if ( what == GFMARK )
841            value = imm_mod_gf( value, cf.value );
842        else  if ( what )
843            value = imm_mod( value, cf.value );
844        else {
845            InternalCF * dummy = cf.value->copyObject();
846            value = dummy->modcoeff( value, true );
847        }
848    }
849    else  if ( is_imm( cf.value ) )
850        value = value->modcoeff( cf.value, false );
851    else  if ( value->level() == cf.value->level() ) {
852        if ( value->levelcoeff() == cf.value->levelcoeff() )
853            value = value->modsame( cf.value );
854        else  if ( value->levelcoeff() > cf.value->levelcoeff() )
855            value = value->modcoeff( cf.value, false );
856        else {
857            InternalCF * dummy = cf.value->copyObject();
858            dummy = dummy->modcoeff( value, true );
859            if ( value->deleteObject() ) delete value;
860            value = dummy;
861        }
862    }
863    else  if ( level() > cf.level() )
864        value = value->modcoeff( cf.value, false );
865    else {
866        InternalCF * dummy = cf.value->copyObject();
867        dummy = dummy->modcoeff( value, true );
868        if ( value->deleteObject() ) delete value;
869        value = dummy;
870    }
871    return *this;
872}
873
874CanonicalForm
875operator - ( const CanonicalForm & cf )
876{
877    CanonicalForm result( cf );
878    int what = is_imm( result.value );
879    if ( what == FFMARK )
880        result.value = imm_neg_p( result.value );
881    else  if ( what == GFMARK )
882        result.value = imm_neg_gf( result.value );
883    else  if ( what )
884        result.value = imm_neg( result.value );
885    else
886        result.value = result.value->neg();
887    return result;
888}
889
890CanonicalForm
891operator + ( const CanonicalForm &c1, const CanonicalForm &c2 )
892{
893    CanonicalForm result( c1 );
894    result += c2;
895    return result;
896}
897
898CanonicalForm
899operator - ( const CanonicalForm &c1, const CanonicalForm &c2 )
900{
901    CanonicalForm result( c1 );
902    result -= c2;
903    return result;
904}
905
906CanonicalForm
907operator * ( const CanonicalForm &c1, const CanonicalForm &c2 )
908{
909    CanonicalForm result( c1 );
910    result *= c2;
911    return result;
912}
913
914CanonicalForm
915operator / ( const CanonicalForm &c1, const CanonicalForm &c2 )
916{
917    CanonicalForm result( c1 );
918    result /= c2;
919    return result;
920}
921
922CanonicalForm
923div ( const CanonicalForm &c1, const CanonicalForm &c2 )
924{
925    CanonicalForm result( c1 );
926    result.div( c2 );
927    return result;
928}
929
930CanonicalForm
931mod ( const CanonicalForm &c1, const CanonicalForm &c2 )
932{
933    CanonicalForm result( c1 );
934    result.mod( c2 );
935    return result;
936}
937
938CanonicalForm
939operator % ( const CanonicalForm &c1, const CanonicalForm &c2 )
940{
941    CanonicalForm result( c1 );
942    result %= c2;
943    return result;
944}
945
946void
947divrem ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
948{
949    InternalCF * qq = 0, * rr = 0;
950    int what = is_imm( f.value );
951    if ( what )
952        if ( is_imm( g.value ) ) {
953            if ( what == FFMARK )
954                imm_divrem_p( f.value, g.value, qq, rr );
955            else  if ( what == GFMARK )
956                imm_divrem_gf( f.value, g.value, qq, rr );
957            else
958                imm_divrem( f.value, g.value, qq, rr );
959        }
960        else
961            g.value->divremcoeff( f.value, qq, rr, true );
962    else  if ( (what=is_imm( g.value )) )
963        f.value->divremcoeff( g.value, qq, rr, false );
964    else  if ( f.value->level() == g.value->level() )
965        if ( f.value->levelcoeff() == g.value->levelcoeff() )
966            f.value->divremsame( g.value, qq, rr );
967        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
968            f.value->divremcoeff( g.value, qq, rr, false );
969        else
970            g.value->divremcoeff( f.value, qq, rr, true );
971    else  if ( f.value->level() > g.value->level() )
972        f.value->divremcoeff( g.value, qq, rr, false );
973    else
974        g.value->divremcoeff( f.value, qq, rr, true );
975    ASSERT( qq != 0 && rr != 0, "error in divrem" );
976    q = CanonicalForm( qq );
977    r = CanonicalForm( rr );
978}
979
980bool
981divremt ( const CanonicalForm & f, const CanonicalForm & g, CanonicalForm & q, CanonicalForm & r )
982{
983    InternalCF * qq = 0, * rr = 0;
984    int what = is_imm( f.value );
985    bool result = true;
986    if ( what )
987        if ( is_imm( g.value ) ) {
988            if ( what == FFMARK )
989                imm_divrem_p( f.value, g.value, qq, rr );
990            else  if ( what == GFMARK )
991                imm_divrem_gf( f.value, g.value, qq, rr );
992            else
993                imm_divrem( f.value, g.value, qq, rr );
994        }
995        else
996            result = g.value->divremcoefft( f.value, qq, rr, true );
997    else  if ( (what=is_imm( g.value )) )
998        result = f.value->divremcoefft( g.value, qq, rr, false );
999    else  if ( f.value->level() == g.value->level() )
1000        if ( f.value->levelcoeff() == g.value->levelcoeff() )
1001            result = f.value->divremsamet( g.value, qq, rr );
1002        else  if ( f.value->levelcoeff() > g.value->levelcoeff() )
1003            result = f.value->divremcoefft( g.value, qq, rr, false );
1004        else
1005            result = g.value->divremcoefft( f.value, qq, rr, true );
1006    else  if ( f.value->level() > g.value->level() )
1007        result = f.value->divremcoefft( g.value, qq, rr, false );
1008    else
1009        result = g.value->divremcoefft( f.value, qq, rr, true );
1010    if ( result ) {
1011        ASSERT( qq != 0 && rr != 0, "error in divrem" );
1012        q = CanonicalForm( qq );
1013        r = CanonicalForm( rr );
1014    }
1015    else {
1016        q = 0; r = 0;
1017    }
1018    return result;
1019}
1020
1021#ifndef NOSTREAMIO
1022ostream&
1023operator << ( ostream & os, const CanonicalForm & cf )
1024{
1025    cf.print( os, "" );
1026    return os;
1027}
1028#endif /* NOSTREAMIO */
1029
1030#ifndef NOSTREAMIO
1031istream&
1032operator >> ( istream & is, CanonicalForm & cf )
1033{
1034#ifndef SINGULAR
1035    cf = readCF( is );
1036    return is;
1037#else /* SINGULAR */
1038    return 0;
1039#endif /* SINGULAR */
1040}
1041#endif /* NOSTREAMIO */
1042
1043CanonicalForm
1044CanonicalForm::operator () ( const CanonicalForm & f ) const
1045{
1046    if ( inBaseDomain() )
1047        return *this;
1048    else {
1049        CanonicalForm result = 0;
1050        for ( CFIterator i = *this; i.hasTerms(); i++ )
1051            if ( i.exp() == 0 )
1052                result += i.coeff();
1053            else
1054                result += power( f, i.exp() ) * i.coeff();
1055        return result;
1056    }
1057}
1058
1059CanonicalForm
1060CanonicalForm::operator () ( const CanonicalForm & f, const Variable & v ) const
1061{
1062    if ( inBaseDomain() || v > mvar() )
1063        return *this;
1064    else  if ( v == mvar() ) {
1065        CanonicalForm result = 0;
1066        for ( CFIterator i = *this; i.hasTerms(); i++ )
1067            if ( i.exp() == 0 )
1068                result += i.coeff();
1069            else
1070                result += power( f, i.exp() ) * i.coeff();
1071        return result;
1072    }
1073    else {
1074        CanonicalForm G = swapvar( *this, v, Variable::highest() );
1075        if ( G.mvar() != Variable::highest() )
1076            return *this;
1077        CanonicalForm result = 0;
1078        for ( CFIterator i = G; i.hasTerms(); ++i )
1079            if ( i.exp() == 0 )
1080                result += i.coeff();
1081            else
1082                result += power( f, i.exp() ) * i.coeff();
1083        return result;
1084    }
1085}
1086
1087CanonicalForm
1088CanonicalForm::operator[] ( int i ) const
1089{
1090    return value->coeff( i );
1091}
1092
1093int
1094CanonicalForm::sign() const
1095{
1096    if ( is_imm( value ) )
1097        return imm_sign( value );
1098    else
1099        return value->sign();
1100}
1101
1102CanonicalForm
1103power ( const CanonicalForm & f, int n )
1104{
1105    ASSERT( n >= 0, "illegal exponent" );
1106    if ( f == 0 )
1107        return 0;
1108    else  if ( f == 1 )
1109        return f;
1110    else  if ( f == -1 ) {
1111        if ( n % 2 == 0 )
1112            return 1;
1113        else
1114            return -1;
1115    }
1116    else  if ( n == 0 )
1117        return 1;
1118    else {
1119        CanonicalForm result = f;
1120        for ( int i = 1; i < n; i++ )
1121            result *= f;
1122        return result;
1123    }
1124}
1125
1126CanonicalForm
1127power ( const Variable & v, int n )
1128{
1129    ASSERT( n >= 0, "illegal exponent" );
1130    if ( n == 0 )
1131        return 1;
1132    else  if ( n == 1 )
1133        return v;
1134    else  if ( v.level() < 0 ) {
1135        CanonicalForm result( v, n-1 );
1136        return result * v;
1137    }
1138    else
1139        return CanonicalForm( v, n );
1140}
1141
1142
1143int initializeGMP();
1144int initializeCharacteristic();
1145#ifdef SINGULAR
1146int mmInit(void);
1147#endif
1148
1149int
1150initCanonicalForm( void )
1151{
1152    static bool initialized = false;
1153    if ( ! initialized ) {
1154#if (defined (USE_MEMUTIL) && ! defined (USE_OLD_MEMMAN)) || defined (SINGULAR)
1155        (void)mmInit();
1156#endif
1157
1158        (void)initializeCharacteristic();
1159        (void)initializeGMP();
1160        initPT();
1161        initialized = true;
1162    }
1163    return 1;
1164}
1165
1166
1167CanonicalForm
1168CanonicalForm::mapinto () const
1169{
1170    ASSERT( is_imm( value ) ||  ! value->inExtension(), "cannot map into different Extension" );
1171    if ( is_imm( value ) )
1172        if ( getCharacteristic() == 0 )
1173            if ( is_imm( value ) == FFMARK )
1174                return CanonicalForm( int2imm( ff_symmetric( imm2int( value ) ) ) );
1175            else  if ( is_imm( value ) == GFMARK )
1176                return CanonicalForm( int2imm( ff_symmetric( gf_gf2ff( imm2int( value ) ) ) ) );
1177            else
1178                return *this;
1179        else  if ( CFFactory::gettype() == PrimePowerDomain )
1180            return CanonicalForm( CFFactory::basic( imm2int( value ) ) );
1181        else  if ( getGFDegree() == 1 )
1182            return CanonicalForm( int2imm_p( ff_norm( imm2int( value ) ) ) );
1183        else
1184            return CanonicalForm( int2imm_gf( gf_int2gf( imm2int( value ) ) ) );
1185    else  if ( value->inBaseDomain() )
1186        if ( getCharacteristic() == 0 )
1187            if ( value->levelcoeff() == PrimePowerDomain )
1188                return CFFactory::basic( getmpi( value, true ) );
1189            else
1190                return *this;
1191        else  if ( CFFactory::gettype() == PrimePowerDomain ) {
1192            ASSERT( value->levelcoeff() == PrimePowerDomain || value->levelcoeff() == IntegerDomain, "no proper map defined" );
1193            if ( value->levelcoeff() == PrimePowerDomain )
1194                return *this;
1195            else
1196                return CFFactory::basic( getmpi( value ) );
1197        }
1198        else {
1199            int val;
1200            if ( value->levelcoeff() == IntegerDomain )
1201                val = value->intmod( ff_prime );
1202            else  if ( value->levelcoeff() == RationalDomain )
1203                return num().mapinto() / den().mapinto();
1204            else {
1205                ASSERT( 0, "illegal domain" );
1206                return 0;
1207            }
1208            if ( getGFDegree() > 1 )
1209                return CanonicalForm( int2imm_gf( gf_int2gf( val ) ) );
1210            else
1211                return CanonicalForm( int2imm_p( val ) );
1212        }
1213    else {
1214        Variable x = value->variable();
1215        CanonicalForm result;
1216        for ( CFIterator i = *this; i.hasTerms(); i++ )
1217            result += power( x, i.exp() ) * i.coeff().mapinto();
1218        return result;
1219    }
1220}
1221
1222void
1223On( int sw )
1224{
1225    cf_glob_switches.On( sw );
1226}
1227
1228void
1229Off( int sw )
1230{
1231    cf_glob_switches.Off( sw );
1232}
1233
1234bool
1235isOn( int sw )
1236{
1237    return cf_glob_switches.isOn( sw );
1238}
1239
1240bool
1241CanonicalForm::isFFinGF() const
1242{
1243    return is_imm( value ) == GFMARK && gf_isff( imm2int( value ) );
1244}
1245
1246CanonicalForm
1247CanonicalForm::sqrt ( ) const
1248{
1249    if ( is_imm( value ) ) {
1250        ASSERT( is_imm( value ) == INTMARK, "not implemented" );
1251        int a = imm2int( value );
1252        ASSERT( a >= 0, "arg to sqrt less than zero" );
1253        if ( a == 0 || a == 1 )
1254            return CanonicalForm( CFFactory::basic( a ) );
1255        else {
1256            int x0, x1 = a;
1257            long long int h;
1258            do {
1259                x0 = x1;
1260                h = (long long int)x0 * x0 + a - 1;
1261                if ( h % (2 * x0) == 0 )
1262                    x1 = h / (2 * x0);
1263                else
1264                    x1 = (h - 1)  / (2 * x0);
1265            } while ( x1 < x0 );
1266            return CanonicalForm( CFFactory::basic( x1 ) );
1267        }
1268    }
1269    else
1270        return CanonicalForm( value->sqrt() );
1271}
1272
1273//{{{ int CanonicalForm::ilog2( ) const
1274//{{{ docu
1275//
1276// ilog2() - integer logarithm to base 2.
1277//
1278// Returns the largest integer smaller than logarithm of CO to
1279// base 2.  CO should be an integer.
1280//
1281//}}}
1282int
1283CanonicalForm::ilog2( ) const
1284{
1285    if ( is_imm( value ) ) {
1286        ASSERT( is_imm( value ) == INTMARK, "not implemented" );
1287        int a = imm2int( value );
1288        ASSERT( a > 0, "log arg <= 0" );
1289        int n = -1;
1290        while ( a != 0 ) {
1291            n++;
1292            a /= 2;
1293        }
1294        return n;
1295    }
1296    else
1297        return value->ilog2();
1298}
1299//}}}
1300
1301bool
1302divides ( const CanonicalForm & f, const CanonicalForm & g )
1303{
1304    if ( g.level() > 0 && g.level() == f.level() )
1305        if ( divides( f.tailcoeff(), g.tailcoeff() ) && divides( f.LC(), g.LC() ) ) {
1306            CanonicalForm q, r;
1307            bool ok = divremt( g, f, q, r );
1308            return ok && r == 0;
1309        }
1310        else
1311            return false;
1312    else {
1313        CanonicalForm q, r;
1314        bool ok = divremt( g, f, q, r );
1315        return ok && r == 0;
1316    }
1317}
Note: See TracBrowser for help on using the repository browser.