source: git/factory/canonicalform.cc @ 1343d6

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