source: git/factory/cf_map.cc @ 281760

fieker-DuValspielwiese
Last change on this file since 281760 was 1f28ed, checked in by Jens Schmidt <schmidt@…>, 27 years ago
* cf_map.cc: doc fix (subsrec): doc fix (CFMap): doc fix (operator <<): doc fix (newpair): doc fix (operator =): doc fix (operator ()): doc fix (compress): doc fix * cf_map.cc (CFMap( CFList )): 'P.append()' replaced by 'P.insert()' * cf_map.cc (CFList, CFListIterator, MPListIterator): references to List<CanonicalForm>, ListIterator<CanonicalForm>, and ListIterator<MapPair> replaced by their respective typedefs * cf_map.cc (cmpfunc): doc fix (insfunc): doc fix git-svn-id: file:///usr/local/Singular/svn/trunk@573 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 8.2 KB
Line 
1/* emacs edit mode for this file is -*- C++ -*- */
2/* $Id: cf_map.cc,v 1.7 1997-07-23 16:22:34 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    if ( m.P.isEmpty() )
208        s << "( )";
209    else {
210        MPListIterator i = m.P;
211        s << "( " << i.getItem();
212        i++;
213        while ( i.hasItem() ) {
214            s << ", " << i.getItem();
215            i++;
216        }
217        s << " )";
218    }
219    return s;
220}
221//}}}
222#endif /* NOSTREAMIO */
223
224//{{{ CanonicalForm compress ( const CanonicalForm & f, CFMap & m )
225//{{{ docu
226//
227// compress() - compress the canonical form f.
228//
229// Compress the polynomial f such that the levels of its
230// polynomial variables are ordered without any gaps starting
231// from level 1.  Return the compressed polynomial and a map m to
232// undo the compression.  That is, if f' = compress(f, m), than f
233// = m(f').
234//
235//}}}
236CanonicalForm
237compress ( const CanonicalForm & f, CFMap & m )
238{
239    CanonicalForm result = f;
240    int i, n;
241    int * degs = degrees( f );
242
243    m = CFMap();
244    n = i = 1;
245    while ( i <= level( f ) ) {
246        while( degs[i] == 0 ) i++;
247        if ( i != n ) {
248            // swap variables and remember the swap in the map
249            m.newpair( Variable( n ), Variable( i ) );
250            result = swapvar( result, Variable( i ), Variable( n ) );
251        }
252        n++; i++;
253    }
254    delete [] degs;
255    return result;
256}
257//}}}
258
259//{{{ void compress ( const CFArray & a, CFMap & M, CFMap & N )
260//{{{ docu
261//
262// compress() - compress the variables occuring in an a.
263//
264// Compress the polynomial variables occuring in a so that their
265// levels are ordered without any gaps starting from level 1.
266// Return the CFMap M to realize the compression and its inverse,
267// the CFMap N.  Note that if you compress a member of a using M
268// the result of the compression is not necessarily compressed,
269// since the map is constructed using all variables occuring in
270// a.
271//
272//}}}
273void
274compress ( const CFArray & a, CFMap & M, CFMap & N )
275{
276    M = N = CFMap();
277    if ( a.size() == 0 )
278        return;
279    int maxlevel = level( a[a.min()] );
280    int i, j;
281
282    // get the maximum of levels in a
283    for ( i = a.min() + 1; i <= a.max(); i++ )
284        if ( level( a[i] ) > maxlevel )
285            maxlevel = level( a[i] );
286    if ( maxlevel <= 0 )
287        return;
288
289    int * degs = new int[maxlevel+1];
290    int * tmp = new int[maxlevel+1];
291    for ( i = 1; i <= maxlevel; i++ )
292        degs[i] = 0;
293
294    // calculate the union of all levels occuring in a
295    for ( i = a.min(); i <= a.max(); i++ ) {
296        tmp = degrees( a[i], tmp );
297        for ( j = 1; j <= level( a[i] ); j++ )
298            if ( tmp[j] != 0 )
299                degs[j] = 1;
300    }
301
302    // create the maps
303    i = 1; j = 1;
304    while ( i <= maxlevel ) {
305        if ( degs[i] != 0 ) {
306            M.newpair( Variable(i), Variable(j) );
307            N.newpair( Variable(j), Variable(i) );
308            j++;
309        }
310        i++;
311    }
312    delete [] tmp;
313    delete [] degs;
314}
315//}}}
316
317//{{{ void compress ( const CanonicalForm & f, const CanonicalForm & g, CFMap & M, CFMap & N )
318//{{{ docu
319//
320// compress() - compress the variables occurring in f and g.
321//
322// Compress the polynomial variables occurring in f and g so that
323// the levels of variables common to f and g are ordered without
324// any gaps starting from level 1, whereas the variables occuring
325// in only one of f or g are moved to levels higher than the
326// levels of the common variables.  Return the CFMap M to realize
327// the compression and its inverse, the CFMap N.
328//
329//}}}
330void
331compress ( const CanonicalForm & f, const CanonicalForm & g, CFMap & M, CFMap & N )
332{
333    int n = tmax( f.level(), g.level() );
334    int i, k, m;
335    int * degsf = new int[n+1];
336    int * degsg = new int[n+1];
337
338    for ( i = 0; i <= n; i++ ) {
339        degsf[i] = degsg[i] = 0;
340    }
341
342    degsf = degrees( f, degsf );
343    degsg = degrees( g, degsg );
344    i = 1; k = 1; m = n;
345    while ( i <= n ) {
346        if ( degsf[i] > 0 && degsg[i] > 0 ) {
347            // store common variables at the beginning
348            if ( i != k ) {
349                M.newpair( Variable(i), Variable(k) );
350                N.newpair( Variable(k), Variable(i) );
351            }
352            k++;
353        }
354        else {
355            // all others at the end
356            M.newpair( Variable(i), Variable(m) );
357            N.newpair( Variable(m), Variable(i) );
358            m--;
359        }
360        i++;
361    }
362
363    delete [] degsf;
364    delete [] degsg;
365}
366//}}}
Note: See TracBrowser for help on using the repository browser.