source: git/factory/variable.cc @ 767da0

spielwiese
Last change on this file since 767da0 was a3f0fea, checked in by Reimer Behrends <behrends@…>, 5 years ago
Modify variable declarions for pSingular.
  • Property mode set to 100644
File size: 8.5 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_VAR ext_entry * algextensions = 0;
42STATIC_VAR char * var_names = 0;
43STATIC_VAR char * var_names_ext = 0;
44STATIC_VAR char default_name = 'v';
45STATIC_VAR 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  if (alpha.level()==LEVELBASE) return;
264  int last_var=-alpha.level();
265  if ((last_var <= 0)||(var_names_ext==NULL)) return;
266  int i, n = strlen( var_names_ext );
267  ASSERT (n+1 >= last_var, "wrong variable");
268  if (last_var == 1)
269  {
270    delete [] var_names_ext;
271    delete [] algextensions;
272    var_names_ext= 0;
273    algextensions= 0;
274    alpha= Variable();
275    return;
276  }
277  char * newvarnames = new char [last_var+1];
278  for ( i = 0; i < last_var; i++ )
279    newvarnames[i] = var_names_ext[i];
280  newvarnames[last_var] = 0;
281  delete [] var_names_ext;
282  var_names_ext = newvarnames;
283  ext_entry * newalgext = new ext_entry [last_var];
284  for ( i = 0; i < last_var; i++ )
285    newalgext[i] = algextensions[i];
286  delete [] algextensions;
287  algextensions = newalgext;
288  alpha= Variable();
289}
290
291void prune1 (const Variable& alpha)
292{
293  int i, n = strlen( var_names_ext );
294  ASSERT (n+1 >= -alpha.level(), "wrong variable");
295
296  char * newvarnames = new char [-alpha.level() + 2];
297  for ( i = 0; i <= -alpha.level(); i++ )
298    newvarnames[i] = var_names_ext[i];
299  newvarnames[-alpha.level()+1] = 0;
300  delete [] var_names_ext;
301  var_names_ext = newvarnames;
302  ext_entry * newalgext = new ext_entry [-alpha.level()+1];
303  for ( i = 0; i <= -alpha.level(); i++ )
304    newalgext[i] = algextensions[i];
305  delete [] algextensions;
306  algextensions = newalgext;
307}
308
309void Reduce( bool on)
310{
311  int i;
312  for (i=ExtensionLevel(); i>0;i--)
313  {
314    Variable l(-i);
315    setReduce(l,on);
316  }
317}
Note: See TracBrowser for help on using the repository browser.