source: git/kernel/semic.cc @ f5d2647

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