source: git/factory/variable.cc @ 37f64cb

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