source: git/dyn_modules/syzextra/syzextra.h @ 1cf13b

jengelh-datetimespielwiese
Last change on this file since 1cf13b was 1cf13b, checked in by Oleksandr Motsak <motsak@…>, 9 years ago
Traverse API redesign + avoid multiplication as far as possible add/chg: TraverseNF similar to SchreyerSyzygyNF add/chg: use TraverseTail(mult, int tail_index) everywhere add: usage of CReducerFinder::FindReducer controlled by NOPRODUCT macro define add: _p_LmDivisibleByNoComp, CReducerFinder::FindReducer for products NOTE: needs p_GetShortExpVector for 'products'
  • Property mode set to 100644
File size: 9.9 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 CReducerFinder: public SchreyerSyzygyComputationFlags
115{
116  private:
117    class CLeadingTerm
118    {
119      public: 
120        CLeadingTerm(unsigned int id,  const poly p, const ring);
121
122      private:
123        CLeadingTerm();
124
125      public:
126
127        const unsigned long m_sev; ///< not short exp. vector
128        // NOTE/TODO: either of the following should be enough:
129        const unsigned int  m_label; ///< index in the main L[] + 1
130        const poly          m_lt; ///< the leading term itself L[label-1]
131    };
132
133    typedef long TComponentKey;
134    typedef std::vector<const CLeadingTerm*> TReducers;
135    typedef std::map< TComponentKey, TReducers> CReducersHash;
136   
137  public:
138    /// goes over all leading terms
139    CReducerFinder(const ideal L, const SchreyerSyzygyComputationFlags& flags);
140
141    void Initialize(const ideal L);
142
143    ~CReducerFinder();
144
145    // TODO: save shortcut (syz: |-.->) LM(LM(m) * "t") -> syz?   
146    poly FindReducer(const poly product, const poly syzterm, const CReducerFinder& checker) const;
147
148    bool IsDivisible(const poly q) const;
149
150    bool IsNonempty() const { return !m_hash.empty(); }
151
152    poly FindReducer(const poly multiplier, const poly monom, const poly syzterm, const CReducerFinder& checker) const;
153   
154#ifndef NDEBUG
155    void DebugPrint() const;
156#endif
157   
158  private:
159    ideal m_L; ///< only for debug
160
161    CReducersHash m_hash; // can also be replaced with a vector indexed by components
162};
163
164
165
166/** @class SchreyerSyzygyComputation syzextra.h
167 *
168 * Computing syzygies after Schreyer
169 *
170 * Storing/accumulating data during the computation requires some global
171 * object, like this class. Ideally the above global functions should not
172 * be used in favour of this class.
173 *
174 * @sa Schreyer Syzygy Computation Paper & Talk & Python prototype
175 */
176class SchreyerSyzygyComputation: public SchreyerSyzygyComputationFlags
177{
178  friend class CLCM;
179  friend class CReducerFinder;
180 
181  public:
182
183    /// Construct a global object for given input data (separated into leads & tails)
184    SchreyerSyzygyComputation(const ideal idLeads, const ideal idTails, const SchreyerSyzygyComputationFlags setting):
185        SchreyerSyzygyComputationFlags(setting),
186        m_idLeads(idLeads), m_idTails(idTails), 
187        m_syzLeads(NULL), m_syzTails(NULL), m_LS(NULL),
188        m_lcm(m_idLeads, setting), m_div(m_idLeads, setting), m_checker(NULL, setting)
189    {
190    }
191
192    /// Construct a global object for given input data (separated into leads & tails)
193    SchreyerSyzygyComputation(const ideal idLeads, const ideal idTails, const ideal syzLeads, const SchreyerSyzygyComputationFlags setting):
194        SchreyerSyzygyComputationFlags(setting),
195        m_idLeads(idLeads), m_idTails(idTails), 
196        m_syzLeads(syzLeads), m_syzTails(NULL), m_LS(syzLeads), 
197        m_lcm(m_idLeads, setting), m_div(m_idLeads, setting), m_checker(NULL, setting)
198    {
199      if( __TAILREDSYZ__ && !__IGNORETAILS__ && syzLeads != NULL )
200        m_checker.Initialize(syzLeads);
201    }
202
203   
204    /// Destructor should not destruct the resulting m_syzLeads, m_syzTails.
205    ~SchreyerSyzygyComputation(){ CleanUp(); }
206
207    /// Read off the results while detaching them from this object
208    /// NOTE: no copy!
209    inline void ReadOffResult(ideal& syzL, ideal& syzT)
210    {
211      syzL = m_syzLeads; syzT = m_syzTails; 
212
213      m_syzLeads = m_syzTails = NULL; // m_LS ?
214    }
215   
216    /// The main driver function: computes
217    void ComputeSyzygy();
218
219    /// Computes Syz(leads) or only LEAD of it.
220    /// The result is stored into m_syzLeads
221    void ComputeLeadingSyzygyTerms(bool bComputeSecondTerms = true);
222
223    poly SchreyerSyzygyNF(const poly syz_lead, poly syz_2 = NULL) const;
224
225    poly TraverseTail(poly multiplier, const int tail) const;
226
227    // called only from above and from outside (for testing)
228    poly TraverseTail(poly multiplier, poly tail) const;
229
230    // TODO: save shortcut (syz: |-.->) LM(m) * "t" -> ?
231    poly ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck) const;
232
233    //
234    poly TraverseNF(const poly syz_lead, const poly syz_2 = NULL) const;
235   
236  public:
237    /// just for testing via the wrapper below
238    inline poly _FindReducer(const poly product, const poly syzterm) const
239        { return m_div.FindReducer(product, syzterm, m_checker); } 
240   
241  protected:
242
243    /// just leading terms
244    ideal Compute1LeadingSyzygyTerms();
245
246    /// leading + second terms
247    ideal Compute2LeadingSyzygyTerms();
248
249    /// Clean up all the accumulated data
250    void CleanUp() {}
251
252  private:
253    /// input leading terms
254    const ideal m_idLeads;
255
256    /// input tails
257    const ideal m_idTails;
258
259    /// output (syzygy) leading terms (+2nd terms?)
260    ideal m_syzLeads;
261
262    /// output (syzygy) tails
263    ideal m_syzTails;
264
265    /// Bitmask for variables occuring in leading terms
266    const CLCM m_lcm;
267
268    /// Divisor finder
269    const CReducerFinder m_div;
270
271    /// for checking tail-terms and makeing them irreducible (wrt m_LS!)
272    CReducerFinder m_checker;
273
274    /*mutable?*/ ideal m_LS; ///< leading syzygy terms used for reducing syzygy tails
275};
276
277
278// The following wrappers are just for testing separate functions on highest level (within schreyer.lib)
279
280static inline void ComputeSyzygy(const ideal L, const ideal T, ideal& LL, ideal& TT, const SchreyerSyzygyComputationFlags A)
281{
282  SchreyerSyzygyComputation syz(L, T, A);
283  syz.ComputeSyzygy();
284  syz.ReadOffResult(LL, TT);
285}
286
287static inline ideal ComputeLeadingSyzygyTerms(const ideal& L, const SchreyerSyzygyComputationFlags A)
288{
289  SchreyerSyzygyComputation syz(L, NULL, A);
290  syz.ComputeLeadingSyzygyTerms(false);
291  ideal LL, TT;
292  syz.ReadOffResult(LL, TT);
293  return LL; // assume TT is NULL!
294}
295
296static inline ideal Compute2LeadingSyzygyTerms(const ideal& L, const SchreyerSyzygyComputationFlags A)
297{
298  SchreyerSyzygyComputation syz(L, NULL, A);
299  syz.ComputeLeadingSyzygyTerms(true);
300  ideal LL, TT;
301  syz.ReadOffResult(LL, TT);
302  return LL; // assume TT is NULL!
303}
304
305static inline poly FindReducer(poly product, poly syzterm,
306                               ideal L, ideal LS, const SchreyerSyzygyComputationFlags A)
307{
308  SchreyerSyzygyComputation syz(L, NULL, LS, A);
309  return syz._FindReducer(product, syzterm);
310}
311
312static inline poly TraverseTail(poly multiplier, poly tail, 
313                                ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
314{
315  SchreyerSyzygyComputation syz(L, T, LS, A);
316  return syz.TraverseTail(multiplier, tail);
317}
318
319static inline poly ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck,
320                              ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
321{
322  SchreyerSyzygyComputation syz(L, T, LS, A);
323  return syz.ReduceTerm(multiplier, term4reduction, syztermCheck);
324}
325
326
327static inline poly SchreyerSyzygyNF(poly syz_lead, poly syz_2,
328                                    ideal L, ideal T, ideal LS, const SchreyerSyzygyComputationFlags A)
329{
330  SchreyerSyzygyComputation syz(L, T, LS, A);
331  return syz.SchreyerSyzygyNF(syz_lead, syz_2);
332}
333
334END_NAMESPACE
335   
336END_NAMESPACE_SINGULARXX
337
338#endif
339/* #ifndef SYZEXTRA_H */
340
341// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
342
Note: See TracBrowser for help on using the repository browser.