source: git/kernel/semic.cc @ 47a4c2

spielwiese
Last change on this file since 47a4c2 was 47a4c2, checked in by Martin Lee <martinlee84@…>, 13 years ago
moved semicState,spectrumState and spectrumPrintError to ipshell.cc adapted member functions involving lists from semic and splist in ipshell.cc moved function declarations from spectrum.h involving leftv to ipshell.h
  • Property mode set to 100644
File size: 11.8 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//  Initialize a  spectrum  deep from another  spectrum
94// ----------------------------------------------------------------------------
95
96void spectrum::copy_deep( const spectrum &spec )
97{
98    mu = spec.mu;
99    pg = spec.pg;
100    n  = spec.n;
101
102    copy_new( n );
103
104    for( int i=0; i<n; i++ )
105    {
106        s[i] = spec.s[i];
107        w[i] = spec.w[i];
108    }
109}
110
111// ----------------------------------------------------------------------------
112//  Copy constructor for  spectrum
113// ----------------------------------------------------------------------------
114
115spectrum::spectrum( const spectrum &spec )
116{
117    copy_deep( spec );
118}
119
120// ----------------------------------------------------------------------------
121//  Destructor for  spectrum
122// ----------------------------------------------------------------------------
123
124spectrum::~spectrum( )
125{
126    copy_delete( );
127}
128
129
130// ----------------------------------------------------------------------------
131//  operator  =  for  spectrum
132// ----------------------------------------------------------------------------
133
134spectrum spectrum::operator = ( const spectrum &spec )
135{
136    copy_delete( );
137    copy_deep( spec );
138
139    return *this;
140}
141
142// ----------------------------------------------------------------------------
143//  add the two spectra  s1  and  s2  and return their sum
144// ----------------------------------------------------------------------------
145
146spectrum  operator + ( const spectrum &s1,const spectrum &s2 )
147{
148    int i1=0, i2=0, i3=0;
149
150    spectrum result;
151
152    do
153    {
154        if( i1 >= s1.n )
155        {
156            i2++;
157        }
158        else if( i2 >= s2.n )
159        {
160            i1++;
161        }
162        else if( s1.s[i1] < s2.s[i2] )
163        {
164            i1++;
165        }
166        else if( s1.s[i1] == s2.s[i2] )
167        {
168            i1++;
169            i2++;
170        }
171        else
172        {
173            i2++;
174        }
175        i3++;
176    }
177    while( i1 < s1.n || i2 < s2.n );
178
179    result.copy_new( i3 );
180    result.n = i3;
181
182    i1 = i2 = i3 = 0;
183
184    do
185    {
186        if( i1 >= s1.n )
187        {
188            result.s[i3] = s2.s[i2];
189            result.w[i3] = s2.w[i2];
190            i2++;
191        }
192        else if( i2 >= s2.n )
193        {
194            result.s[i3] = s1.s[i1];
195            result.w[i3] = s1.w[i1];
196            i1++;
197        }
198        else if( s1.s[i1] < s2.s[i2] )
199        {
200            result.s[i3] = s1.s[i1];
201            result.w[i3] = s1.w[i1];
202            i1++;
203          }
204        else if( s1.s[i1] == s2.s[i2] )
205        {
206            result.s[i3] = s1.s[i1];
207            result.w[i3] = s1.w[i1] + s2.w[i2];
208            i1++;
209            i2++;
210        }
211        else
212        {
213            result.s[i3] = s2.s[i2];
214            result.w[i3] = s2.w[i2];
215            i2++;
216        }
217        i3++;
218    }
219    while( i1 < s1.n || i2 < s2.n );
220
221    result.mu = s1.mu + s2.mu;
222    result.pg = s1.pg + s2.pg;
223
224    return  result;
225}
226
227// ----------------------------------------------------------------------------
228//  multiply the multiplicities of the spectrum numbers of  a  with  m
229// ----------------------------------------------------------------------------
230
231spectrum operator * ( int k,const spectrum &spec )
232{
233    if( k == 0 )
234    {
235        spectrum result;
236
237        return  result;
238    }
239    else
240    {
241        spectrum result( spec );
242
243        result.mu *= k;
244        result.pg *= k;
245
246        for( int i=0; i<result.n; i++ )
247        {
248            result.w[i] *= k;
249        }
250
251        return  result;
252    }
253}
254
255// ----------------------------------------------------------------------------
256//  Print a  spectrum
257// ----------------------------------------------------------------------------
258
259#ifdef SEMIC_PRINT
260
261ostream & operator << ( ostream &s,const spectrum &spec )
262{
263    for( int i=0; i<spec.n; i++ )
264    {
265        if( i>0 )
266        {
267            #ifdef SEMIC_STDOUT
268                s << "+";
269            #else
270                fprintf( stdout,"+" );
271            #endif
272        }
273
274        #ifdef SEMIC_STDOUT
275            s << spec.w[i] << "*t^";
276        #else
277            fprintf( stdout,"%d*t^",spec.w[i] );
278        #endif
279
280        s << spec.s[i];
281    }
282
283    return s;
284}
285#endif
286
287// ----------------------------------------------------------------------------
288//  Add a subspectrum with multiplicity  k  (faster than '+')
289// ----------------------------------------------------------------------------
290
291int    spectrum::add_subspectrum( spectrum &a,int k )
292{
293    int i,j;
294    for( i=0, j=0; i<n; i++ )
295    {
296        if( s[i] == a.s[j] )
297        {
298            w[i] += k*a.w[j];
299            j++;
300        }
301    }
302
303    return ( j == a.n ? TRUE : FALSE );
304}
305
306// ----------------------------------------------------------------------------
307//  set  *alpha  to the next spectrum number strictly bigger than  *alpha
308//  returns: TRUE, if such a spectrum number exists
309//           FALSE otherwise
310// ----------------------------------------------------------------------------
311
312int    spectrum::next_number( Rational *alpha )
313{
314    int i=0;
315
316    while( i < n && *alpha >= s[i]  )
317    {
318        i++;
319    }
320
321    if( i < n )
322    {
323        *alpha = s[i];
324        return TRUE;
325    }
326    else
327    {
328        return FALSE;
329    }
330}
331
332// ----------------------------------------------------------------------------
333//  find the next interval on the real line of same length as
334//  [*alpha1,*alpha2]  having a spectrum number as interval border
335// ----------------------------------------------------------------------------
336
337int     spectrum::next_interval( Rational *alpha1,Rational *alpha2 )
338{
339    Rational zero( 0,1 );
340    Rational a1 = *alpha1;
341    Rational a2 = *alpha2;
342    Rational d  = *alpha2 - *alpha1;
343
344    int    e1 = this->next_number( &a1 );
345    int    e2 = this->next_number( &a2 );
346
347    if( e1 || e2 )
348    {
349        Rational d1 = a1 - *alpha1;
350        Rational d2 = a2 - *alpha2;
351
352        if( d1 < d2 || d2 == zero )
353        {
354            *alpha1 = a1;
355            *alpha2 = a1 + d;
356        }
357        else
358        {
359            *alpha1 = a2 - d;
360            *alpha2 = a2;
361        }
362        return  TRUE;
363    }
364    else
365    {
366        return  FALSE;
367    }
368}
369
370// ----------------------------------------------------------------------------
371//  compute the numver of spectrum numbers in the inverval  [*alpha1,*alpha2]
372// ----------------------------------------------------------------------------
373
374int     spectrum::numbers_in_interval( Rational &alpha1,
375                Rational &alpha2,interval_status status )
376{
377    int count = 0;
378
379    for( int i=0; i<n; i++ )
380    {
381        if( ( ( status == OPEN   || status == LEFTOPEN  ) &&
382              s[i] >  alpha1 ) ||
383            ( ( status == CLOSED || status == RIGHTOPEN ) &&
384              s[i] >= alpha1 ) )
385        {
386              if( ( ( status == OPEN   || status == RIGHTOPEN  ) &&
387                  s[i] <  alpha2 ) ||
388                ( ( status == CLOSED || status == LEFTOPEN ) &&
389                  s[i] <= alpha2 ) )
390            {
391                count += w[i];
392            }
393            else
394            {
395                break;
396            }
397        }
398    }
399
400    return count;
401}
402
403// ----------------------------------------------------------------------------
404//  find the maximal integer  k  such that  k*t is semicontinous
405//  for the spectrum
406// ----------------------------------------------------------------------------
407
408int     spectrum::mult_spectrum( spectrum &t )
409{
410    spectrum u = *this + t;
411
412    Rational alpha1 = -2;
413    Rational alpha2 = -1;
414
415    int      mult=INT_MAX,nthis,nt;
416
417    while( u.next_interval( &alpha1,&alpha2 ) )
418    {
419        nt    = t.numbers_in_interval( alpha1,alpha2,LEFTOPEN );
420        nthis = this->numbers_in_interval( alpha1,alpha2,LEFTOPEN );
421
422        if( nt != 0 )
423        {
424            mult = (nthis/nt < mult ? nthis/nt: mult );
425        }
426
427    }
428
429    return  mult;
430}
431
432// ----------------------------------------------------------------------------
433//  find the maximal integer  k  such that  k*t is semicontinous
434//  for the spectrum (in the homogeneous sense)
435// ----------------------------------------------------------------------------
436
437int     spectrum::mult_spectrumh( spectrum &t )
438{
439    spectrum u = *this + t;
440
441    Rational alpha1 = -2;
442    Rational alpha2 = -1;
443
444    int      mult=INT_MAX,nthis,nt;
445
446    while( u.next_interval( &alpha1,&alpha2 ) )
447    {
448        nt    = t.numbers_in_interval( alpha1,alpha2,LEFTOPEN );
449        nthis = this->numbers_in_interval( alpha1,alpha2,LEFTOPEN );
450
451        if( nt != 0 )
452        {
453            mult = (nthis/nt < mult ? nthis/nt: mult );
454        }
455
456        nt    = t.numbers_in_interval( alpha1,alpha2,OPEN );
457        nthis = this->numbers_in_interval( alpha1,alpha2,OPEN );
458
459        if( nt != 0 )
460        {
461            mult = (nthis/nt < mult ? nthis/nt: mult );
462        }
463    }
464
465    return  mult;
466}
467
468// ----------------------------------------------------------------------------
469//  Set the Milnor number
470// ----------------------------------------------------------------------------
471
472/*
473int spectrum::set_milnor( void )
474{
475   mu = 0;
476
477   for( int i=0; i<n; i++ )
478   {
479      mu += w[i];
480   }
481
482   return  mu;
483}
484
485// ----------------------------------------------------------------------------
486//  Set the geometrical genus
487// ----------------------------------------------------------------------------
488
489int spectrum::set_geometric_genus( void )
490{
491   pg = 0;
492
493   for( int i=0; i<n && s[i]<=1; i++ )
494   {
495      pg += w[i];
496   }
497   return  pg;
498}
499*/
500
501#endif /* HAVE_SPECTRUM */
502// ----------------------------------------------------------------------------
503//  semic.cc
504//  end of file
505// ----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.