source: git/Singular/dyn_modules/syzextra/syzextra.h @ 266ae3

fieker-DuValspielwiese
Last change on this file since 266ae3 was 266ae3, checked in by Hans Schoenemann <hannes@…>, 6 years ago
chg: only one definition for poly/ideal/map/matrix
  • Property mode set to 100644
File size: 17.2 KB
RevLine 
[ff7993]1// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2/*****************************************************************************\
[fea494]3 * Computer Algebra System SINGULAR
[ff7993]4\*****************************************************************************/
5/** @file syzextra.h
[fea494]6 *
[ff7993]7 * Computation of Syzygies
8 *
9 * ABSTRACT: Computation of Syzygies due to Schreyer
10 *
11 * @author Oleksandr Motsak
12 *
13 **/
14/*****************************************************************************/
15
16#ifndef SYZEXTRA_H
17#define SYZEXTRA_H
18
[026171]19#include <vector>
[dd24e5]20#include <map>
[2ded87]21#include <string.h>
[85bd2a]22#include <stack>
[026171]23
[ff7993]24// include basic definitions
25#include "singularxx_defs.h"
[d38e6a]26#include "kernel/ideals.h"
[ff7993]27
[4ca3e3]28class idrec; typedef idrec *   idhdl;
[ff7993]29
[4ca3e3]30class kBucket; typedef kBucket* kBucket_pt;
[ff7993]31
[6b8853a]32#ifndef NOPRODUCT
33# define NOPRODUCT 1
34#endif
[ff7993]35
[75f460]36// set to 1 if all leading coeffs are assumed to be all =1...
[55e6b0]37// note the use of simplify on input in SSinit!
[8a5af4]38#ifndef NODIVISION
39# define NODIVISION 1
40#endif
41
[9936d6]42poly leadmonom(const poly p, const ring r, const bool bSetZeroComp = true);
[ff7993]43
[cd5fefc]44/// return the tail of a given polynomial or vector
45/// returns NULL if input is NULL, otherwise
46/// the result is a new polynomial/vector in the ring r
47poly p_Tail(const poly p, const ring r);
48
49
50/// return the tail of a given ideal or module
51/// returns NULL if input is NULL, otherwise
52/// the result is a new ideal/module in the ring r
53/// NOTE: the resulting rank is autocorrected
54ideal id_Tail(const ideal id, const ring r);
55
[92992c]56/// inplace sorting of the module (ideal) id wrt <_(c,ds)
[204092]57void Sort_c_ds(const ideal id, const ring r);
58
59
[85bd2a]60class sBucket; typedef sBucket* sBucket_pt;
61
62/** @class SBucketFactory syzextra.h
63 *
64 * sBucket Factory
65 *
66 * Cleate/store/reuse buckets
[75f460]67 *
[85bd2a]68 */
69class SBucketFactory: private std::stack <sBucket_pt>
70{
71  private:
72    typedef std::stack <sBucket_pt> Base;
73//    typedef std::vector<Bucket> Memory;
74//    typedef std::deque <Bucket> Memory;
75//    typedef std::stack <Bucket, Memory > Base;
76
77  public:
78    typedef Base::value_type Bucket;
79
80    SBucketFactory(const ring r)
[75f460]81#ifndef SING_NDEBUG
[85bd2a]82        : m_ring(r)
83#endif
84    {
[75f460]85      push ( _CreateBucket(r) ); // start with at least one sBucket...?
[85bd2a]86      assume( top() != NULL );
87    };
88
89    ~SBucketFactory()
90    {
91      while( !empty() )
92      {
93        _DestroyBucket( top() );
94        pop();
95      }
96    }
[75f460]97
[85bd2a]98    Bucket getBucket(const ring r, const bool remove = true)
99    {
100      assume( r == m_ring );
101
102      Bucket bt = NULL;
103
104      if( !empty() )
105      {
106        bt = top();
107
[75f460]108        if( remove )
[85bd2a]109          pop();
110      }
111      else
112      {
113        bt = _CreateBucket(r);
114
115        if( !remove )
116        {
117          push(bt);
118          assume( bt == top() );
119        }
120      }
121
122      assume( bt != NULL );
123      assume( _IsBucketEmpty(bt) );
124      assume( r == _GetBucketRing(bt) );
125
126      return bt;
127    }
128
129    // TODO: this may be spared if we give-out a smart Bucket (which returns here upon its destructor!)
130    void putBucket(const Bucket & bt, const bool replace = false)
131    {
[75f460]132      assume( bt != NULL );
[85bd2a]133      assume( _IsBucketEmpty(bt) );
134      assume( m_ring == _GetBucketRing(bt) );
135
136      if( empty() )
137        push( bt );
138      else
139      {
140        if( replace )
141          top() = bt;
142        else
143        {
144          if( bt != top() )
145            push( bt );
146        }
147      }
148
149      assume( bt == top() );
[75f460]150    }
[85bd2a]151
152  private:
153
[75f460]154#ifndef SING_NDEBUG
[85bd2a]155    const ring m_ring; ///< For debugging: all buckets are over the same ring... right?!
156
157    /// get bucket ring
158    static ring _GetBucketRing(const Bucket& bt);
159
160    static bool  _IsBucketEmpty(const Bucket& bt);
161#endif
162
163    /// inital allocation for new buckets
164    static Bucket _CreateBucket(const ring r);
165
166    /// we only expect empty buckets to be left at the end for destructor
167    /// bt will be set to NULL
168    static void _DestroyBucket(Bucket & bt);
169
170  private:
171    SBucketFactory();
172    SBucketFactory(const SBucketFactory&);
173    void operator=(const SBucketFactory&);
174
175};
176
177
178
179
[4eba3ad]180
181
182
183/// Computation attribute storage
[9936d6]184struct SchreyerSyzygyComputationFlags
[4eba3ad]185{
[e98c64]186    SchreyerSyzygyComputationFlags(idhdl rootRingHdl);
187
188    SchreyerSyzygyComputationFlags(const SchreyerSyzygyComputationFlags& attr):
[73ba50]189        OPT__DEBUG(attr.OPT__DEBUG),
190        OPT__LEAD2SYZ(attr.OPT__LEAD2SYZ),  OPT__TAILREDSYZ(attr.OPT__TAILREDSYZ),
191        OPT__HYBRIDNF(attr.OPT__HYBRIDNF), OPT__IGNORETAILS(attr.OPT__IGNORETAILS),
192        OPT__SYZNUMBER(attr.OPT__SYZNUMBER), OPT__TREEOUTPUT(attr.OPT__TREEOUTPUT),
193        OPT__SYZCHECK(attr.OPT__SYZCHECK), OPT__PROT(attr.OPT__PROT),
194        OPT__NOCACHING(attr.OPT__NOCACHING),
[c760e25]195        m_rBaseRing(attr.m_rBaseRing)
[fea494]196    {}
[495328]197
[4eba3ad]198  /// output all the intermediate states
[73ba50]199  const int OPT__DEBUG; // DebugOutput;
[4eba3ad]200
201  /// ?
[73ba50]202  const int OPT__LEAD2SYZ; // TwoLeadingSyzygyTerms;
[4eba3ad]203
204  /// Reduce syzygy tails wrt the leading syzygy terms
[73ba50]205  const int OPT__TAILREDSYZ; // TailReducedSyzygies;
[4eba3ad]206
207  /// Use the usual NF's S-poly reduction while dropping lower order terms
[68fedf]208  /// 2 means - smart selection!
[73ba50]209  const int OPT__HYBRIDNF; // UseHybridNF
[4eba3ad]210
[e98c64]211
212  /// ignore tails and compute the pure Schreyer frame
[73ba50]213  const int OPT__IGNORETAILS; // @IGNORETAILS
[68fedf]214
215  /// Syzygy level (within a resolution)
[73ba50]216  mutable int OPT__SYZNUMBER;
[fea494]217
[8152f7]218  inline void  nextSyzygyLayer() const
219  {
[73ba50]220     OPT__SYZNUMBER++;
[8152f7]221  }
[c760e25]222
223  /// output lifting tree
[73ba50]224  const int OPT__TREEOUTPUT;
[c760e25]225
[196580]226  /// CheckSyzygyProperty: TODO
[73ba50]227  const int OPT__SYZCHECK;
[ed3876]228
229  /// TEST_OPT_PROT
[75f460]230  const bool OPT__PROT;
231
[8a5af4]232  /// no caching/stores/lookups
[73ba50]233  const int OPT__NOCACHING;
[196580]234
[495328]235  /// global base ring
236  const ring m_rBaseRing;
[4eba3ad]237};
238
[026171]239class SchreyerSyzygyComputation;
240
[495328]241class CLCM: public SchreyerSyzygyComputationFlags, public std::vector<bool>
[026171]242{
243  public:
[5cecde]244    CLCM(const ideal& L, const SchreyerSyzygyComputationFlags& flags);
[026171]245
246    bool Check(const poly m) const;
[fea494]247
[026171]248  private:
249    bool m_compute;
[5cecde]250
251    const unsigned int m_N; ///< number of ring variables
[026171]252};
[4eba3ad]253
254
[1a4c343]255class CLeadingTerm
[dd24e5]256{
[fea494]257  public:
[1a4c343]258    CLeadingTerm(unsigned int label,  const poly lt, const ring);
259
[542685e]260#ifndef SING_NDEBUG
[ed3876]261    ~CLeadingTerm();
[542685e]262#endif
[75f460]263
[6b8853a]264#if NOPRODUCT
[1a4c343]265    bool DivisibilityCheck(const poly multiplier, const poly t, const unsigned long not_sev, const ring r) const;
[6b8853a]266#endif
267    bool DivisibilityCheck(const poly product, const unsigned long not_sev, const ring r) const;
[75f460]268
[542685e]269    bool CheckLT( const ideal & L ) const;
270
[ed3876]271#ifndef SING_NDEBUG
[75f460]272    poly lt() const;
[542685e]273    unsigned long sev() const;
274    unsigned int label() const;
[ed3876]275#else
276    inline poly lt() const { return m_lt; };
277    inline unsigned long sev() const { return m_sev; };
[75f460]278    inline unsigned int label() const { return m_label; };
[ed3876]279#endif
[75f460]280
[1a4c343]281  private:
[ed3876]282    const unsigned long m_sev; ///< not short exp. vector
[75f460]283
[ed3876]284    // NOTE/TODO: either of the following should be enough:
285    const unsigned int  m_label; ///< index in the main L[] + 1
[542685e]286
[ed3876]287    const poly          m_lt; ///< the leading term itself L[label-1]
288
289#ifndef SING_NDEBUG
[662075a]290    const ring _R;
[75f460]291
[662075a]292    const poly          m_lt_copy; ///< original copy of LEAD(lt) (only for debug!!!)
[75f460]293#endif
294
[1a4c343]295    // disable the following:
296    CLeadingTerm();
297    CLeadingTerm(const CLeadingTerm&);
298    void operator=(const CLeadingTerm&);
299};
300
301
302// TODO: needs a specialized variant without a component (hash!)
303class CReducerFinder: public SchreyerSyzygyComputationFlags
304{
[6b8853a]305#if NOPRODUCT
[6bfd78]306  friend class CDivisorEnumerator2;
[6b8853a]307#endif
308  friend class CDivisorEnumerator;
[75f460]309
[7a08403]310  public:
[dd24e5]311    typedef long TComponentKey;
312    typedef std::vector<const CLeadingTerm*> TReducers;
[7a08403]313
314  private:
[dd24e5]315    typedef std::map< TComponentKey, TReducers> CReducersHash;
[1a4c343]316
[dd24e5]317  public:
318    /// goes over all leading terms
[5cecde]319    CReducerFinder(const ideal L, const SchreyerSyzygyComputationFlags& flags);
320
321    void Initialize(const ideal L);
[dd24e5]322
323    ~CReducerFinder();
324
[75f460]325
[6b8853a]326#if NOPRODUCT
327    poly
328        FindReducer(const poly multiplier, const poly monom, const poly syzterm, const CReducerFinder& checker) const;
329
330#endif
[1a4c343]331    // TODO: save shortcut (syz: |-.->) LM(LM(m) * "t") -> syz?
[fea494]332    poly // const_iterator // TODO: return const_iterator it, s.th: it->m_lt is the needed
[6b8853a]333        FindReducer(const poly product, const poly syzterm, const CReducerFinder& checker) const;
[5cecde]334
335    bool IsDivisible(const poly q) const;
336
[75f460]337
[9936d6]338    inline bool IsNonempty() const { return !m_hash.empty(); }
339
340    /// is the term to be "preprocessed" as lower order term or lead to only reducible syzygies...
[68fedf]341    int PreProcessTerm(const poly t, CReducerFinder& syzChecker) const;
[dd24e5]342
[2e4396]343#ifndef SING_NDEBUG
[c81423]344    void DebugPrint() const;
[542685e]345    void Verify() const;
[c81423]346#endif
[fea494]347
[dd24e5]348  private:
[5cecde]349    ideal m_L; ///< only for debug
[dd24e5]350
351    CReducersHash m_hash; // can also be replaced with a vector indexed by components
[1a4c343]352
353  private:
354    CReducerFinder(const CReducerFinder&);
355    void operator=(const CReducerFinder&);
[dd24e5]356};
357
[7edaddb]358bool my_p_LmCmp (poly, poly, const ring);
[dd24e5]359
[7edaddb]360typedef poly TCacheKey;
361typedef poly TCacheValue;
362
363struct CCacheCompare
364{
[7a08403]365  const ring & m_ring;
366
[fea494]367  CCacheCompare();
368
[7a08403]369  CCacheCompare(const ring& r): m_ring(r) { assume(r != NULL); }
370
371  CCacheCompare(const CCacheCompare& lhs): m_ring(lhs.m_ring) { assume(m_ring != NULL); }
372  CCacheCompare& operator=(const CCacheCompare& lhs) { assume(lhs.m_ring != NULL); return (const_cast<CCacheCompare&>(lhs)); }
[fea494]373
[7a08403]374  inline bool operator() (const TCacheKey& l, const TCacheKey& r) const { assume(m_ring != NULL); return my_p_LmCmp(l, r, m_ring); }
[7edaddb]375};
[fea494]376
[7edaddb]377typedef std::map<TCacheKey, TCacheValue, CCacheCompare> TP2PCache; // deallocation??? !!!
378typedef std::map<int, TP2PCache> TCache;
[dd24e5]379
[17c644]380
[7088f18]381/** @class SchreyerSyzygyComputation syzextra.h
[fea494]382 *
[7088f18]383 * Computing syzygies after Schreyer
384 *
385 * Storing/accumulating data during the computation requires some global
386 * object, like this class. Ideally the above global functions should not
387 * be used in favour of this class.
388 *
389 * @sa Schreyer Syzygy Computation Paper & Talk & Python prototype
390 */
[495328]391class SchreyerSyzygyComputation: public SchreyerSyzygyComputationFlags
[7088f18]392{
[026171]393  friend class CLCM;
[dd24e5]394  friend class CReducerFinder;
[fea494]395
[7088f18]396  public:
397    /// Construct a global object for given input data (separated into leads & tails)
[495328]398    SchreyerSyzygyComputation(const ideal idLeads, const ideal idTails, const SchreyerSyzygyComputationFlags setting):
399        SchreyerSyzygyComputationFlags(setting),
[fea494]400        m_idLeads(idLeads), m_idTails(id_Copy(idTails, setting.m_rBaseRing)),
[4ca3e3]401        m_syzLeads(NULL), m_syzTails(NULL),
[fea494]402        m_LS(NULL), m_lcm(m_idLeads, setting),
[7edaddb]403        m_div(m_idLeads, setting), m_checker(NULL, setting), m_cache(),
[85bd2a]404        m_sum_bucket_factory(setting.m_rBaseRing),
405        m_spoly_bucket(NULL)
[026171]406    {
[73ba50]407      if( UNLIKELY(OPT__PROT) ) memset( &m_stat, 0, sizeof(m_stat) );
[026171]408    }
[7088f18]409
410    /// Construct a global object for given input data (separated into leads & tails)
[495328]411    SchreyerSyzygyComputation(const ideal idLeads, const ideal idTails, const ideal syzLeads, const SchreyerSyzygyComputationFlags setting):
412        SchreyerSyzygyComputationFlags(setting),
[fea494]413        m_idLeads(idLeads), m_idTails(id_Copy(idTails, setting.m_rBaseRing)),
[4ca3e3]414        m_syzLeads(syzLeads), m_syzTails(NULL),
[7edaddb]415        m_LS(syzLeads), m_lcm(m_idLeads, setting),
416        m_div(m_idLeads, setting), m_checker(NULL, setting), m_cache(),
[85bd2a]417        m_sum_bucket_factory(setting.m_rBaseRing),
418        m_spoly_bucket(NULL)
[026171]419    {
[73ba50]420      if( UNLIKELY(OPT__PROT) ) memset( &m_stat, 0, sizeof(m_stat) );
[75f460]421
[73ba50]422      if( LIKELY(OPT__TAILREDSYZ && !OPT__IGNORETAILS) )
[1a4c343]423      {
424        if (syzLeads != NULL)
425          m_checker.Initialize(syzLeads);
[9936d6]426//        if( idTails != NULL )
427//          SetUpTailTerms();
[1a4c343]428      }
[026171]429    }
[7088f18]430
[fea494]431    /// Destructor should not destruct the resulting m_syzLeads, m_syzTails.
432    ~SchreyerSyzygyComputation(){ CleanUp(); }
[7088f18]433
[1a4c343]434    /// Convert the given ideal of tails into the internal representation (with reducers!)
[9936d6]435    /// Preprocess m_idTails as well...?
436    void SetUpTailTerms();
[fea494]437
[2ded87]438    /// print statistics about the used heuristics
439    void PrintStats() const;
440
[7088f18]441    /// Read off the results while detaching them from this object
442    /// NOTE: no copy!
443    inline void ReadOffResult(ideal& syzL, ideal& syzT)
444    {
[fea494]445      syzL = m_syzLeads; syzT = m_syzTails;
[7088f18]446
447      m_syzLeads = m_syzTails = NULL; // m_LS ?
[75f460]448
[73ba50]449      if ( UNLIKELY(OPT__PROT) )
[2ded87]450        PrintStats();
[7088f18]451    }
[fea494]452
[2ded87]453
[7088f18]454    /// The main driver function: computes
455    void ComputeSyzygy();
456
457    /// Computes Syz(leads) or only LEAD of it.
458    /// The result is stored into m_syzLeads
459    void ComputeLeadingSyzygyTerms(bool bComputeSecondTerms = true);
460
[17c644]461
462
463    /// Main HybridNF == 1: poly reduce + LOT + LCM?
[1cf13b]464    poly SchreyerSyzygyNF(const poly syz_lead, poly syz_2 = NULL) const;
465
[17c644]466
467    // Main (HybridNF == 0) Tree Travers + LOT + LCM?
468    poly TraverseNF(const poly syz_lead, const poly syz_2 = NULL) const;
[75f460]469
[fea494]470    /// High level caching function!!!
[1cf13b]471    poly TraverseTail(poly multiplier, const int tail) const;
[92992c]472
[7edaddb]473    // REMOVE?
474    /// called only from above and from outside (for testing)
[4eba3ad]475    poly TraverseTail(poly multiplier, poly tail) const;
[92992c]476
[7edaddb]477    /// TODO: save shortcut (syz: |-.->) LM(m) * "t" -> ? ???
[4eba3ad]478    poly ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck) const;
[7088f18]479
[7edaddb]480    /// low level computation...
481    poly ComputeImage(poly multiplier, const int tail) const;
482
[1a4c343]483
[fea494]484
[dd24e5]485  public:
486    /// just for testing via the wrapper below
487    inline poly _FindReducer(const poly product, const poly syzterm) const
[fea494]488        { return m_div.FindReducer(product, syzterm, m_checker); }
[9936d6]489 private:
490    void CleanUp();
[7088f18]491  protected:
[c7d29b]492
[9936d6]493
[c7d29b]494    /// just leading terms
495    ideal Compute1LeadingSyzygyTerms();
496
497    /// leading + second terms
498    ideal Compute2LeadingSyzygyTerms();
[026171]499
[75f460]500
[90fa9d]501
[7088f18]502  private:
503    /// input leading terms
504    const ideal m_idLeads;
505
506    /// input tails
507    const ideal m_idTails;
508
509    /// output (syzygy) leading terms (+2nd terms?)
510    ideal m_syzLeads;
511
512    /// output (syzygy) tails
513    ideal m_syzTails;
[fea494]514
[4ca3e3]515    /*mutable?*/ ideal m_LS; ///< leading syzygy terms used for reducing syzygy tails
516
[7088f18]517
[026171]518    /// Bitmask for variables occuring in leading terms
519    const CLCM m_lcm;
[dd24e5]520
521    /// Divisor finder
522    const CReducerFinder m_div;
[5cecde]523
524    /// for checking tail-terms and makeing them irreducible (wrt m_LS!)
525    CReducerFinder m_checker;
526
[1a4c343]527    /*
528    // need more data here:
529    // (m_idLeads : m_tailterm) = (m, pos, compl), s.th: compl * m_tailterm divides m_idLeads[pos]
[fea494]530    // but resulting sysygy compl * gen(pos) should not be in
[1a4c343]531    // Idea: extend CReducerFinder??!!
532    struct CTailTerm
533    {
534      const poly m_tailterm;
[fea494]535
[1a4c343]536      const CReducerFinder m_reducers; // positions are labels (in m_idLeads)...
[fea494]537      // compl - to be computed if needed?
[1a4c343]538
539      CTailTerm(const poly tt, const CReducerFinder reds): m_tailterm(tt), m_reducers(reds) {}
540    };
541
542    typedef std::vector<const CTailTerm*> TTail;
543    typedef std::vector<TTail> TTailTerms;
[fea494]544
[1a4c343]545    TTailTerms m_idTailTerms;
546    */
[fea494]547
[7edaddb]548    mutable TCache m_cache; // cacher comp + poly -> poly! // mutable???
549
[9936d6]550/// TODO: look into m_idTailTerms!!!!!!!!!!!!!!!!!!!!!!!! map? heaps???
[0838d7]551    // NOTE/TODO: the following globally shared buckets violate reentrance - they should rather belong to TLS!
[fea494]552
553    /// used for simple summing up
[85bd2a]554    mutable SBucketFactory m_sum_bucket_factory; // sBucket_pt
[fea494]555
[0838d7]556    /// for S-Polynomial reductions
[85bd2a]557    mutable kBucket_pt m_spoly_bucket; // only used inside of SchreyerSyzygyNF! destruction by CleanUp()!
[7088f18]558
[75f460]559
[2ded87]560    /// Statistics:
561    ///  0..3: as in SetUpTailTerms()::PreProcessTerm() // TODO!!??
562    ///  4: number of terms discarded due to LOT heuristics
563    ///  5: number of terms discarded due to LCM heuristics
564    ///  6, 7: lookups without & with rescale, 8: stores
565    mutable unsigned long m_stat[9];
566};
[7088f18]567
568// The following wrappers are just for testing separate functions on highest level (within schreyer.lib)
569
[495328]570static inline void ComputeSyzygy(const ideal L, const ideal T, ideal& LL, ideal& TT, const SchreyerSyzygyComputationFlags A)
[7088f18]571{
[495328]572  SchreyerSyzygyComputation syz(L, T, A);
[7088f18]573  syz.ComputeSyzygy();
574  syz.ReadOffResult(LL, TT);
575}
576
[495328]577static inline ideal ComputeLeadingSyzygyTerms(const ideal& L, const SchreyerSyzygyComputationFlags A)
[7088f18]578{
[495328]579  SchreyerSyzygyComputation syz(L, NULL, A);
[7088f18]580  syz.ComputeLeadingSyzygyTerms(false);
581  ideal LL, TT;
582  syz.ReadOffResult(LL, TT);
583  return LL; // assume TT is NULL!
584}
585
[495328]586static inline ideal Compute2LeadingSyzygyTerms(const ideal& L, const SchreyerSyzygyComputationFlags A)
[7088f18]587{
[495328]588  SchreyerSyzygyComputation syz(L, NULL, A);
[7088f18]589  syz.ComputeLeadingSyzygyTerms(true);
590  ideal LL, TT;
591  syz.ReadOffResult(LL, TT);
592  return LL; // assume TT is NULL!
593}
594
595static inline poly FindReducer(poly product, poly syzterm,
[495328]596                               ideal L, ideal LS, const SchreyerSyzygyComputationFlags A)
[7088f18]597{
[495328]598  SchreyerSyzygyComputation syz(L, NULL, LS, A);
[dd24e5]599  return syz._FindReducer(product, syzterm);
[7088f18]600}
601
[fea494]602static inline poly TraverseTail(poly multiplier, poly tail,
[495328]603                                ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
[7088f18]604{
[495328]605  SchreyerSyzygyComputation syz(L, T, LS, A);
[7088f18]606  return syz.TraverseTail(multiplier, tail);
607}
608
609static inline poly ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck,
[495328]610                              ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
[7088f18]611{
[495328]612  SchreyerSyzygyComputation syz(L, T, LS, A);
[7088f18]613  return syz.ReduceTerm(multiplier, term4reduction, syztermCheck);
614}
615
616
617static inline poly SchreyerSyzygyNF(poly syz_lead, poly syz_2,
[495328]618                                    ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
[7088f18]619{
[495328]620  SchreyerSyzygyComputation syz(L, T, LS, A);
[7088f18]621  return syz.SchreyerSyzygyNF(syz_lead, syz_2);
622}
623
[fea494]624#endif
[ff7993]625/* #ifndef SYZEXTRA_H */
626
627// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
628
Note: See TracBrowser for help on using the repository browser.