source: git/factory/canonicalform.cc @ d6a968a

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