source: git/factory/canonicalform.cc @ 2206a71

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