source: git/kernel/semic.cc @ f0549c8

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