source: git/factory/variable.cc @ 17a710

spielwiese
Last change on this file since 17a710 was 183688, checked in by Martin Lee <martinlee84@…>, 12 years ago
chg: if variable has level LEVELBASE it has no minpoly
  • Property mode set to 100644
File size: 7.1 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2
3#include "config.h"
4
5#include <string.h>
6
7#include "cf_assert.h"
8
9#include "cf_defs.h"
10#include "variable.h"
11#include "canonicalform.h"
12#include "cf_factory.h"
13#include "int_poly.h"
14#include "cf_iter.h"
15
16class ext_entry
17{
18private:
19    InternalPoly * _mipo;
20    bool _reduce;
21public:
22    ext_entry () : _mipo(0), _reduce(false) {}
23    ext_entry ( InternalPoly * mipoly, bool reduce ) : _mipo(mipoly), _reduce(reduce) {};
24    ext_entry ( const ext_entry & e ) : _mipo(e._mipo), _reduce(e._reduce) {}
25    ~ext_entry () {};
26    ext_entry & operator= ( const ext_entry & e )
27    {
28        if ( this != &e ) {
29            _mipo = e._mipo;
30            _reduce = e._reduce;
31        }
32        return *this;
33    }
34    InternalPoly * mipo () { return _mipo; }
35    void setmipo( InternalPoly * p ) { _mipo = p; }
36    bool & reduce () { return _reduce; }
37};
38
39static ext_entry * algextensions = 0;
40static char * var_names = 0;
41static char * var_names_ext = 0;
42static char default_name = 'v';
43static char default_name_ext = 'a';
44
45Variable::Variable( int l, bool flag ) : _level(l)
46{
47    ASSERT( flag, "illegal level" );
48}
49
50Variable::Variable( int l ) : _level(l)
51{
52    ASSERT( l > 0 && l != LEVELQUOT, "illegal level" );
53}
54
55Variable::Variable( char name )
56{
57    bool isext = false;
58    int n, i;
59    if ( var_names_ext != 0 ) {
60        n = strlen( var_names_ext );
61        i = 1;
62        while ( i < n && var_names_ext[i] != name ) i++;
63        if ( i < n ) {
64            _level = -i;
65            isext = true;
66        }
67    }
68    if ( ! isext ) {
69        if ( var_names == 0 ) {
70            var_names = new char [3];
71            var_names[0] = '@';
72            var_names[1] = name;
73            var_names[2] = '\0';
74            _level = 1;
75        }
76        else {
77            n = strlen( var_names );
78            i = 1;
79            while ( i < n && var_names[i] != name ) i++;
80            if ( i < n )
81                _level = i;
82            else {
83                ASSERT( name != '@', "illegal variable name" );
84                char * newvarnames = new char [n+2];
85                for ( i = 0; i < n; i++ )
86                    newvarnames[i] = var_names[i];
87                newvarnames[n] = name;
88                newvarnames[n+1] = 0;
89                delete [] var_names;
90                var_names = newvarnames;
91                _level = n;
92            }
93        }
94    }
95}
96
97Variable::Variable( int l, char name ) : _level(l)
98{
99    ASSERT( l > 0 && l != LEVELQUOT, "illegal level" );
100    int n;
101    if ( (n = (var_names == 0 ? 0 : strlen( var_names ))) <= l ) {
102        char * newvarnames = new char [l+2];
103        int i;
104        for ( i = 0; i < n; i++ )
105            newvarnames[i] = var_names[i];
106        for ( i = n; i < l; i++ )
107            newvarnames[i] = '@';
108        newvarnames[l] = name;
109        newvarnames[l+1] = 0;
110        delete [] var_names;
111        var_names = newvarnames;
112    }
113    else {
114        ASSERT( var_names[l] == '@', "illegal name" );
115        var_names[l] = name;
116    }
117}
118
119char
120Variable::name() const
121{
122    if ( _level > 0 && _level < (int)strlen( var_names ) )
123        return( var_names[_level] );
124    else if ( _level < 0 && -_level < (int)strlen( var_names_ext ) )
125        return( var_names_ext[-_level] );
126    else
127        return '@';
128}
129
130#ifndef NOSTREAMIO
131OSTREAM & operator << ( OSTREAM & os, const Variable & v )
132{
133    if ( v._level == LEVELBASE )
134        os << "1";
135    else {
136        char * vn = ( v._level > 0 ) ? var_names : var_names_ext;
137        char dn = ( v._level > 0 ) ? default_name : default_name_ext;
138        int l = v._level;
139
140        if ( l < 0 ) l = -l;
141        if ( (vn == 0) || ((int)strlen( vn ) <= l) )
142            os << dn << "_" << l;
143        else  if ( vn[l] == '@' )
144            os << dn << "_" << l;
145        else
146            os << vn[l];
147    }
148    return os;
149}
150#endif /* NOSTREAMIO */
151
152static CanonicalForm conv2mipo ( const CanonicalForm & mipo, const Variable alpha )
153{
154    CanonicalForm result;
155    for ( CFIterator i = mipo; i.hasTerms(); i++ )
156        result += i.coeff() * power( alpha, i.exp() );
157    return result;
158}
159
160Variable rootOf( const CanonicalForm & mipo, char name )
161{
162    ASSERT (mipo.isUnivariate(), "not a legal extension");
163
164    int l;
165    if ( var_names_ext == 0 ) {
166        var_names_ext = new char [3];
167        var_names_ext[0] = '@';
168        var_names_ext[1] = name;
169        var_names_ext[2] = '\0';
170        l = 1;
171        Variable result( -l, true );
172        algextensions = new ext_entry [2];
173        algextensions[1] = ext_entry( 0, false );
174        algextensions[1] = ext_entry( (InternalPoly*)(conv2mipo( mipo, result ).getval()), true );
175        return result;
176    }
177    else {
178        int i, n = strlen( var_names_ext );
179        char * newvarnames = new char [n+2];
180        for ( i = 0; i < n; i++ )
181            newvarnames[i] = var_names_ext[i];
182        newvarnames[n] = name;
183        newvarnames[n+1] = 0;
184        delete [] var_names_ext;
185        var_names_ext = newvarnames;
186        l = n;
187        Variable result( -l, true );
188        ext_entry * newalgext = new ext_entry [n+1];
189        for ( i = 0; i < n; i++ )
190            newalgext[i] = algextensions[i];
191        newalgext[n] = ext_entry( 0, false );
192        delete [] algextensions;
193        algextensions = newalgext;
194        algextensions[n] = ext_entry( (InternalPoly*)(conv2mipo( mipo, result ).getval()), true );
195        return result;
196    }
197}
198
199InternalPoly * getInternalMipo ( const Variable & alpha )
200{
201    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
202    return algextensions[-alpha.level()].mipo();
203}
204
205CanonicalForm getMipo( const Variable & alpha, const Variable & x )
206{
207    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
208    return CanonicalForm( algextensions[-alpha.level()].mipo()->copyObject() )(x,alpha);
209}
210
211CanonicalForm getMipo( const Variable & alpha )
212{
213    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
214    return CanonicalForm( algextensions[-alpha.level()].mipo()->copyObject() );
215}
216
217void setMipo ( const Variable & alpha, const CanonicalForm & mipo)
218{
219    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
220    algextensions[-alpha.level()]= ext_entry((InternalPoly*)(conv2mipo( mipo, alpha ).getval()), true );
221}
222
223bool hasMipo( const Variable & alpha )
224{
225    ASSERT( alpha.level() < 0, "illegal extension" );
226    return (alpha.level() != LEVELBASE && (algextensions!=NULL) && getReduce(alpha) );
227}
228
229bool getReduce( const Variable & alpha )
230{
231    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
232    return algextensions[-alpha.level()].reduce();
233}
234
235void setReduce( const Variable & alpha, bool reduce )
236{
237    ASSERT( alpha.level() < 0 && alpha.level() != LEVELBASE, "illegal extension" );
238    algextensions[-alpha.level()].reduce() = reduce;
239}
240
241char getDefaultVarName()
242{
243    return default_name;
244}
245
246char getDefaultExtName()
247{
248    return default_name_ext;
249}
250
251int ExtensionLevel()
252{
253  if( var_names_ext == 0)
254    return 0;
255  return strlen( var_names_ext )-1;
256}
257
258void Reduce( bool on)
259{
260  int i;
261  for (i=ExtensionLevel(); i>0;i--)
262  {
263    Variable l(-i);
264    setReduce(l,on);
265  }
266}
Note: See TracBrowser for help on using the repository browser.