source: git/kernel/semic.cc @ d16ea9

spielwiese
Last change on this file since d16ea9 was fdbaeb, checked in by mlee <martinlee84@…>, 13 years ago
added misc/mylimits.h to includes
  • Property mode set to 100644
File size: 11.4 KB
Line 
1// ----------------------------------------------------------------------------
2//  semic.cc
3//  begin of file
4//  Stephan Endrass, endrass@mathematik.uni-mainz.de
5//  23.7.99
6// ----------------------------------------------------------------------------
7
8#define SEMIC_CC
9
10#include"mod2.h"
11
12#ifdef HAVE_SPECTRUM
13
14#ifdef  SEMIC_PRINT
15#ifndef SEMIC_IOSTREAM
16#include<stdio.h>
17#else
18#include<iostream.h>
19#endif
20#endif
21
22#include<string.h>
23#ifndef ix86_Win
24//#include<values.h>
25#endif
26
27#include<misc/intvec.h>
28#include<misc/mylimits.h>
29#include"GMPrat.h"
30#include"semic.h"
31
32// ----------------------------------------------------------------------------
33//  Delete the memory of a spectrum
34// ----------------------------------------------------------------------------
35
36inline void spectrum::copy_delete( void )
37{
38    if( s != (Rational*)NULL && n > 0 ) delete [] s;
39    if( w != (int*)NULL      && n > 0 ) delete [] w;
40    copy_zero( );
41}
42
43// ----------------------------------------------------------------------------
44//  Allocate memory for a spectrum of  k  numbers
45// ----------------------------------------------------------------------------
46
47void spectrum::copy_new( int k )
48{
49    if( k > 0 )
50    {
51        s = new Rational[k];
52        w = new int[k];
53
54        #ifndef NDEBUG
55        if( s == (Rational*)NULL || w == (int*)NULL )
56        {
57            #ifdef SEMIC_PRINT
58            #ifdef SEMIC_IOSTREAM
59                cerr << "spectrum::copy_new(" << k << ")" << endl;
60                cerr << "    returned ZERO!!!" << endl;
61                cerr << "    exit..." << endl;
62            #else
63                fprintf( stderr,"spectrum::copy_new( %d )\n",k );
64                fprintf( stderr,"    returned ZERO!!!\n" );
65                fprintf( stderr,"    exit...\n" );
66            #endif
67            #endif
68        }
69        #endif
70    }
71    else if( k == 0 )
72    {
73        s = (Rational*)NULL;
74        w = (int*)NULL;
75    }
76    else if( k < 0 )
77    {
78        #ifdef SEMIC_PRINT
79        #ifdef SEMIC_IOSTREAM
80                cerr << "spectrum::copy_new(" << k << ")";
81                cerr << ": k < 0 ..." << endl;
82        #else
83                fprintf( stderr,"spectrum::copy_new( %d )",k );
84                fprintf( stderr,": k < 0 ...\n" );
85        #endif
86        #endif
87
88        exit( 1 );
89    }
90}
91
92// ----------------------------------------------------------------------------
93//  Copy constructor for  spectrum
94// ----------------------------------------------------------------------------
95
96spectrum::spectrum( const spectrum &spec )
97{
98    copy_deep( spec );
99}
100
101// ----------------------------------------------------------------------------
102//  Destructor for  spectrum
103// ----------------------------------------------------------------------------
104
105spectrum::~spectrum( )
106{
107    copy_delete( );
108}
109
110
111// ----------------------------------------------------------------------------
112//  operator  =  for  spectrum
113// ----------------------------------------------------------------------------
114
115spectrum spectrum::operator = ( const spectrum &spec )
116{
117    copy_delete( );
118    copy_deep( spec );
119
120    return *this;
121}
122
123// ----------------------------------------------------------------------------
124//  add the two spectra  s1  and  s2  and return their sum
125// ----------------------------------------------------------------------------
126
127spectrum  operator + ( const spectrum &s1,const spectrum &s2 )
128{
129    int i1=0, i2=0, i3=0;
130
131    spectrum result;
132
133    do
134    {
135        if( i1 >= s1.n )
136        {
137            i2++;
138        }
139        else if( i2 >= s2.n )
140        {
141            i1++;
142        }
143        else if( s1.s[i1] < s2.s[i2] )
144        {
145            i1++;
146        }
147        else if( s1.s[i1] == s2.s[i2] )
148        {
149            i1++;
150            i2++;
151        }
152        else
153        {
154            i2++;
155        }
156        i3++;
157    }
158    while( i1 < s1.n || i2 < s2.n );
159
160    result.copy_new( i3 );
161    result.n = i3;
162
163    i1 = i2 = i3 = 0;
164
165    do
166    {
167        if( i1 >= s1.n )
168        {
169            result.s[i3] = s2.s[i2];
170            result.w[i3] = s2.w[i2];
171            i2++;
172        }
173        else if( i2 >= s2.n )
174        {
175            result.s[i3] = s1.s[i1];
176            result.w[i3] = s1.w[i1];
177            i1++;
178        }
179        else if( s1.s[i1] < s2.s[i2] )
180        {
181            result.s[i3] = s1.s[i1];
182            result.w[i3] = s1.w[i1];
183            i1++;
184          }
185        else if( s1.s[i1] == s2.s[i2] )
186        {
187            result.s[i3] = s1.s[i1];
188            result.w[i3] = s1.w[i1] + s2.w[i2];
189            i1++;
190            i2++;
191        }
192        else
193        {
194            result.s[i3] = s2.s[i2];
195            result.w[i3] = s2.w[i2];
196            i2++;
197        }
198        i3++;
199    }
200    while( i1 < s1.n || i2 < s2.n );
201
202    result.mu = s1.mu + s2.mu;
203    result.pg = s1.pg + s2.pg;
204
205    return  result;
206}
207
208// ----------------------------------------------------------------------------
209//  multiply the multiplicities of the spectrum numbers of  a  with  m
210// ----------------------------------------------------------------------------
211
212spectrum operator * ( int k,const spectrum &spec )
213{
214    if( k == 0 )
215    {
216        spectrum result;
217
218        return  result;
219    }
220    else
221    {
222        spectrum result( spec );
223
224        result.mu *= k;
225        result.pg *= k;
226
227        for( int i=0; i<result.n; i++ )
228        {
229            result.w[i] *= k;
230        }
231
232        return  result;
233    }
234}
235
236// ----------------------------------------------------------------------------
237//  Print a  spectrum
238// ----------------------------------------------------------------------------
239
240#ifdef SEMIC_PRINT
241
242ostream & operator << ( ostream &s,const spectrum &spec )
243{
244    for( int i=0; i<spec.n; i++ )
245    {
246        if( i>0 )
247        {
248            #ifdef SEMIC_STDOUT
249                s << "+";
250            #else
251                fprintf( stdout,"+" );
252            #endif
253        }
254
255        #ifdef SEMIC_STDOUT
256            s << spec.w[i] << "*t^";
257        #else
258            fprintf( stdout,"%d*t^",spec.w[i] );
259        #endif
260
261        s << spec.s[i];
262    }
263
264    return s;
265}
266#endif
267
268// ----------------------------------------------------------------------------
269//  Add a subspectrum with multiplicity  k  (faster than '+')
270// ----------------------------------------------------------------------------
271
272int    spectrum::add_subspectrum( spectrum &a,int k )
273{
274    int i,j;
275    for( i=0, j=0; i<n; i++ )
276    {
277        if( s[i] == a.s[j] )
278        {
279            w[i] += k*a.w[j];
280            j++;
281        }
282    }
283
284    return ( j == a.n ? TRUE : FALSE );
285}
286
287// ----------------------------------------------------------------------------
288//  set  *alpha  to the next spectrum number strictly bigger than  *alpha
289//  returns: TRUE, if such a spectrum number exists
290//           FALSE otherwise
291// ----------------------------------------------------------------------------
292
293int    spectrum::next_number( Rational *alpha )
294{
295    int i=0;
296
297    while( i < n && *alpha >= s[i]  )
298    {
299        i++;
300    }
301
302    if( i < n )
303    {
304        *alpha = s[i];
305        return TRUE;
306    }
307    else
308    {
309        return FALSE;
310    }
311}
312
313// ----------------------------------------------------------------------------
314//  find the next interval on the real line of same length as
315//  [*alpha1,*alpha2]  having a spectrum number as interval border
316// ----------------------------------------------------------------------------
317
318int     spectrum::next_interval( Rational *alpha1,Rational *alpha2 )
319{
320    Rational zero( 0,1 );
321    Rational a1 = *alpha1;
322    Rational a2 = *alpha2;
323    Rational d  = *alpha2 - *alpha1;
324
325    int    e1 = this->next_number( &a1 );
326    int    e2 = this->next_number( &a2 );
327
328    if( e1 || e2 )
329    {
330        Rational d1 = a1 - *alpha1;
331        Rational d2 = a2 - *alpha2;
332
333        if( d1 < d2 || d2 == zero )
334        {
335            *alpha1 = a1;
336            *alpha2 = a1 + d;
337        }
338        else
339        {
340            *alpha1 = a2 - d;
341            *alpha2 = a2;
342        }
343        return  TRUE;
344    }
345    else
346    {
347        return  FALSE;
348    }
349}
350
351// ----------------------------------------------------------------------------
352//  compute the numver of spectrum numbers in the inverval  [*alpha1,*alpha2]
353// ----------------------------------------------------------------------------
354
355int     spectrum::numbers_in_interval( Rational &alpha1,
356                Rational &alpha2,interval_status status )
357{
358    int count = 0;
359
360    for( int i=0; i<n; i++ )
361    {
362        if( ( ( status == OPEN   || status == LEFTOPEN  ) &&
363              s[i] >  alpha1 ) ||
364            ( ( status == CLOSED || status == RIGHTOPEN ) &&
365              s[i] >= alpha1 ) )
366        {
367              if( ( ( status == OPEN   || status == RIGHTOPEN  ) &&
368                  s[i] <  alpha2 ) ||
369                ( ( status == CLOSED || status == LEFTOPEN ) &&
370                  s[i] <= alpha2 ) )
371            {
372                count += w[i];
373            }
374            else
375            {
376                break;
377            }
378        }
379    }
380
381    return count;
382}
383
384// ----------------------------------------------------------------------------
385//  find the maximal integer  k  such that  k*t is semicontinous
386//  for the spectrum
387// ----------------------------------------------------------------------------
388
389int     spectrum::mult_spectrum( spectrum &t )
390{
391    spectrum u = *this + t;
392
393    Rational alpha1 = -2;
394    Rational alpha2 = -1;
395
396    int      mult=INT_MAX,nthis,nt;
397
398    while( u.next_interval( &alpha1,&alpha2 ) )
399    {
400        nt    = t.numbers_in_interval( alpha1,alpha2,LEFTOPEN );
401        nthis = this->numbers_in_interval( alpha1,alpha2,LEFTOPEN );
402
403        if( nt != 0 )
404        {
405            mult = (nthis/nt < mult ? nthis/nt: mult );
406        }
407
408    }
409
410    return  mult;
411}
412
413// ----------------------------------------------------------------------------
414//  find the maximal integer  k  such that  k*t is semicontinous
415//  for the spectrum (in the homogeneous sense)
416// ----------------------------------------------------------------------------
417
418int     spectrum::mult_spectrumh( spectrum &t )
419{
420    spectrum u = *this + t;
421
422    Rational alpha1 = -2;
423    Rational alpha2 = -1;
424
425    int      mult=INT_MAX,nthis,nt;
426
427    while( u.next_interval( &alpha1,&alpha2 ) )
428    {
429        nt    = t.numbers_in_interval( alpha1,alpha2,LEFTOPEN );
430        nthis = this->numbers_in_interval( alpha1,alpha2,LEFTOPEN );
431
432        if( nt != 0 )
433        {
434            mult = (nthis/nt < mult ? nthis/nt: mult );
435        }
436
437        nt    = t.numbers_in_interval( alpha1,alpha2,OPEN );
438        nthis = this->numbers_in_interval( alpha1,alpha2,OPEN );
439
440        if( nt != 0 )
441        {
442            mult = (nthis/nt < mult ? nthis/nt: mult );
443        }
444    }
445
446    return  mult;
447}
448
449// ----------------------------------------------------------------------------
450//  Set the Milnor number
451// ----------------------------------------------------------------------------
452
453/*
454int spectrum::set_milnor( void )
455{
456   mu = 0;
457
458   for( int i=0; i<n; i++ )
459   {
460      mu += w[i];
461   }
462
463   return  mu;
464}
465
466// ----------------------------------------------------------------------------
467//  Set the geometrical genus
468// ----------------------------------------------------------------------------
469
470int spectrum::set_geometric_genus( void )
471{
472   pg = 0;
473
474   for( int i=0; i<n && s[i]<=1; i++ )
475   {
476      pg += w[i];
477   }
478   return  pg;
479}
480*/
481
482#endif /* HAVE_SPECTRUM */
483// ----------------------------------------------------------------------------
484//  semic.cc
485//  end of file
486// ----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.