source: git/dyn_modules/syzextra/syzextra.cc @ c7d29b

jengelh-datetimespielwiese
Last change on this file since c7d29b was c7d29b, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
final removal of old _INTERNAL_ functions and corresp. wrappers TODO/Q?: eliminate "const BOOLEAN __DEBUG__ = attributes.__DEBUG__;" by inheriting SchreyerSyzygyComputation from SchreyerSyzygyComputationFlags?
  • Property mode set to 100644
File size: 22.2 KB
Line 
1// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2/*****************************************************************************\
3 * Computer Algebra System SINGULAR   
4\*****************************************************************************/
5/** @file syzextra.cc
6 *
7 * Here we implement the Computation of Syzygies
8 *
9 * ABSTRACT: Computation of Syzygies due to Schreyer
10 *
11 * @author Oleksandr Motsak
12 *
13 **/
14/*****************************************************************************/
15
16// include header file
17#include <kernel/mod2.h>
18
19#include "syzextra.h"
20
21#include "DebugPrint.h"
22
23#include <omalloc/omalloc.h>
24
25#include <misc/intvec.h>
26#include <misc/options.h>
27
28#include <coeffs/coeffs.h>
29
30#include <polys/monomials/p_polys.h>
31#include <polys/monomials/ring.h>
32
33#include <kernel/kstd1.h>
34#include <kernel/polys.h>
35#include <kernel/syz.h>
36#include <kernel/ideals.h>
37
38
39
40#include <Singular/tok.h>
41#include <Singular/ipid.h>
42#include <Singular/lists.h>
43#include <Singular/attrib.h>
44
45#include <Singular/ipid.h> 
46#include <Singular/ipshell.h> // For iiAddCproc
47
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51
52// USING_NAMESPACE_SINGULARXX;
53USING_NAMESPACE( SINGULARXXNAME :: DEBUG )
54
55
56BEGIN_NAMESPACE_SINGULARXX     BEGIN_NAMESPACE(SYZEXTRA)
57
58
59BEGIN_NAMESPACE(SORT_c_ds)
60
61
62#ifdef _GNU_SOURCE
63static int cmp_c_ds(const void *p1, const void *p2, void *R)
64{
65#else
66static int cmp_c_ds(const void *p1, const void *p2)
67{
68  void *R = currRing; 
69#endif
70
71  const int YES = 1;
72  const int NO = -1;
73
74  const ring r =  (const ring) R; // TODO/NOTE: the structure is known: C, lp!!!
75
76  assume( r == currRing );
77
78  const poly a = *(const poly*)p1;
79  const poly b = *(const poly*)p2;
80
81  assume( a != NULL );
82  assume( b != NULL );
83
84  assume( p_LmTest(a, r) );
85  assume( p_LmTest(b, r) );
86
87
88  const signed long iCompDiff = p_GetComp(a, r) - p_GetComp(b, r);
89
90  // TODO: test this!!!!!!!!!!!!!!!!
91
92  //return -( compare (c, qsorts) )
93
94#ifndef NDEBUG
95  const int __DEBUG__ = 0;
96  if( __DEBUG__ )
97  {
98    PrintS("cmp_c_ds: a, b: \np1: "); dPrint(a, r, r, 2);
99    PrintS("b: "); dPrint(b, r, r, 2);
100    PrintLn();
101  }
102#endif
103
104
105  if( iCompDiff > 0 )
106    return YES;
107
108  if( iCompDiff < 0 )
109    return  NO;
110
111  assume( iCompDiff == 0 );
112
113  const signed long iDegDiff = p_Totaldegree(a, r) - p_Totaldegree(b, r);
114
115  if( iDegDiff > 0 )
116    return YES;
117
118  if( iDegDiff < 0 )
119    return  NO;
120
121  assume( iDegDiff == 0 );
122
123#ifndef NDEBUG
124  if( __DEBUG__ )
125  {
126    PrintS("cmp_c_ds: a & b have the same comp & deg! "); PrintLn();
127  }
128#endif
129
130  for (int v = rVar(r); v > 0; v--)
131  {
132    assume( v > 0 );
133    assume( v <= rVar(r) );
134
135    const signed int d = p_GetExp(a, v, r) - p_GetExp(b, v, r);
136
137    if( d > 0 )
138      return YES;
139
140    if( d < 0 )
141      return NO;
142
143    assume( d == 0 );
144  }
145
146  return 0; 
147}
148
149END_NAMESPACE
150/* namespace SORT_c_ds */
151
152/// return a new term: leading coeff * leading monomial of p
153/// with 0 leading component!
154poly leadmonom(const poly p, const ring r)
155{
156  poly m = NULL;
157
158  if( p != NULL )
159  {
160    assume( p != NULL );
161    assume( p_LmTest(p, r) );
162
163    m = p_LmInit(p, r);
164    p_SetCoeff0(m, n_Copy(p_GetCoeff(p, r), r), r);
165
166    p_SetComp(m, 0, r);
167    p_Setm(m, r);
168
169    assume( p_GetComp(m, r) == 0 );
170    assume( m != NULL );
171    assume( pNext(m) == NULL );
172    assume( p_LmTest(m, r) );
173  }
174
175  return m;
176}
177
178
179   
180poly p_Tail(const poly p, const ring r)
181{
182  if( p == NULL)
183    return NULL;
184  else
185    return p_Copy( pNext(p), r );
186}
187
188
189ideal id_Tail(const ideal id, const ring r)
190{
191  if( id == NULL)
192    return NULL;
193
194  const ideal newid = idInit(IDELEMS(id),id->rank);
195 
196  for (int i=IDELEMS(id) - 1; i >= 0; i--)
197    newid->m[i] = p_Tail( id->m[i], r );
198
199  newid->rank = id_RankFreeModule(newid, currRing);
200
201  return newid; 
202}
203
204
205
206void Sort_c_ds(const ideal id, const ring r)
207{
208  const int sizeNew = IDELEMS(id);
209
210#ifdef _GNU_SOURCE
211#define qsort_my(m, s, ss, r, cmp) qsort_r(m, s, ss, cmp, r)
212#else
213#define qsort_my(m, s, ss, r, cmp) qsort_r(m, s, ss, cmp)
214#endif
215 
216  if( sizeNew >= 2 )
217    qsort_my(id->m, sizeNew, sizeof(poly), r, FROM_NAMESPACE(SORT_c_ds, cmp_c_ds));
218
219#undef qsort_my
220
221  id->rank = id_RankFreeModule(id, r);
222}
223
224
225ideal SchreyerSyzygyComputation::Compute1LeadingSyzygyTerms()
226{
227  const ideal& id = m_idLeads;
228  const ring& r = m_rBaseRing;
229  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
230
231
232  //   const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
233//   const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
234  const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
235//   const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
236//   const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
237
238  assume(!__LEAD2SYZ__);
239
240  // 1. set of components S?
241  // 2. for each component c from S: set of indices of leading terms
242  // with this component?
243  // 3. short exp. vectors for each leading term?
244
245  const int size = IDELEMS(id);
246
247  if( size < 2 )
248  {
249    const ideal newid = idInit(1, 0); newid->m[0] = NULL; // zero ideal...       
250    return newid;
251  }
252
253
254  // TODO/NOTE: input is supposed to be (reverse-) sorted wrt "(c,ds)"!??
255
256  // components should come in groups: count elements in each group
257  // && estimate the real size!!!
258
259
260  // use just a vector instead???
261  const ideal newid = idInit( (size * (size-1))/2, size); // maximal size: ideal case!
262
263  int k = 0;
264
265  for (int j = 0; j < size; j++)
266  {
267    const poly p = id->m[j];
268    assume( p != NULL );
269    const int  c = p_GetComp(p, r);
270
271    for (int i = j - 1; i >= 0; i--)
272    {
273      const poly pp = id->m[i];
274      assume( pp != NULL );
275      const int  cc = p_GetComp(pp, r);
276
277      if( c != cc )
278        continue;
279
280      const poly m = p_Init(r); // p_New???
281
282      // m = LCM(p, pp) / p! // TODO: optimize: knowing the ring structure: (C/lp)!
283      for (int v = rVar(r); v > 0; v--)
284      {
285        assume( v > 0 );
286        assume( v <= rVar(r) );
287
288        const short e1 = p_GetExp(p , v, r);
289        const short e2 = p_GetExp(pp, v, r);
290
291        if( e1 >= e2 )
292          p_SetExp(m, v, 0, r);
293        else
294          p_SetExp(m, v, e2 - e1, r);
295
296      }
297
298      assume( (j > i) && (i >= 0) );
299
300      p_SetComp(m, j + 1, r);
301      pNext(m) = NULL;
302      p_SetCoeff0(m, n_Init(1, r->cf), r); // for later...
303
304      p_Setm(m, r); // should not do anything!!!
305
306      newid->m[k++] = m;
307    }
308  }
309
310//   if( __DEBUG__ && FALSE )
311//   {
312//     PrintS("ComputeLeadingSyzygyTerms::Temp0: \n");
313//     dPrint(newid, r, r, 1);
314//   }
315
316  // the rest of newid is assumed to be zeroes...
317
318  // simplify(newid, 2 + 32)??
319  // sort(newid, "C,ds")[1]???
320  id_DelDiv(newid, r); // #define SIMPL_LMDIV 32
321
322//   if( __DEBUG__ && FALSE )
323//   {
324//     PrintS("ComputeLeadingSyzygyTerms::Temp1: \n");
325//     dPrint(newid, r, r, 1);
326//   }
327
328  idSkipZeroes(newid); // #define SIMPL_NULL 2
329
330//   if( __DEBUG__ )
331//   {
332//     PrintS("ComputeLeadingSyzygyTerms::Output: \n");
333//     dPrint(newid, r, r, 1);
334//   }
335
336  Sort_c_ds(newid, r);
337
338  return newid;
339}
340
341ideal SchreyerSyzygyComputation::Compute2LeadingSyzygyTerms()
342{
343  const ideal& id = m_idLeads;
344  const ring& r = m_rBaseRing;
345  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
346 
347//   const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
348//   const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
349//   const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
350//   const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
351  const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
352 
353
354  // 1. set of components S?
355  // 2. for each component c from S: set of indices of leading terms
356  // with this component?
357  // 3. short exp. vectors for each leading term?
358
359  const int size = IDELEMS(id);
360
361  if( size < 2 )
362  {
363    const ideal newid = idInit(1, 1); newid->m[0] = NULL; // zero module...   
364    return newid;
365  }
366
367
368    // TODO/NOTE: input is supposed to be sorted wrt "C,ds"!??
369
370    // components should come in groups: count elements in each group
371    // && estimate the real size!!!
372
373
374    // use just a vector instead???
375  ideal newid = idInit( (size * (size-1))/2, size); // maximal size: ideal case!
376
377  int k = 0;
378
379  for (int j = 0; j < size; j++)
380  {
381    const poly p = id->m[j];
382    assume( p != NULL );
383    const int  c = p_GetComp(p, r);
384
385    for (int i = j - 1; i >= 0; i--)
386    {
387      const poly pp = id->m[i];
388      assume( pp != NULL );
389      const int  cc = p_GetComp(pp, r);
390
391      if( c != cc )
392        continue;
393
394        // allocate memory & zero it out!
395      const poly m = p_Init(r); const poly mm = p_Init(r);
396
397
398        // m = LCM(p, pp) / p! mm = LCM(p, pp) / pp!
399        // TODO: optimize: knowing the ring structure: (C/lp)!
400
401      for (int v = rVar(r); v > 0; v--)
402      {
403        assume( v > 0 );
404        assume( v <= rVar(r) );
405
406        const short e1 = p_GetExp(p , v, r);
407        const short e2 = p_GetExp(pp, v, r);
408
409        if( e1 >= e2 )
410          p_SetExp(mm, v, e1 - e2, r); //            p_SetExp(m, v, 0, r);
411        else
412          p_SetExp(m, v, e2 - e1, r); //            p_SetExp(mm, v, 0, r);
413
414      }
415
416      assume( (j > i) && (i >= 0) );
417
418      p_SetComp(m, j + 1, r);
419      p_SetComp(mm, i + 1, r);
420
421      const number& lc1 = p_GetCoeff(p , r);
422      const number& lc2 = p_GetCoeff(pp, r);
423
424      number g = n_Lcm( lc1, lc2, r );
425
426      p_SetCoeff0(m ,       n_Div(g, lc1, r), r);
427      p_SetCoeff0(mm, n_Neg(n_Div(g, lc2, r), r), r);
428
429      n_Delete(&g, r);
430
431      p_Setm(m, r); // should not do anything!!!
432      p_Setm(mm, r); // should not do anything!!!
433
434      pNext(m) = mm; //        pNext(mm) = NULL;
435
436      newid->m[k++] = m;
437    }
438  }
439
440//   if( __DEBUG__ && FALSE )
441//   {
442//     PrintS("Compute2LeadingSyzygyTerms::Temp0: \n");
443//     dPrint(newid, r, r, 1);
444//   }
445
446  if( !__TAILREDSYZ__ )
447  {
448      // simplify(newid, 2 + 32)??
449      // sort(newid, "C,ds")[1]???
450    id_DelDiv(newid, r); // #define SIMPL_LMDIV 32
451
452//     if( __DEBUG__ && FALSE )
453//     {
454//       PrintS("Compute2LeadingSyzygyTerms::Temp1 (deldiv): \n");
455//       dPrint(newid, r, r, 1);
456//     }
457  }
458  else
459  {
460      //      option(redSB); option(redTail);
461      //      TEST_OPT_REDSB
462      //      TEST_OPT_REDTAIL
463    assume( r == currRing );
464    BITSET _save_test = test;
465    test |= (Sy_bit(OPT_REDTAIL) | Sy_bit(OPT_REDSB));
466
467    intvec* w=new intvec(IDELEMS(newid));
468    ideal tmp = kStd(newid, currQuotient, isHomog, &w);
469    delete w;
470
471    test = _save_test;
472
473    id_Delete(&newid, r);
474    newid = tmp;
475
476//     if( __DEBUG__ && FALSE )
477//     {
478//       PrintS("Compute2LeadingSyzygyTerms::Temp1 (std): \n");
479//       dPrint(newid, r, r, 1);
480//     }
481
482  }
483
484  idSkipZeroes(newid);
485
486  Sort_c_ds(newid, r);
487 
488  return newid;
489}
490
491void SchreyerSyzygyComputation::ComputeSyzygy()
492{
493//  FROM_NAMESPACE(INTERNAL, _ComputeSyzygy(m_idLeads, m_idTails, m_syzLeads, m_syzTails, m_rBaseRing, m_atttributes)); // TODO: just a wrapper for now :/
494
495  assume( m_idLeads != NULL );
496  assume( m_idTails != NULL );
497 
498  const ideal& L = m_idLeads;
499  const ideal& T = m_idTails;
500
501  ideal& TT = m_syzTails;
502  const ring& R = m_rBaseRing;
503  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
504
505//  const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
506//  const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
507  const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
508  const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
509  const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
510
511  assume( R == currRing ); // For attributes :-/
512
513  assume( IDELEMS(L) == IDELEMS(T) );
514
515  ComputeLeadingSyzygyTerms( __LEAD2SYZ__ ); // 2 terms OR 1 term!
516
517  ideal& LL = m_syzLeads;
518 
519  const int size = IDELEMS(LL);
520
521  TT = idInit(size, 0);
522
523  if( size == 1 && LL->m[0] == NULL )
524    return;
525
526
527  ideal LS = NULL;
528
529  if( __TAILREDSYZ__ )
530    LS = LL;
531
532  for( int k = size - 1; k >= 0; k-- )
533  {
534    const poly a = LL->m[k]; assume( a != NULL );
535
536    const int r = p_GetComp(a, R) - 1; 
537
538    assume( r >= 0 && r < IDELEMS(T) );
539    assume( r >= 0 && r < IDELEMS(L) );
540
541    poly aa = leadmonom(a, R); assume( aa != NULL); // :(   
542
543    poly a2 = pNext(a);   
544
545    if( a2 != NULL )
546    {
547      TT->m[k] = a2; pNext(a) = NULL;
548    }
549
550    if( ! __HYBRIDNF__ )
551    {
552      poly t = TraverseTail(aa, T->m[r]);
553
554      if( a2 != NULL )
555      {
556        assume( __LEAD2SYZ__ );
557
558        const int r2 = p_GetComp(a2, R) - 1; poly aa2 = leadmonom(a2, R); // :(
559
560        assume( r2 >= 0 && r2 < IDELEMS(T) );
561
562        TT->m[k] = p_Add_q(a2, p_Add_q(t, TraverseTail(aa2, T->m[r2]), R), R);
563
564        p_Delete(&aa2, R);
565      } else
566        TT->m[k] = p_Add_q(t, ReduceTerm(aa, L->m[r], a), R);
567
568    } else
569    {
570      if( a2 == NULL )
571      {
572        aa = p_Mult_mm(aa, L->m[r], R);
573        a2 = FindReducer(aa, a); 
574      }
575      assume( a2 != NULL );
576
577      TT->m[k] = SchreyerSyzygyNF(a, a2); // will copy a2 :(
578
579      p_Delete(&a2, R);
580    }
581    p_Delete(&aa, R);   
582  }
583
584  TT->rank = id_RankFreeModule(TT, R);
585}
586
587void SchreyerSyzygyComputation::ComputeLeadingSyzygyTerms(bool bComputeSecondTerms)
588{
589  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
590
591  const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
592  const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
593
594  if( bComputeSecondTerms )
595//    m_syzLeads = FROM_NAMESPACE(INTERNAL, _Compute2LeadingSyzygyTerms(m_idLeads, m_rBaseRing, m_atttributes));
596    m_syzLeads = Compute2LeadingSyzygyTerms();
597  else
598    m_syzLeads = Compute1LeadingSyzygyTerms();
599//    m_syzLeads = FROM_NAMESPACE(INTERNAL, _ComputeLeadingSyzygyTerms(m_idLeads, m_rBaseRing, m_atttributes));
600 
601  // NOTE: set m_LS if tails are to be reduced!
602
603  if (__TAILREDSYZ__)
604    m_LS = m_syzLeads;
605}
606
607poly SchreyerSyzygyComputation::FindReducer(poly product, poly syzterm) const
608{
609//  return FROM_NAMESPACE(INTERNAL, _FindReducer(product, syzterm, m_idLeads, m_LS, m_rBaseRing, m_atttributes));
610//  poly _FindReducer(poly product, poly syzterm,
611//                     ideal L, ideal LS,
612//                     const ring r,
613//                     const SchreyerSyzygyComputationFlags attributes)
614
615  const ideal& L = m_idLeads;
616  const ideal& LS = m_LS;
617  const ring& r = m_rBaseRing;
618  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
619
620
621  const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
622  const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
623//   const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
624//   const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
625  const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
626
627  assume( product != NULL );
628  assume( L != NULL );
629
630  int c = 0;
631
632  if (syzterm != NULL)
633    c = p_GetComp(syzterm, r) - 1;
634
635  assume( c >= 0 && c < IDELEMS(L) );
636
637  if (__SYZCHECK__ && syzterm != NULL)
638  {
639    const poly m = L->m[c];
640
641    assume( m != NULL ); assume( pNext(m) == NULL );
642
643    poly lm = p_Mult_mm(leadmonom(syzterm, r), m, r);
644    assume( p_EqualPolys(lm, product, r) );
645
646    //  def @@c = leadcomp(syzterm); int @@r = int(@@c);
647    //  def @@product = leadmonomial(syzterm) * L[@@r];
648
649    p_Delete(&lm, r);   
650  }
651
652  // looking for an appropriate diviser q = L[k]...
653  for( int k = IDELEMS(L)-1; k>= 0; k-- )
654  {
655    const poly p = L->m[k];   
656
657    // ... which divides the product, looking for the _1st_ appropriate one!
658    if( !p_LmDivisibleBy(p, product, r) )
659      continue;
660
661
662    const poly q = p_New(r);
663    pNext(q) = NULL;
664    p_ExpVectorDiff(q, product, p, r); // (LM(product) / LM(L[k]))
665    p_SetComp(q, k + 1, r);
666    p_Setm(q, r);
667
668    // cannot allow something like: a*gen(i) - a*gen(i)
669    if (syzterm != NULL && (k == c))
670      if (p_ExpVectorEqual(syzterm, q, r))
671      {
672        if( __DEBUG__ )
673        {
674          Print("_FindReducer::Test SYZTERM: q == syzterm !:((, syzterm is: ");
675          dPrint(syzterm, r, r, 1);
676        }   
677
678        p_LmFree(q, r);
679        continue;
680      }
681
682    // while the complement (the fraction) is not reducible by leading syzygies
683    if( LS != NULL )
684    {
685      assume( __TAILREDSYZ__ );
686      BOOLEAN ok = TRUE;
687
688      for(int kk = IDELEMS(LS)-1; kk>= 0; kk-- )
689      {
690        const poly pp = LS->m[kk];
691
692        if( p_LmDivisibleBy(pp, q, r) )
693        {
694
695          if( __DEBUG__ )
696          {
697            Print("_FindReducer::Test LS: q is divisible by LS[%d] !:((, diviser is: ", kk+1);
698            dPrint(pp, r, r, 1);
699          }   
700
701          ok = FALSE; // q in <LS> :((
702          break;                 
703        }
704      }
705
706      if(!ok)
707      {
708        p_LmFree(q, r);
709        continue;
710      }
711    }
712
713    p_SetCoeff0(q, n_Neg( n_Div( p_GetCoeff(product, r), p_GetCoeff(p, r), r), r), r);
714    return q;
715
716  }
717
718
719  return NULL;
720}
721
722
723poly SchreyerSyzygyComputation::SchreyerSyzygyNF(poly syz_lead, poly syz_2) const
724{
725// return FROM_NAMESPACE(INTERNAL, _SchreyerSyzygyNF(syz_lead, syz_2, m_idLeads, m_idTails, m_LS, m_rBaseRing, m_atttributes));
726// poly _SchreyerSyzygyNF(poly syz_lead, poly syz_2,
727//                       ideal L, ideal T, ideal LS,
728//                       const ring r,
729//                       const SchreyerSyzygyComputationFlags attributes)
730// {
731
732  const ideal& L = m_idLeads;
733  const ideal& T = m_idTails;
734  const ideal& LS = m_LS;
735  const ring& r = m_rBaseRing;
736  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
737
738 
739//   const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
740//   const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
741//   const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
742//   const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
743//   const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
744
745  assume( syz_lead != NULL );
746  assume( syz_2 != NULL );
747
748  assume( L != NULL );
749  assume( T != NULL );
750
751  assume( IDELEMS(L) == IDELEMS(T) );
752
753  int  c = p_GetComp(syz_lead, r) - 1;
754
755  assume( c >= 0 && c < IDELEMS(T) );
756
757  poly p = leadmonom(syz_lead, r); // :( 
758  poly spoly = pp_Mult_qq(p, T->m[c], r);
759  p_Delete(&p, r);
760
761
762  c = p_GetComp(syz_2, r) - 1;
763  assume( c >= 0 && c < IDELEMS(T) );
764
765  p = leadmonom(syz_2, r); // :(
766  spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);
767  p_Delete(&p, r);
768
769  poly tail = p_Copy(syz_2, r); // TODO: use bucket!?
770
771  while (spoly != NULL)
772  {
773    poly t = FindReducer(spoly, NULL);
774
775    p_LmDelete(&spoly, r);
776
777    if( t != NULL )
778    {
779      p = leadmonom(t, r); // :(
780      c = p_GetComp(t, r) - 1;
781
782      assume( c >= 0 && c < IDELEMS(T) );
783
784      spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);
785
786      p_Delete(&p, r);
787
788      tail = p_Add_q(tail, t, r);
789    }   
790  }
791
792  return tail;
793}
794
795
796poly SchreyerSyzygyComputation::TraverseTail(poly multiplier, poly tail) const
797{
798  const ideal& L = m_idLeads;
799  const ideal& T = m_idTails;
800  const ideal& LS = m_LS;
801  const ring& r = m_rBaseRing;
802  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
803
804//  return FROM_NAMESPACE(INTERNAL, _TraverseTail(multiplier, tail, m_idLeads, m_idTails, m_LS, m_rBaseRing, m_atttributes));
805// poly _TraverseTail(poly multiplier, poly tail,
806//                    ideal L, ideal T, ideal LS,
807//                    const ring r,
808//                    const SchreyerSyzygyComputationFlags attributes)
809// {
810
811
812//   const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
813//   const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
814//   const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
815//   const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
816//   const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
817
818  assume( multiplier != NULL );
819
820  assume( L != NULL );
821  assume( T != NULL );
822
823  poly s = NULL;
824
825  // iterate over the tail
826  for(poly p = tail; p != NULL; p = pNext(p))
827    s = p_Add_q(s, ReduceTerm(multiplier, p, NULL), r); 
828
829  return s;
830}
831
832
833
834
835poly SchreyerSyzygyComputation::ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck) const
836{
837  const ideal& L = m_idLeads;
838  const ideal& T = m_idTails;
839  const ideal& LS = m_LS;
840  const ring& r = m_rBaseRing;
841  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
842
843//  return FROM_NAMESPACE(INTERNAL, _ReduceTerm(multiplier, term4reduction, syztermCheck, m_idLeads, m_idTails, m_LS, m_rBaseRing, m_atttributes));
844// poly _ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck,
845//                 ideal L, ideal T, ideal LS,
846//                 const ring r,
847//                 const SchreyerSyzygyComputationFlags attributes)
848
849
850
851//   const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
852//   const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
853//   const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
854//   const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
855//   const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
856
857  assume( multiplier != NULL );
858  assume( term4reduction != NULL );
859
860
861  assume( L != NULL );
862  assume( T != NULL );
863
864  // assume(r == currRing); // ?
865
866  // simple implementation with FindReducer:
867  poly s = NULL;
868
869  if(1)
870  {
871    // NOTE: only LT(term4reduction) should be used in the following:
872    poly product = pp_Mult_mm(multiplier, term4reduction, r);
873    s = FindReducer(product, syztermCheck);
874    p_Delete(&product, r);
875  }
876
877  if( s == NULL ) // No Reducer?
878    return s;
879
880  poly b = leadmonom(s, r);
881
882  const int c = p_GetComp(s, r) - 1;
883  assume( c >= 0 && c < IDELEMS(T) );
884
885  const poly tail = T->m[c];
886
887  if( tail != NULL )
888    s = p_Add_q(s, TraverseTail(b, tail), r); 
889
890  return s;
891}
892
893
894
895
896
897BEGIN_NAMESPACE_NONAME
898   
899static inline int atGetInt(idhdl rootRingHdl, const char* attribute, int def)
900{
901  return ((int)(long)(atGet(rootRingHdl, attribute, INT_CMD, (void*)def)));
902}
903
904END_NAMESPACE   
905
906SchreyerSyzygyComputationFlags::SchreyerSyzygyComputationFlags(idhdl rootRingHdl):
907#ifndef NDEBUG
908    __DEBUG__( (BOOLEAN)atGetInt(rootRingHdl,"DEBUG", TRUE) ),
909#else
910    __DEBUG__( (BOOLEAN)atGetInt(rootRingHdl,"DEBUG", FALSE) ),
911#endif
912    __SYZCHECK__( (BOOLEAN)atGetInt(rootRingHdl, "SYZCHECK", __DEBUG__) ),
913    __LEAD2SYZ__( (BOOLEAN)atGetInt(rootRingHdl, "LEAD2SYZ", 1) ), 
914    __TAILREDSYZ__( (BOOLEAN)atGetInt(rootRingHdl, "TAILREDSYZ", 1) ), 
915    __HYBRIDNF__( (BOOLEAN)atGetInt(rootRingHdl, "HYBRIDNF", 0) ) 
916{   
917  if( __DEBUG__ )
918  {
919    PrintS("SchreyerSyzygyComputationFlags: \n");
920    Print("   DEBUG     : \t%d\n", __DEBUG__);
921    Print("   SYZCHECK  : \t%d\n", __SYZCHECK__);
922    Print("   LEAD2SYZ  : \t%d\n", __LEAD2SYZ__);
923    Print("   TAILREDSYZ: \t%d\n", __TAILREDSYZ__);
924  }
925
926  // TODO: just current setting!
927  assume( rootRingHdl == currRingHdl );
928  assume( rootRingHdl->typ == RING_CMD );
929  assume( rootRingHdl->data.uring == currRing );
930  // move the global ring here inside???
931}
932
933   
934
935
936END_NAMESPACE               END_NAMESPACE_SINGULARXX
937
938
939// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
Note: See TracBrowser for help on using the repository browser.