source: git/factory/cf_map.cc @ 72dd6e

spielwiese
Last change on this file since 72dd6e was d88948, checked in by Jens Schmidt <schmidt@…>, 27 years ago
* cf_map.cc (operator << ( ostream& s, const CFMap & m )): rewritten git-svn-id: file:///usr/local/Singular/svn/trunk@595 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 8.0 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: cf_map.cc,v 1.8 1997-08-01 11:45:54 schmidt Exp $ */
3
4//{{{ docu
5//
6// cf_map.cc - definition of class CFMap.
7//
8// Used by: cf_gcd.cc, fac_multivar.cc, sm_sparsemod.cc
9//
10//}}}
11
12#include <config.h>
13
14#include "canonicalform.h"
15#include "cf_map.h"
16#include "cf_iter.h"
17#ifdef macintosh
18#include <::templates:ftmpl_functions.h>
19#else
20#include "templates/ftmpl_functions.h"
21#endif
22
23//{{{ static int cmpfunc ( const MapPair & p1, const MapPair & p2 )
24//{{{ docu
25//
26// cmpfunc() - compare two map pairs.
27//
28// Return -1 if p2's variable is less than p1's, 0 if they are
29// equal, 1 if p2's level is greater than p1's.
30//
31//}}}
32static int
33cmpfunc ( const MapPair & p1, const MapPair & p2 )
34{
35    if ( p1.var() > p2.var() ) return -1;
36    else if ( p1.var() == p2.var() ) return 0;
37    else return 1;
38}
39//}}}
40
41//{{{ static void insfunc ( MapPair & orgp, const MapPair & newp )
42//{{{ docu
43//
44// insfunc() - assign newp to orgp.
45//
46// cmpfunc() and insfunc() are used as functions for inserting a
47// map pair into a Map.
48//
49//}}}
50static void
51insfunc ( MapPair & orgp, const MapPair & newp )
52{
53    orgp = newp;
54}
55//}}}
56
57//{{{ static CanonicalForm subsrec( const CanonicalForm & f, const MPListIterator & i )
58//{{{ docu
59//
60// subsrec() - recursively apply the substitutions in i to f.
61//
62// Substitutes algebraic variables, too.  The substituted
63// expression are not subject to further substitutions.
64//
65//}}}
66static CanonicalForm
67subsrec( const CanonicalForm & f, const MPListIterator & i )
68{
69    if ( f.inBaseDomain() ) return f;
70    MPListIterator j = i;
71
72    // skip MapPairs larger than the main variable of f
73    while ( j.hasItem() && j.getItem().var() > f.mvar() ) j++;
74
75    if ( j.hasItem() )
76        if ( j.getItem().var() != f.mvar() ) {
77            // simply descend if the current MapPair variable is
78            // not the main variable of f
79            CanonicalForm result = 0;
80            CFIterator I;
81            for ( I = f; I.hasTerms(); I++ )
82                result += power( f.mvar(), I.exp() ) * subsrec( I.coeff(), j );
83            return result;
84        }
85        else {
86            // replace the main variable of f with the image of
87            // the current variable under MapPair
88            CanonicalForm result = 0;
89            CanonicalForm s = j.getItem().subst();
90            CFIterator I;
91            // move on to the next MapPair
92            j++;
93            for ( I = f; I.hasTerms(); I++ )
94                result += subsrec( I.coeff(), j ) * power( s, I.exp() );
95            return result;
96        }
97    else
98        return f;
99}
100//}}}
101
102//{{{ MapPair& MapPair::operator = ( const MapPair & p )
103//{{{ docu
104//
105// MapPair::operator = - assignment operator.
106//
107//}}}
108MapPair&
109MapPair::operator = ( const MapPair & p )
110{
111    if ( this != &p ) {
112        V = p.V;
113        S = p.S;
114    }
115    return *this;
116}
117//}}}
118
119#ifndef NOSTREAMIO
120//{{{ ostream& operator << ( ostream& s, const MapPair & p )
121//{{{ docu
122//
123// operator << - print a map pair ("V -> S").
124//
125//}}}
126ostream&
127operator << ( ostream& s, const MapPair & p )
128{
129    s << p.var() << " -> " << p.subst();
130    return s;
131}
132//}}}
133#endif /* NOSTREAMIO */
134
135//{{{ CFMap::CFMap ( const CFList & L )
136//{{{ docu
137//
138// CFMap::CFMap() - construct a CFMap from a CFList.
139//
140// Variable[i] will be mapped to CFList[i] under the resulting
141// map.
142//
143//}}}
144CFMap::CFMap ( const CFList & L )
145{
146    CFListIterator i;
147    int j;
148    for ( i = L, j = 1; i.hasItem(); i++, j++ )
149        P.insert( MapPair( Variable(j), i.getItem() ) );
150}
151//}}}
152
153//{{{ CFMap& CFMap::operator = ( const CFMap & m )
154//{{{ docu
155//
156// CFMap::operator = - assignment operator.
157//
158//}}}
159CFMap&
160CFMap::operator = ( const CFMap & m )
161{
162    if ( this != &m )
163        P = m.P;
164    return *this;
165}
166//}}}
167
168//{{{ void CFMap::newpair( const Variable & v, const CanonicalForm & s )
169//{{{ docu
170//
171// CFMap::newpair() - inserts a MapPair into a CFMap.
172//
173//}}}
174void
175CFMap::newpair( const Variable & v, const CanonicalForm & s )
176{
177    P.insert( MapPair( v, s ), cmpfunc, insfunc );
178}
179//}}}
180
181//{{{ CanonicalForm CFMap::operator () ( const CanonicalForm & f ) const
182//{{{ docu
183//
184// CFMap::operator () - apply the map to f.
185//
186// See subsrec() for more detailed information.
187//
188//}}}
189CanonicalForm
190CFMap::operator () ( const CanonicalForm & f ) const
191{
192    MPListIterator i = P;
193    return subsrec( f, i );
194}
195//}}}
196
197#ifndef NOSTREAMIO
198//{{{ ostream& operator << ( ostream& s, const CFMap & m )
199//{{{ docu
200//
201// operator << - print a CFMap ("( V[1] -> S[1], ..., V[n] -> // S[n] )".
202//
203//}}}
204ostream&
205operator << ( ostream& s, const CFMap & m )
206{
207    return s << m.P;
208}
209//}}}
210#endif /* NOSTREAMIO */
211
212//{{{ CanonicalForm compress ( const CanonicalForm & f, CFMap & m )
213//{{{ docu
214//
215// compress() - compress the canonical form f.
216//
217// Compress the polynomial f such that the levels of its
218// polynomial variables are ordered without any gaps starting
219// from level 1.  Return the compressed polynomial and a map m to
220// undo the compression.  That is, if f' = compress(f, m), than f
221// = m(f').
222//
223//}}}
224CanonicalForm
225compress ( const CanonicalForm & f, CFMap & m )
226{
227    CanonicalForm result = f;
228    int i, n;
229    int * degs = degrees( f );
230
231    m = CFMap();
232    n = i = 1;
233    while ( i <= level( f ) ) {
234        while( degs[i] == 0 ) i++;
235        if ( i != n ) {
236            // swap variables and remember the swap in the map
237            m.newpair( Variable( n ), Variable( i ) );
238            result = swapvar( result, Variable( i ), Variable( n ) );
239        }
240        n++; i++;
241    }
242    delete [] degs;
243    return result;
244}
245//}}}
246
247//{{{ void compress ( const CFArray & a, CFMap & M, CFMap & N )
248//{{{ docu
249//
250// compress() - compress the variables occuring in an a.
251//
252// Compress the polynomial variables occuring in a so that their
253// levels are ordered without any gaps starting from level 1.
254// Return the CFMap M to realize the compression and its inverse,
255// the CFMap N.  Note that if you compress a member of a using M
256// the result of the compression is not necessarily compressed,
257// since the map is constructed using all variables occuring in
258// a.
259//
260//}}}
261void
262compress ( const CFArray & a, CFMap & M, CFMap & N )
263{
264    M = N = CFMap();
265    if ( a.size() == 0 )
266        return;
267    int maxlevel = level( a[a.min()] );
268    int i, j;
269
270    // get the maximum of levels in a
271    for ( i = a.min() + 1; i <= a.max(); i++ )
272        if ( level( a[i] ) > maxlevel )
273            maxlevel = level( a[i] );
274    if ( maxlevel <= 0 )
275        return;
276
277    int * degs = new int[maxlevel+1];
278    int * tmp = new int[maxlevel+1];
279    for ( i = 1; i <= maxlevel; i++ )
280        degs[i] = 0;
281
282    // calculate the union of all levels occuring in a
283    for ( i = a.min(); i <= a.max(); i++ ) {
284        tmp = degrees( a[i], tmp );
285        for ( j = 1; j <= level( a[i] ); j++ )
286            if ( tmp[j] != 0 )
287                degs[j] = 1;
288    }
289
290    // create the maps
291    i = 1; j = 1;
292    while ( i <= maxlevel ) {
293        if ( degs[i] != 0 ) {
294            M.newpair( Variable(i), Variable(j) );
295            N.newpair( Variable(j), Variable(i) );
296            j++;
297        }
298        i++;
299    }
300    delete [] tmp;
301    delete [] degs;
302}
303//}}}
304
305//{{{ void compress ( const CanonicalForm & f, const CanonicalForm & g, CFMap & M, CFMap & N )
306//{{{ docu
307//
308// compress() - compress the variables occurring in f and g.
309//
310// Compress the polynomial variables occurring in f and g so that
311// the levels of variables common to f and g are ordered without
312// any gaps starting from level 1, whereas the variables occuring
313// in only one of f or g are moved to levels higher than the
314// levels of the common variables.  Return the CFMap M to realize
315// the compression and its inverse, the CFMap N.
316//
317//}}}
318void
319compress ( const CanonicalForm & f, const CanonicalForm & g, CFMap & M, CFMap & N )
320{
321    int n = tmax( f.level(), g.level() );
322    int i, k, m;
323    int * degsf = new int[n+1];
324    int * degsg = new int[n+1];
325
326    for ( i = 0; i <= n; i++ ) {
327        degsf[i] = degsg[i] = 0;
328    }
329
330    degsf = degrees( f, degsf );
331    degsg = degrees( g, degsg );
332    i = 1; k = 1; m = n;
333    while ( i <= n ) {
334        if ( degsf[i] > 0 && degsg[i] > 0 ) {
335            // store common variables at the beginning
336            if ( i != k ) {
337                M.newpair( Variable(i), Variable(k) );
338                N.newpair( Variable(k), Variable(i) );
339            }
340            k++;
341        }
342        else {
343            // all others at the end
344            M.newpair( Variable(i), Variable(m) );
345            N.newpair( Variable(m), Variable(i) );
346            m--;
347        }
348        i++;
349    }
350
351    delete [] degsf;
352    delete [] degsg;
353}
354//}}}
Note: See TracBrowser for help on using the repository browser.