source: git/dyn_modules/syzextra/syzextra.h @ 6bfd78

spielwiese
Last change on this file since 6bfd78 was 6bfd78, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Added CDivisorEnumerator(2) - to be used by CReducerFinder add: FindReducer + multiplier!
  • Property mode set to 100644
File size: 11.5 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.h
6 *
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
19#include <vector>
20#include <map>
21
22// include basic definitions
23#include "singularxx_defs.h"
24
25struct  spolyrec;
26typedef struct spolyrec    polyrec;
27typedef polyrec *          poly;
28
29struct ip_sring;
30typedef struct ip_sring *         ring;
31
32struct sip_sideal;
33typedef struct sip_sideal *       ideal;
34
35class idrec;
36typedef idrec *   idhdl;
37
38BEGIN_NAMESPACE_SINGULARXX    BEGIN_NAMESPACE(SYZEXTRA)
39
40poly leadmonom(const poly p, const ring r);
41
42/// return the tail of a given polynomial or vector
43/// returns NULL if input is NULL, otherwise
44/// the result is a new polynomial/vector in the ring r
45poly p_Tail(const poly p, const ring r);
46
47
48/// return the tail of a given ideal or module
49/// returns NULL if input is NULL, otherwise
50/// the result is a new ideal/module in the ring r
51/// NOTE: the resulting rank is autocorrected
52ideal id_Tail(const ideal id, const ring r);
53
54/// inplace sorting of the module (ideal) id wrt <_(c,ds)
55void Sort_c_ds(const ideal id, const ring r);
56
57
58
59
60
61/// Computation attribute storage
62class SchreyerSyzygyComputationFlags
63{
64  public: 
65    SchreyerSyzygyComputationFlags(idhdl rootRingHdl);
66
67    SchreyerSyzygyComputationFlags(const SchreyerSyzygyComputationFlags& attr):
68        __DEBUG__(attr.__DEBUG__),
69  //      __SYZCHECK__(attr.__SYZCHECK__),
70        __LEAD2SYZ__(attr.__LEAD2SYZ__),  __TAILREDSYZ__(attr.__TAILREDSYZ__),
71        __HYBRIDNF__(attr.__HYBRIDNF__), __IGNORETAILS__(attr.__IGNORETAILS__),
72        m_rBaseRing(attr.m_rBaseRing)
73    {}   
74
75  /// output all the intermediate states
76  const bool __DEBUG__; // DebugOutput;
77
78  //  const bool __SYZCHECK__; // CheckSyzygyProperty: never tested here...
79
80  /// ?
81  const bool __LEAD2SYZ__; // TwoLeadingSyzygyTerms;
82
83  /// Reduce syzygy tails wrt the leading syzygy terms
84  const bool __TAILREDSYZ__; // TailReducedSyzygies;
85
86  /// Use the usual NF's S-poly reduction while dropping lower order terms
87  const bool __HYBRIDNF__; // UseHybridNF
88
89
90  /// ignore tails and compute the pure Schreyer frame
91  const bool __IGNORETAILS__; // @IGNORETAILS
92 
93  /// global base ring
94  const ring m_rBaseRing;
95
96};
97
98class SchreyerSyzygyComputation;
99
100class CLCM: public SchreyerSyzygyComputationFlags, public std::vector<bool>
101{
102  public:
103    CLCM(const ideal& L, const SchreyerSyzygyComputationFlags& flags);
104
105    bool Check(const poly m) const;
106   
107  private:
108    bool m_compute;
109
110    const unsigned int m_N; ///< number of ring variables
111};
112
113
114class CLeadingTerm
115{
116  public: 
117    CLeadingTerm(unsigned int label,  const poly lt, const ring);
118
119  public:
120
121    const unsigned long m_sev; ///< not short exp. vector
122        // NOTE/TODO: either of the following should be enough:
123    const unsigned int  m_label; ///< index in the main L[] + 1
124    const poly          m_lt; ///< the leading term itself L[label-1]
125
126  public:
127    bool DivisibilityCheck(const poly product, const unsigned long not_sev, const ring r) const;
128    bool DivisibilityCheck(const poly multiplier, const poly t, const unsigned long not_sev, const ring r) const;
129
130  private:
131    // disable the following:
132    CLeadingTerm();
133    CLeadingTerm(const CLeadingTerm&);
134    void operator=(const CLeadingTerm&);
135};
136
137
138// TODO: needs a specialized variant without a component (hash!)
139class CReducerFinder: public SchreyerSyzygyComputationFlags
140{
141  friend class CDivisorEnumerator;
142  friend class CDivisorEnumerator2;
143  private:
144    typedef long TComponentKey;
145    typedef std::vector<const CLeadingTerm*> TReducers;
146    typedef std::map< TComponentKey, TReducers> CReducersHash;
147
148  public:
149    /// goes over all leading terms
150    CReducerFinder(const ideal L, const SchreyerSyzygyComputationFlags& flags);
151
152    void Initialize(const ideal L);
153
154    ~CReducerFinder();
155
156    // TODO: save shortcut (syz: |-.->) LM(LM(m) * "t") -> syz?
157    poly // const_iterator // TODO: return const_iterator it, s.th: it->m_lt is the needed
158    FindReducer(const poly product, const poly syzterm, const CReducerFinder& checker) const;
159
160    bool IsDivisible(const poly q) const;
161
162    bool IsNonempty() const { return !m_hash.empty(); }
163
164    poly FindReducer(const poly multiplier, const poly monom, const poly syzterm, const CReducerFinder& checker) const;
165   
166#ifndef NDEBUG
167    void DebugPrint() const;
168#endif
169   
170  private:
171    ideal m_L; ///< only for debug
172
173    CReducersHash m_hash; // can also be replaced with a vector indexed by components
174
175  private:
176    CReducerFinder(const CReducerFinder&);
177    void operator=(const CReducerFinder&);
178};
179
180
181
182/** @class SchreyerSyzygyComputation syzextra.h
183 *
184 * Computing syzygies after Schreyer
185 *
186 * Storing/accumulating data during the computation requires some global
187 * object, like this class. Ideally the above global functions should not
188 * be used in favour of this class.
189 *
190 * @sa Schreyer Syzygy Computation Paper & Talk & Python prototype
191 */
192class SchreyerSyzygyComputation: public SchreyerSyzygyComputationFlags
193{
194  friend class CLCM;
195  friend class CReducerFinder;
196 
197  public:
198    /// Construct a global object for given input data (separated into leads & tails)
199    SchreyerSyzygyComputation(const ideal idLeads, const ideal idTails, const SchreyerSyzygyComputationFlags setting):
200        SchreyerSyzygyComputationFlags(setting),
201        m_idLeads(idLeads), m_idTails(idTails), 
202        m_syzLeads(NULL), m_syzTails(NULL), m_LS(NULL),
203        m_lcm(m_idLeads, setting), m_div(m_idLeads, setting), m_checker(NULL, setting)
204    {
205      if( __TAILREDSYZ__ && !__IGNORETAILS__)
206      {
207        if( idTails != NULL )
208          SetUpTailTerms(idTails);
209      }
210    }
211
212    /// Construct a global object for given input data (separated into leads & tails)
213    SchreyerSyzygyComputation(const ideal idLeads, const ideal idTails, const ideal syzLeads, const SchreyerSyzygyComputationFlags setting):
214        SchreyerSyzygyComputationFlags(setting),
215        m_idLeads(idLeads), m_idTails(idTails), 
216        m_syzLeads(syzLeads), m_syzTails(NULL), m_LS(syzLeads), 
217        m_lcm(m_idLeads, setting), m_div(m_idLeads, setting), m_checker(NULL, setting)
218    {
219      if( __TAILREDSYZ__ && !__IGNORETAILS__)
220      {
221        if (syzLeads != NULL)
222          m_checker.Initialize(syzLeads);
223        if( idTails != NULL )
224          SetUpTailTerms(idTails);
225      }
226    }
227
228    /// Destructor should not destruct the resulting m_syzLeads, m_syzTails.
229    ~SchreyerSyzygyComputation(){ CleanUp(); }
230
231    /// Convert the given ideal of tails into the internal representation (with reducers!)
232    void SetUpTailTerms(const ideal idTails);
233   
234    void CleanUp();
235
236    /// Read off the results while detaching them from this object
237    /// NOTE: no copy!
238    inline void ReadOffResult(ideal& syzL, ideal& syzT)
239    {
240      syzL = m_syzLeads; syzT = m_syzTails; 
241
242      m_syzLeads = m_syzTails = NULL; // m_LS ?
243    }
244   
245    /// The main driver function: computes
246    void ComputeSyzygy();
247
248    /// Computes Syz(leads) or only LEAD of it.
249    /// The result is stored into m_syzLeads
250    void ComputeLeadingSyzygyTerms(bool bComputeSecondTerms = true);
251
252    poly SchreyerSyzygyNF(const poly syz_lead, poly syz_2 = NULL) const;
253
254    poly TraverseTail(poly multiplier, const int tail) const;
255
256    // called only from above and from outside (for testing)
257    poly TraverseTail(poly multiplier, poly tail) const;
258
259    // TODO: save shortcut (syz: |-.->) LM(m) * "t" -> ?
260    poly ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck) const;
261
262    //
263    poly TraverseNF(const poly syz_lead, const poly syz_2 = NULL) const;
264
265   
266  public:
267    /// just for testing via the wrapper below
268    inline poly _FindReducer(const poly product, const poly syzterm) const
269        { return m_div.FindReducer(product, syzterm, m_checker); } 
270   
271  protected:
272
273    /// just leading terms
274    ideal Compute1LeadingSyzygyTerms();
275
276    /// leading + second terms
277    ideal Compute2LeadingSyzygyTerms();
278
279  private:
280    /// input leading terms
281    const ideal m_idLeads;
282
283    /// input tails
284    const ideal m_idTails;
285
286    /// output (syzygy) leading terms (+2nd terms?)
287    ideal m_syzLeads;
288
289    /// output (syzygy) tails
290    ideal m_syzTails;
291
292    /// Bitmask for variables occuring in leading terms
293    const CLCM m_lcm;
294
295    /// Divisor finder
296    const CReducerFinder m_div;
297
298    /// for checking tail-terms and makeing them irreducible (wrt m_LS!)
299    CReducerFinder m_checker;
300
301    /*mutable?*/ ideal m_LS; ///< leading syzygy terms used for reducing syzygy tails
302
303    /*
304    // need more data here:
305    // (m_idLeads : m_tailterm) = (m, pos, compl), s.th: compl * m_tailterm divides m_idLeads[pos]
306    // but resulting sysygy compl * gen(pos) should not be in
307    // Idea: extend CReducerFinder??!!
308    struct CTailTerm
309    {
310      const poly m_tailterm;
311     
312      const CReducerFinder m_reducers; // positions are labels (in m_idLeads)...
313      // compl - to be computed if needed?
314
315      CTailTerm(const poly tt, const CReducerFinder reds): m_tailterm(tt), m_reducers(reds) {}
316    };
317
318    typedef std::vector<const CTailTerm*> TTail;
319    typedef std::vector<TTail> TTailTerms;
320   
321    TTailTerms m_idTailTerms;
322    */
323};
324
325
326// The following wrappers are just for testing separate functions on highest level (within schreyer.lib)
327
328static inline void ComputeSyzygy(const ideal L, const ideal T, ideal& LL, ideal& TT, const SchreyerSyzygyComputationFlags A)
329{
330  SchreyerSyzygyComputation syz(L, T, A);
331  syz.ComputeSyzygy();
332  syz.ReadOffResult(LL, TT);
333}
334
335static inline ideal ComputeLeadingSyzygyTerms(const ideal& L, const SchreyerSyzygyComputationFlags A)
336{
337  SchreyerSyzygyComputation syz(L, NULL, A);
338  syz.ComputeLeadingSyzygyTerms(false);
339  ideal LL, TT;
340  syz.ReadOffResult(LL, TT);
341  return LL; // assume TT is NULL!
342}
343
344static inline ideal Compute2LeadingSyzygyTerms(const ideal& L, const SchreyerSyzygyComputationFlags A)
345{
346  SchreyerSyzygyComputation syz(L, NULL, A);
347  syz.ComputeLeadingSyzygyTerms(true);
348  ideal LL, TT;
349  syz.ReadOffResult(LL, TT);
350  return LL; // assume TT is NULL!
351}
352
353static inline poly FindReducer(poly product, poly syzterm,
354                               ideal L, ideal LS, const SchreyerSyzygyComputationFlags A)
355{
356  SchreyerSyzygyComputation syz(L, NULL, LS, A);
357  return syz._FindReducer(product, syzterm);
358}
359
360static inline poly TraverseTail(poly multiplier, poly tail, 
361                                ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
362{
363  SchreyerSyzygyComputation syz(L, T, LS, A);
364  return syz.TraverseTail(multiplier, tail);
365}
366
367static inline poly ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck,
368                              ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
369{
370  SchreyerSyzygyComputation syz(L, T, LS, A);
371  return syz.ReduceTerm(multiplier, term4reduction, syztermCheck);
372}
373
374
375static inline poly SchreyerSyzygyNF(poly syz_lead, poly syz_2,
376                                    ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
377{
378  SchreyerSyzygyComputation syz(L, T, LS, A);
379  return syz.SchreyerSyzygyNF(syz_lead, syz_2);
380}
381
382END_NAMESPACE
383   
384END_NAMESPACE_SINGULARXX
385
386#endif
387/* #ifndef SYZEXTRA_H */
388
389// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
390
Note: See TracBrowser for help on using the repository browser.