source: git/kernel/semic.cc @ abe5c8

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