source: git/factory/variable.cc @ ff3a4f

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