source: git/kernel/tgb_internal.h @ 52f95b

fieker-DuValspielwiese
Last change on this file since 52f95b was 0509a99, checked in by Hans Schoenemann <hannes@…>, 11 years ago
removed kernel/modulop.h
  • Property mode set to 100644
File size: 50.3 KB
RevLine 
[f4adfcb]1#ifndef TGB_INTERNAL_H
2#define TGB_INTERNAL_H
[b553e5]3//!\file tgb_internal.h
[6b9532]4/****************************************
5*  Computer Algebra System SINGULAR     *
6****************************************/
7/*
8 * ABSTRACT: tgb internal .h file
9*/
[f2b5839]10#define USE_NORO 1
[d7cb52]11
[47e836b]12#include <omalloc/omalloc.h>
[d7cb52]13
[f478f5b]14//#define TGB_DEBUG
15#define FULLREDUCTIONS
16#define HANS_IDEA
17//#define HALFREDUCTIONS
18//#define HEAD_BIN
19//#define HOMOGENEOUS_EXAMPLE
20#define REDTAIL_S
21#define PAR_N 100
22#define PAR_N_F4 5000
23#define AC_NEW_MIN 2
24#define AC_FLATTEN 1
25
26//#define FIND_DETERMINISTIC
27//#define REDTAIL_PROT
28//#define QUICK_SPOLY_TEST
[a7d970]29#ifdef USE_NORO
30#define NORO_CACHE 1
31#define NORO_SPARSE_ROWS_PRE 1
32#define NORO_NON_POLY 1
[8120f8]33#include <algorithm>
[a7d970]34#endif
[89b59f]35#ifdef NORO_CACHE
[cc4d094]36//#include <map>
[89b59f]37#include <vector>
38#endif
[1cddd8]39#ifdef HAVE_BOOST_DYNAMIC_BITSET_HPP
[542228]40#define  HAVE_BOOST 1
[1cddd8]41#endif
[2fd387d]42//#define HAVE_BOOST 1
[1cddd8]43//#define USE_STDVECBOOL 1
[26914c]44#ifdef HAVE_BOOST
45#include <vector>
46using boost::dynamic_bitset;
47using std::vector;
48#endif
[4b7049]49#ifdef USE_STDVECBOOL
50#include <vector>
51using std::vector;
52#endif
[47e836b]53#include <stdlib.h>
[f478f5b]54
55#include <polys/monomials/p_polys.h>
56
57#include <kernel/ideals.h>
58#include <polys/monomials/ring.h>
59#include <kernel/febase.h>
60#include <misc/options.h>
[737a68]61#include <kernel/polys.h>
[599326]62#include <kernel/kutil.h>
[8bb03b]63#include <kernel/kInline.h>
[599326]64#include <kernel/kstd1.h>
[210e07]65#include <polys/kbuckets.h>
[f4adfcb]66
[f478f5b]67class PolySimple
68{
[89b59f]69public:
[384455]70  PolySimple(poly p)
71  {
[89b59f]72    impl=p;
73  }
[384455]74  PolySimple()
75  {
[89b59f]76    impl=NULL;
77  }
[384455]78  PolySimple(const PolySimple& a)
79  {
[89b59f]80    //impl=p_Copy(a.impl,currRing);
81    impl=a.impl;
82  }
[384455]83  PolySimple& operator=(const PolySimple& p2)
84  {
[89b59f]85    //p_Delete(&impl,currRing);
86    //impl=p_Copy(p2.impl,currRing);
87    impl=p2.impl;
88    return *this;
89  }
[384455]90  ~PolySimple()
91  {
[89b59f]92    //p_Delete(&impl,currRing);
93  }
[384455]94  bool operator< (const PolySimple& other) const
95  {
[89b59f]96    return pLmCmp(impl,other.impl)<0;
97  }
[384455]98  bool operator==(const PolySimple& other)
99  {
[89b59f]100    return pLmEqual(impl,other.impl);
101  }
102  poly impl;
[384455]103
[89b59f]104};
[5ac8e5]105template<class number_type> class DataNoroCacheNode;
106/*class MonRedRes{
[b16a613]107public:
108  poly p;
109  number coef;
110  BOOLEAN changed;
111  int len;
112  BOOLEAN onlyBorrowed;
113  bool operator<(const MonRedRes& other) const{
114    int cmp=p_LmCmp(p,other.p,currRing);
115    if ((cmp<0)||((cmp==0)&&((onlyBorrowed)&&(!(other.onlyBorrowed))))){
116      return true;
117    } else return false;
118  }
119  DataNoroCacheNode* ref;
120  MonRedRes(){
121    ref=NULL;
122    p=NULL;
123  }
[5ac8e5]124};*/
[384455]125template <class number_type> class MonRedResNP
126{
[e01da4]127public:
128  number coef;
129
130
[5ac8e5]131  DataNoroCacheNode<number_type>* ref;
[384455]132  MonRedResNP()
133  {
[e01da4]134    ref=NULL;
135  }
136};
[384455]137struct sorted_pair_node
138{
[f4adfcb]139  //criterium, which is stable 0. small lcm 1. small i 2. small j
[c72471]140  wlen_type expected_length;
141  poly lcm_of_lm;
[f4adfcb]142  int i;
143  int j;
144  int deg;
[384455]145
146
[f4adfcb]147};
[5ac8e5]148#ifdef NORO_CACHE
149#ifndef NORO_NON_POLY
[384455]150class NoroPlaceHolder
151{
[b16a613]152public:
153  DataNoroCacheNode* ref;
154  number coef;
155};
[5ac8e5]156#endif
157#endif
[f4adfcb]158//static ideal debug_Ideal;
159
160
[384455]161struct poly_list_node
162{
[f4adfcb]163  poly p;
164  poly_list_node* next;
165};
[bddc9d]166
[384455]167struct int_pair_node
168{
[f4adfcb]169  int_pair_node* next;
170  int a;
171  int b;
172};
[384455]173struct monom_poly
174{
[f4adfcb]175  poly m;
176  poly f;
177};
[384455]178struct mp_array_list
179{
[f4adfcb]180  monom_poly* mp;
181  int size;
182  mp_array_list* next;
183};
[b055de9]184
185
[384455]186struct poly_array_list
187{
[f4adfcb]188  poly* p;
189  int size;
190  poly_array_list* next;
191};
[9cbb7a3]192class slimgb_alg
[f4adfcb]193{
[9cbb7a3]194  public:
[86aa6a1]195    slimgb_alg(ideal I, int syz_comp,BOOLEAN F4,int deg_pos);
[384455]196                void introduceDelayedPairs(poly* pa,int s);
[68ae61]197    virtual ~slimgb_alg();
[9108d3]198    void cleanDegs(int lower, int upper);
[4b7049]199#ifndef HAVE_BOOST
200#ifdef USE_STDVECBOOL
201  vector<vector<bool> > states;
202#else
[f4adfcb]203  char** states;
[4b7049]204#endif
205#else
[26914c]206  vector<dynamic_bitset<> > states;
[4b7049]207#endif
[ca086f]208  ideal add_later;
[f4adfcb]209  ideal S;
210  ring r;
211  int* lengths;
[6b4fbf7]212  wlen_type* weighted_lengths;
[f4adfcb]213  long* short_Exps;
214  kStrategy strat;
215  int* T_deg;
216  int* T_deg_full;
217  poly tmp_lm;
218  poly* tmp_pair_lm;
219  sorted_pair_node** tmp_spn;
220  poly* expandS;
221  poly* gcd_of_terms;
222  int_pair_node* soon_free;
223  sorted_pair_node** apairs;
[c72471]224  #if 0
[f4adfcb]225  BOOLEAN* modifiedS;
[c72471]226  #endif
[c481b8]227  #ifdef TGB_RESORT_PAIRS
[c72471]228  bool* replaced;
[c481b8]229  #endif
[f4adfcb]230  poly_list_node* to_destroy;
231  //for F4
232  mp_array_list* F;
233  poly_array_list* F_minus;
234
235  //end for F4
236#ifdef HEAD_BIN
[c5e0e1]237  omBin   HeadBin;
[f4adfcb]238#endif
239  unsigned int reduction_steps;
240  int n;
[6d7605]241  //! array_lengths should be greater equal n;
[625767]242  int syz_comp;
[384455]243  int array_lengths;
[f4adfcb]244  int normal_forms;
245  int current_degree;
246  int Rcounter;
247  int last_index;
248  int max_pairs;
249  int pair_top;
250  int easy_product_crit;
251  int extended_product_crit;
252  int average_length;
[bfcd46]253  int lastDpBlockStart;
[9108d3]254  int lastCleanedDeg;
[86aa6a1]255  int deg_pos;
[f2b5839]256  BOOLEAN use_noro;
257  BOOLEAN use_noro_last_block;
[c57134]258  BOOLEAN isDifficultField;
[a60a21]259  BOOLEAN completed;
[f4adfcb]260  BOOLEAN is_homog;
[9108d3]261  BOOLEAN tailReductions;
[c57134]262  BOOLEAN eliminationProblem;
[f4adfcb]263  BOOLEAN F4_mode;
[d491e3]264  BOOLEAN nc;
[c481b8]265  #ifdef TGB_RESORT_PAIRS
[c72471]266  BOOLEAN used_b;
[c481b8]267  #endif
[384455]268  unsigned long pTotaldegree(poly p)
269  {
[86aa6a1]270      pTest(p);
[99bdcf]271      //assume(pDeg(p,r)==::p_Totaldegree(p,r));
272      assume(((unsigned long)::p_Totaldegree(p,r))==p->exp[deg_pos]);
[86aa6a1]273      return p->exp[deg_pos];
274      //return ::pTotaldegree(p,this->r);
[2ade7a2]275  }
[384455]276  int pTotaldegree_full(poly p)
277  {
[5f4463]278    int rr=0;
[384455]279    while(p)
280    {
[2ade7a2]281      int d=this->pTotaldegree(p);
[5f4463]282      rr=si_max(rr,d);
[2ade7a2]283      pIter(p);
284    }
[5f4463]285    return rr;
[2ade7a2]286  }
[f4adfcb]287};
[384455]288class red_object
289{
[f4adfcb]290 public:
291  kBucket_pt bucket;
292  poly p;
293  unsigned long sev;
[d64382]294  int sugar;
[f4adfcb]295  void flatten();
296  void validate();
[470dd9]297  wlen_type initial_quality;
[f4adfcb]298  void adjust_coefs(number c_r, number c_ac_r);
[9cd599]299  wlen_type guess_quality(slimgb_alg* c);
[f4adfcb]300  int clear_to_poly();
301  void canonicalize();
302};
303
304
305enum calc_state
306  {
307    UNCALCULATED,
[113bb8]308    HASTREP//,
309    //UNIMPORTANT,
[6b4fbf7]310    //SOONTREP
[f4adfcb]311  };
[a41623]312//static BOOLEAN pair_cmp(sorted_pair_node* a,sorted_pair_node* b);
[25061a]313template <class len_type, class set_type>  int pos_helper(kStrategy strat, poly p, len_type len, set_type setL, polyset set);
[321283]314static int add_to_reductors(slimgb_alg* c, poly h, int len, int ecart, BOOLEAN simplified=FALSE);
[f4adfcb]315static int bucket_guess(kBucket* bucket);
316static poly redNFTail (poly h,const int sl,kStrategy strat, int len);
[9cbb7a3]317static poly redNF2 (poly h,slimgb_alg* c , int &len, number&  m,int n=0);
[b75d13]318void free_sorted_pair_node(sorted_pair_node* s, ring r);
[9cbb7a3]319static void shorten_tails(slimgb_alg* c, poly monom);
320static void replace_pair(int & i, int & j, slimgb_alg* c);
321//static sorted_pair_node** add_to_basis(poly h, int i, int j,slimgb_alg* c, int* ip=NULL);
[a41623]322//static void do_this_spoly_stuff(int i,int j,slimgb_alg* c);
[f4adfcb]323//ideal t_rep_gb(ring r,ideal arg_I);
[86aa6a1]324ideal do_t_rep_gb(ring r,ideal arg_I, int syz_comp, BOOLEAN F4_mode,int deg_pos);
[9cbb7a3]325static BOOLEAN has_t_rep(const int & arg_i, const int & arg_j, slimgb_alg* state);
[a41623]326//static int* make_connections(int from, poly bound, slimgb_alg* c);
[9cbb7a3]327static int* make_connections(int from, int to, poly bound, slimgb_alg* c);
328void now_t_rep(const int & arg_i, const int & arg_j, slimgb_alg* c);
[a41623]329//static void soon_t_rep(const int & arg_i, const int & arg_j, slimgb_alg* c);
330//static int pLcmDeg(poly a, poly b);
[25061a]331static int simple_posInS (kStrategy strat, poly p,int len, wlen_type wlen);
[a41623]332//static BOOLEAN find_next_pair(slimgb_alg* c, BOOLEAN go_higher=TRUE);
[9cbb7a3]333
[a41623]334//static sorted_pair_node* pop_pair(slimgb_alg* c);
335//static BOOLEAN no_pairs(slimgb_alg* c);
[9cbb7a3]336void clean_top_of_pair_list(slimgb_alg* c);
337static void super_clean_top_of_pair_list(slimgb_alg* c);
338static BOOLEAN state_is(calc_state state, const int & i, const int & j, slimgb_alg* c);
[8492cb9]339static BOOLEAN pair_better(sorted_pair_node* a,sorted_pair_node* b, slimgb_alg* c=NULL);
[b75d13]340static int tgb_pair_better_gen(const void* ap,const void* bp);
[f4adfcb]341static poly redTailShort(poly h, kStrategy strat);
342static poly gcd_of_terms(poly p, ring r);
[9cbb7a3]343static BOOLEAN extended_product_criterion(poly p1, poly gcd1, poly p2, poly gcd2, slimgb_alg* c);
[a41623]344//static poly kBucketGcd(kBucket* b, ring r);
[9cbb7a3]345static void multi_reduction(red_object* los, int & losl, slimgb_alg* c);
[e9f4c9]346int slim_nsize(number n, ring r);
[9cbb7a3]347sorted_pair_node* quick_pop_pair(slimgb_alg* c);
348sorted_pair_node* top_pair(slimgb_alg* c);
[0f2374]349sorted_pair_node** add_to_basis_ideal_quotient(poly h, slimgb_alg* c, int* ip);//, BOOLEAN new_pairs=TRUE);
[9cbb7a3]350sorted_pair_node**  spn_merge(sorted_pair_node** p, int pn,sorted_pair_node **q, int qn,slimgb_alg* c);
[b75d13]351int kFindDivisibleByInS_easy(kStrategy strat,const red_object & obj);
352int tgb_pair_better_gen2(const void* ap,const void* bp);
353int kFindDivisibleByInS_easy(kStrategy strat,poly p, long sev);
[9cbb7a3]354//static int quality(poly p, int len, slimgb_alg* c);
[f4adfcb]355/**
356   makes on each red_object in a region a single_step
357 **/
[384455]358class reduction_step
359{
[f4adfcb]360 public:
361  /// we assume hat all occuring red_objects have same lm, and all
362  /// occ. lm's in r[l...u] are the same, only reductor does not occur
363  virtual void reduce(red_object* r, int l, int u);
364  //int reduction_id;
365  virtual ~reduction_step();
[9cbb7a3]366  slimgb_alg* c;
[f4adfcb]367  int reduction_id;
368};
[384455]369class simple_reducer:public reduction_step
370{
[f4adfcb]371 public:
372  poly p;
373  kBucket_pt fill_back;
374  int p_len;
[321283]375  int reducer_deg;
[5f4463]376  simple_reducer(poly pp, int pp_len,int pp_reducer_deg, slimgb_alg* pp_c =NULL)
[384455]377  {
[5f4463]378    this->p=pp;
379    this->reducer_deg=pp_reducer_deg;
380    assume(pp_len==pLength(pp));
381    this->p_len=pp_len;
382    this->c=pp_c;
[f4adfcb]383  }
384  virtual void pre_reduce(red_object* r, int l, int u);
385  virtual void reduce(red_object* r, int l, int u);
386  ~simple_reducer();
387
[bddc9d]388
[d2d842]389  virtual void do_reduce(red_object & ro);
[f4adfcb]390};
[36b1aa]391
[f4adfcb]392//class sum_canceling_reducer:public reduction_step {
393//  void reduce(red_object* r, int l, int u);
394//};
[384455]395struct find_erg
396{
[f4adfcb]397  poly expand;
398  int expand_length;
399  int to_reduce_u;
400  int to_reduce_l;
401  int reduce_by;//index of reductor
402  BOOLEAN fromS;//else from los
403
404};
405
[9cbb7a3]406static void multi_reduce_step(find_erg & erg, red_object* r, slimgb_alg* c);
[a41623]407//static void finalize_reduction_step(reduction_step* r);
[b055de9]408
[384455]409template <class len_type, class set_type>  int pos_helper(kStrategy strat, poly p, len_type len, set_type setL, polyset set)
410{
[9cd599]411  //Print("POSHELER:%d",sizeof(wlen_type));
[25061a]412  int length=strat->sl;
413  int i;
414  int an = 0;
415  int en= length;
416
417  if ((len>setL[length])
418      || ((len==setL[length]) && (pLmCmp(set[length],p)== -1)))
419    return length+1;
420
421  loop
422  {
423    if (an >= en-1)
424    {
425      if ((len<setL[an])
426          || ((len==setL[an]) && (pLmCmp(set[an],p) == 1))) return an;
427      return en;
428    }
429    i=(an+en) / 2;
430    if ((len<setL[i])
431        || ((len==setL[i]) && (pLmCmp(set[i],p) == 1))) en=i;
432    //else if ((len>setL[i])
433    //|| ((len==setL[i]) && (pLmCmp(set[i],p) == -1))) an=i;
434    else an=i;
435  }
436
437}
[a7d970]438#ifdef NORO_CACHE
[95692a]439#define slim_prec_cast(a) (unsigned int) (unsigned long) (a)
[5ac8e5]440#define F4mat_to_number_type(a) (number_type) slim_prec_cast(a)
[a7d970]441typedef unsigned short tgb_uint16;
442typedef unsigned char tgb_uint8;
443typedef unsigned int tgb_uint32;
[384455]444class NoroCacheNode
445{
[a7d970]446public:
447  NoroCacheNode** branches;
448  int branches_len;
[b055de9]449
[384455]450
451  NoroCacheNode()
452  {
[a7d970]453    branches=NULL;
454    branches_len=0;
[384455]455
[a7d970]456  }
[384455]457  NoroCacheNode* setNode(int branch, NoroCacheNode* node)
458  {
459    if (branch>=branches_len)
460    {
461      if (branches==NULL)
462      {
[a7d970]463        branches_len=branch+1;
464        branches_len=si_max(branches_len,3);
[0661d42]465        branches=(NoroCacheNode**) omAlloc(branches_len*sizeof(NoroCacheNode*));
[a7d970]466        int i;
[384455]467        for(i=0;i<branches_len;i++)
468        {
[a7d970]469          branches[i]=NULL;
470        }
[384455]471      }
472      else
473      {
[a7d970]474        int branches_len_old=branches_len;
475        branches_len=branch+1;
476        branches=(NoroCacheNode**) omrealloc(branches,branches_len*sizeof(NoroCacheNode*));
477        int i;
[384455]478        for(i=branches_len_old;i<branches_len;i++)
479        {
[a7d970]480          branches[i]=NULL;
481        }
482      }
483    }
484    assume(branches[branch]==NULL);
485    branches[branch]=node;
486    return node;
487  }
[384455]488  NoroCacheNode* getBranch(int branch)
489  {
[a7d970]490    if (branch<branches_len) return branches[branch];
491    return NULL;
492  }
[384455]493  virtual ~NoroCacheNode()
494  {
[a7d970]495    int i;
[384455]496    for(i=0;i<branches_len;i++)
497    {
[a7d970]498      delete branches[i];
499    }
500    omfree(branches);
501  }
[384455]502  NoroCacheNode* getOrInsertBranch(int branch)
503  {
[a7d970]504    if ((branch<branches_len)&&(branches[branch]))
505      return branches[branch];
[384455]506    else
507    {
[a7d970]508      return setNode(branch,new NoroCacheNode());
509    }
510  }
511};
512class DenseRow{
513public:
514  number* array;
515  int begin;
516  int end;
[384455]517  DenseRow()
518  {
[a7d970]519    array=NULL;
520  }
[384455]521  ~DenseRow()
522  {
[a7d970]523    omfree(array);
524  }
525};
[384455]526template <class number_type> class SparseRow
527{
[a7d970]528public:
529  int* idx_array;
[5ac8e5]530  number_type* coef_array;
[a7d970]531  int len;
[384455]532  SparseRow()
533  {
[a7d970]534    len=0;
535    idx_array=NULL;
536    coef_array=NULL;
537  }
[384455]538  SparseRow<number_type>(int n)
539  {
[a7d970]540    len=n;
[44fac1]541    idx_array=(int*) omAlloc(n*sizeof(int));
542    coef_array=(number_type*) omAlloc(n*sizeof(number_type));
[a7d970]543  }
[384455]544  SparseRow<number_type>(int n, const number_type* source)
545  {
[3a2985]546    len=n;
547    idx_array=NULL;
[44fac1]548    coef_array=(number_type*) omAlloc(n*sizeof(number_type));
[3a2985]549    memcpy(coef_array,source,n*sizeof(number_type));
550  }
[384455]551  ~SparseRow<number_type>()
552  {
[a7d970]553    omfree(idx_array);
554    omfree(coef_array);
555  }
556};
[b055de9]557
[384455]558template <class number_type> class DataNoroCacheNode:public NoroCacheNode
559{
[a7d970]560public:
[384455]561
[a7d970]562  int value_len;
563  poly value_poly;
564  #ifdef NORO_SPARSE_ROWS_PRE
[5ac8e5]565  SparseRow<number_type>* row;
[a7d970]566  #else
567  DenseRow* row;
568  #endif
569  int term_index;
[384455]570  DataNoroCacheNode(poly p, int len)
571  {
[a7d970]572    value_len=len;
573    value_poly=p;
574    row=NULL;
575    term_index=-1;
576  }
577  #ifdef NORO_SPARSE_ROWS_PRE
[384455]578  DataNoroCacheNode(SparseRow<number_type>* row)
579  {
[a7d970]580    if (row!=NULL)
581      value_len=row->len;
582    else
583      value_len=0;
584    value_poly=NULL;
585    this->row=row;
586    term_index=-1;
587  }
588  #endif
[384455]589  ~DataNoroCacheNode()
590  {
[a7d970]591    //p_Delete(&value_poly,currRing);
592    if (row) delete row;
593  }
594};
[384455]595template <class number_type> class TermNoroDataNode
596{
[abce2e]597public:
[5ac8e5]598  DataNoroCacheNode<number_type>* node;
[abce2e]599  poly t;
600};
[5ac8e5]601
[384455]602template <class number_type> class NoroCache
603{
[a7d970]604public:
605  poly temp_term;
[5ac8e5]606#ifndef NORO_NON_POLY
[a7d970]607  void evaluatePlaceHolder(number* row,std::vector<NoroPlaceHolder>& place_holders);
608  void evaluateRows();
609  void evaluateRows(int level, NoroCacheNode* node);
[5ac8e5]610#endif
611  void collectIrreducibleMonomials( std::vector<DataNoroCacheNode<number_type>* >& res);
612  void collectIrreducibleMonomials(int level,  NoroCacheNode* node, std::vector<DataNoroCacheNode<number_type>* >& res);
613
[a7d970]614#ifdef NORO_RED_ARRAY_RESERVER
615  int reserved;
616  poly* recursionPolyBuffer;
617#endif
618  static const int backLinkCode=-222;
[384455]619  DataNoroCacheNode<number_type>* insert(poly term, poly nf, int len)
620  {
[a7d970]621    //assume(impl.find(p_Copy(term,currRing))==impl.end());
622    //assume(len==pLength(nf));
[47e836b]623    assume(n_IsOne(p_GetCoeff(term,currRing),currRing->cf));
[384455]624    if (term==nf)
625    {
[a7d970]626      term=p_Copy(term,currRing);
627
628      ressources.push_back(term);
629      nIrreducibleMonomials++;
630      return treeInsertBackLink(term);
[384455]631
632    }
633    else
634    {
635      if (nf)
636      {
[a7d970]637        //nf=p_Copy(nf,currRing);
638        assume(p_LmCmp(nf,term,currRing)==-1);
639        ressources.push_back(nf);
640      }
641      return treeInsert(term,nf,len);
[384455]642
[a7d970]643    }
[384455]644
[a7d970]645    //impl[term]=std::pair<PolySimple,int> (nf,len);
646  }
647  #ifdef NORO_SPARSE_ROWS_PRE
[384455]648  DataNoroCacheNode<number_type>* insert(poly term, SparseRow<number_type>* srow)
649  {
[a7d970]650    //assume(impl.find(p_Copy(term,currRing))==impl.end());
651    //assume(len==pLength(nf));
652
653      return treeInsert(term,srow);
[384455]654
655
[a7d970]656    //impl[term]=std::pair<PolySimple,int> (nf,len);
657  }
658  #endif
[2e4ec14]659  DataNoroCacheNode<number_type>* insertAndTransferOwnerShip(poly t, ring /*r*/)
[384455]660  {
[a7d970]661    ressources.push_back(t);
[5ac8e5]662    DataNoroCacheNode<number_type>* res=treeInsertBackLink(t);
[a7d970]663    res->term_index=nIrreducibleMonomials;
664    nIrreducibleMonomials++;
665    return res;
666  }
667  poly lookup(poly term, BOOLEAN& succ, int & len);
[5ac8e5]668  DataNoroCacheNode<number_type>* getCacheReference(poly term);
[384455]669  NoroCache()
670  {
[a7d970]671    buffer=NULL;
672#ifdef NORO_RED_ARRAY_RESERVER
673    reserved=0;
[0661d42]674    recursionPolyBuffer=(poly*)omAlloc(1000000*sizeof(poly));
[a7d970]675#endif
676    nIrreducibleMonomials=0;
677    nReducibleMonomials=0;
678    temp_term=pOne();
[7b2896]679    tempBufferSize=3000;
[0661d42]680    tempBuffer=omAlloc(tempBufferSize);
[7b2896]681  }
[384455]682  void ensureTempBufferSize(size_t size)
683  {
684    if (tempBufferSize<size)
685    {
[7b2896]686      tempBufferSize=2*size;
[44fac1]687      omFree(tempBuffer);
[0661d42]688      tempBuffer=omAlloc(tempBufferSize);
[7b2896]689    }
[a7d970]690  }
691#ifdef NORO_RED_ARRAY_RESERVER
[384455]692  poly* reserve(int n)
693  {
[a7d970]694    poly* res=recursionPolyBuffer+reserved;
695    reserved+=n;
696    return res;
697  }
[384455]698  void free(int n)
699  {
[a7d970]700    reserved-=n;
701  }
702#endif
[384455]703  ~NoroCache()
704  {
[a7d970]705    int s=ressources.size();
706    int i;
[384455]707    for(i=0;i<s;i++)
708    {
[a7d970]709      p_Delete(&ressources[i].impl,currRing);
710    }
711    p_Delete(&temp_term,currRing);
712#ifdef NORO_RED_ARRAY_RESERVER
713    omfree(recursionPolyBuffer);
714#endif
[44fac1]715   omFree(tempBuffer);
[a7d970]716  }
[384455]717
[a7d970]718  int nIrreducibleMonomials;
719  int nReducibleMonomials;
[7b2896]720  void* tempBuffer;
721  size_t tempBufferSize;
[a7d970]722protected:
[384455]723  DataNoroCacheNode<number_type>* treeInsert(poly term,poly nf,int len)
724  {
[a7d970]725    int i;
726    nReducibleMonomials++;
[1f637e]727    int nvars=(currRing->N);
[a7d970]728    NoroCacheNode* parent=&root;
[384455]729    for(i=1;i<nvars;i++)
730    {
[a7d970]731      parent=parent->getOrInsertBranch(p_GetExp(term,i,currRing));
732    }
[5ac8e5]733    return (DataNoroCacheNode<number_type>*) parent->setNode(p_GetExp(term,nvars,currRing),new DataNoroCacheNode<number_type>(nf,len));
[a7d970]734  }
735  #ifdef NORO_SPARSE_ROWS_PRE
[384455]736  DataNoroCacheNode<number_type>* treeInsert(poly term,SparseRow<number_type>* srow)
737  {
[a7d970]738    int i;
739    nReducibleMonomials++;
[1f637e]740    int nvars=(currRing->N);
[a7d970]741    NoroCacheNode* parent=&root;
[384455]742    for(i=1;i<nvars;i++)
743    {
[a7d970]744      parent=parent->getOrInsertBranch(p_GetExp(term,i,currRing));
745    }
[5ac8e5]746    return (DataNoroCacheNode<number_type>*) parent->setNode(p_GetExp(term,nvars,currRing),new DataNoroCacheNode<number_type>(srow));
[a7d970]747  }
748  #endif
[384455]749  DataNoroCacheNode<number_type>* treeInsertBackLink(poly term)
750  {
[a7d970]751    int i;
[1f637e]752    int nvars=(currRing->N);
[a7d970]753    NoroCacheNode* parent=&root;
[384455]754    for(i=1;i<nvars;i++)
755    {
[a7d970]756      parent=parent->getOrInsertBranch(p_GetExp(term,i,currRing));
757    }
[5ac8e5]758    return (DataNoroCacheNode<number_type>*) parent->setNode(p_GetExp(term,nvars,currRing),new DataNoroCacheNode<number_type>(term,backLinkCode));
[a7d970]759  }
[384455]760
[a7d970]761  //@TODO descruct nodes;
762  typedef std::vector<PolySimple> poly_vec;
763  poly_vec ressources;
764  //typedef std::map<PolySimple,std::pair<PolySimple,int> > cache_map;
765  //cache_map impl;
766  NoroCacheNode root;
767  number* buffer;
768};
[5ac8e5]769template<class number_type> SparseRow<number_type> * noro_red_to_non_poly_t(poly p, int &len, NoroCache<number_type>* cache,slimgb_alg* c);
770template<class number_type> MonRedResNP<number_type> noro_red_mon_to_non_poly(poly t,  NoroCache<number_type> * cache,slimgb_alg* c)
771{
772  MonRedResNP<number_type> res_holder;
773
774
775    DataNoroCacheNode<number_type>* ref=cache->getCacheReference(t);
[384455]776    if (ref!=NULL)
777    {
[5ac8e5]778      res_holder.coef=p_GetCoeff(t,c->r);
[384455]779
[5ac8e5]780      res_holder.ref=ref;
781      p_Delete(&t,c->r);
782      return res_holder;
783    }
[384455]784
[5ac8e5]785  unsigned long sev=p_GetShortExpVector(t,currRing);
786  int i=kFindDivisibleByInS_easy(c->strat,t,sev);
[384455]787  if (i>=0)
788  {
[5ac8e5]789    number coef_bak=p_GetCoeff(t,c->r);
790
[47e836b]791    p_SetCoeff(t,n_Init(1,c->r->cf),c->r);
792    assume(n_IsOne(p_GetCoeff(c->strat->S[i],c->r),c->r->cf));
[5ac8e5]793    number coefstrat=p_GetCoeff(c->strat->S[i],c->r);
794
795
796    poly exp_diff=cache->temp_term;
797    p_ExpVectorDiff(exp_diff,t,c->strat->S[i],c->r);
[47e836b]798    p_SetCoeff(exp_diff,n_Neg(n_Invers(coefstrat,c->r->cf),c->r->cf),c->r);
[5ac8e5]799    p_Setm(exp_diff,c->r);
800    assume(c->strat->S[i]!=NULL);
801
802    poly res;
803    res=pp_Mult_mm(pNext(c->strat->S[i]),exp_diff,c->r);
804
805    int len=c->strat->lenS[i]-1;
806    SparseRow<number_type>* srow;
807    srow=noro_red_to_non_poly_t<number_type>(res,len,cache,c);
808    ref=cache->insert(t,srow);
809    p_Delete(&t,c->r);
810
811
812    res_holder.coef=coef_bak;
813    res_holder.ref=ref;
814    return res_holder;
815
816  } else {
817    number coef_bak=p_GetCoeff(t,c->r);
[47e836b]818    number one=n_Init(1, c->r->cf);
[5ac8e5]819    p_SetCoeff(t,one,c->r);
[384455]820
[5ac8e5]821    res_holder.ref=cache->insertAndTransferOwnerShip(t,c->r);
822    assume(res_holder.ref!=NULL);
823    res_holder.coef=coef_bak;
[384455]824
[5ac8e5]825    return res_holder;
[384455]826
[5ac8e5]827  }
828
829}
830/*
[384455]831poly tree_add(poly* a,int begin, int end,ring r)
832{
[5ac8e5]833  int d=end-begin;
[384455]834  switch(d)
835  {
[5ac8e5]836    case 0:
837      return NULL;
838    case 1:
839      return a[begin];
840    case 2:
841      return p_Add_q(a[begin],a[begin+1],r);
842    default:
843      int s=d/2;
844      return p_Add_q(tree_add(a,begin,begin+s,r),tree_add(a,begin+s,end,r),r);
845  }
846}
847*/
[d7cb52]848#ifdef __GNUC__
849#define LIKELY(expression) (__builtin_expect(!!(expression), 1))
850#define UNLIKELY(expression) (__builtin_expect(!!(expression), 0))
851#else
852#define LIKELY(expression) (expression)
853#define UNLIKELY(expression) (expression)
854#endif
855
856template<class number_type> SparseRow<number_type>* convert_to_sparse_row(number_type* temp_array,int temp_size,int non_zeros){
857SparseRow<number_type>* res=new SparseRow<number_type>(non_zeros);
[74802b]858//int pos=0;
[8120f8]859//Print("denseness:%f\n",((double) non_zeros/(double) temp_size));
[74802b]860number_type* it_coef=res->coef_array;
861int* it_idx=res->idx_array;
[d7cb52]862#if 0
863for(i=0;i<cache->nIrreducibleMonomials;i++){
864  if (!(0==temp_array[i])){
[384455]865
[d7cb52]866    res->idx_array[pos]=i;
867    res->coef_array[pos]=temp_array[i];
868
869    pos++;
870    non_zeros--;
871    if (non_zeros==0) break;
872  }
[384455]873
[d7cb52]874}
875#else
876int64* start=(int64*) ((void*)temp_array);
877int64* end;
878const int multiple=sizeof(int64)/sizeof(number_type);
879if (temp_size==0) end=start;
880
881else
[384455]882{
[d7cb52]883  int temp_size_rounded=temp_size+(multiple-(temp_size%multiple));
884  assume(temp_size_rounded>=temp_size);
885  assume(temp_size_rounded%multiple==0);
886  assume(temp_size_rounded<temp_size+multiple);
887  number_type* nt_end=temp_array+temp_size_rounded;
888  end=(int64*)((void*)nt_end);
889}
890int64* it=start;
[384455]891while(it!=end)
892{
893  if UNLIKELY((*it)!=0)
894  {
[d7cb52]895    int small_i;
896    const int temp_index=((number_type*)((void*) it))-temp_array;
897    const int bound=temp_index+multiple;
[74802b]898    number_type c;
[384455]899    for(small_i=temp_index;small_i<bound;small_i++)
900    {
901      if((c=temp_array[small_i])!=0)
902      {
[74802b]903        //res->idx_array[pos]=small_i;
904        //res->coef_array[pos]=temp_array[small_i];
905        (*(it_idx++))=small_i;
906        (*(it_coef++))=c;
907        //pos++;
[d7cb52]908        non_zeros--;
[384455]909
[d7cb52]910      }
[74802b]911      if UNLIKELY(non_zeros==0) break;
[d7cb52]912    }
[384455]913
[d7cb52]914  }
915  ++it;
916}
917#endif
918return res;
919}
[2e4ec14]920#ifdef NDEBUG
921template <class number_type> void add_coef_times_sparse(number_type* const temp_array,
922int /*temp_size*/,SparseRow<number_type>* row, number coef)
923#else
[b66eeb]924template <class number_type> void add_coef_times_sparse(number_type* const temp_array,
[384455]925int temp_size,SparseRow<number_type>* row, number coef)
[2e4ec14]926#endif
[384455]927{
[74802b]928  int j;
[8120f8]929  number_type* const coef_array=row->coef_array;
930  int* const idx_array=row->idx_array;
931  const int len=row->len;
[b66eeb]932  tgb_uint32 buffer[256];
[47e836b]933  const tgb_uint32 prime=n_GetChar(currRing->cf);
[b66eeb]934  const tgb_uint32 c=F4mat_to_number_type(coef);
[40a823]935  assume(!(n_IsZero(coef,currRing->cf)));
[384455]936  for(j=0;j<len;j=j+256)
937  {
[b66eeb]938    const int bound=std::min(j+256,len);
939    int i;
940    int bpos=0;
[384455]941    for(i=j;i<bound;i++)
942    {
[b66eeb]943      buffer[bpos++]=coef_array[i];
944    }
945    int bpos_bound=bound-j;
[384455]946    for(i=0;i<bpos_bound;i++)
947    {
[b66eeb]948       buffer[i]*=c;
949     }
[384455]950    for(i=0;i<bpos_bound;i++)
951    {
[b66eeb]952       buffer[i]=buffer[i]%prime;
953    }
954    bpos=0;
[384455]955    for(i=j;i<bound;i++)
956    {
[b66eeb]957      int idx=idx_array[i];
958      assume(bpos<256);
[40a823]959      assume(!(n_IsZero((number)(long) buffer[bpos],currRing->cf)));
[47e836b]960      temp_array[idx]=F4mat_to_number_type(n_Add((number)(long) temp_array[idx], (number)(long) buffer[bpos++],currRing->cf));
[b66eeb]961      assume(idx<temp_size);
962    }
[384455]963
[74802b]964  }
965}
[2e4ec14]966#ifdef NDEBUG
967template <class number_type> void add_coef_times_dense(number_type* const temp_array,
968int /*temp_size*/,const number_type* row, int len,number coef)
969#else
[3a2985]970template <class number_type> void add_coef_times_dense(number_type* const temp_array,
[384455]971int temp_size,const number_type* row, int len,number coef)
[2e4ec14]972#endif
[384455]973{
[3a2985]974  int j;
975  const number_type* const coef_array=row;
976  //int* const idx_array=row->idx_array;
977  //const int len=temp_size;
978  tgb_uint32 buffer[256];
[47e836b]979  const tgb_uint32 prime=n_GetChar(currRing->cf);
[3a2985]980  const tgb_uint32 c=F4mat_to_number_type(coef);
[40a823]981  assume(!(n_IsZero(coef,currRing->cf)));
[384455]982  for(j=0;j<len;j=j+256)
983  {
[3a2985]984    const int bound=std::min(j+256,len);
985    int i;
986    int bpos=0;
[384455]987    for(i=j;i<bound;i++)
988    {
[3a2985]989      buffer[bpos++]=coef_array[i];
990    }
991    int bpos_bound=bound-j;
[384455]992    for(i=0;i<bpos_bound;i++)
993    {
[3a2985]994       buffer[i]*=c;
995     }
[384455]996    for(i=0;i<bpos_bound;i++)
997    {
[3a2985]998       buffer[i]=buffer[i]%prime;
999    }
1000    bpos=0;
[384455]1001    for(i=j;i<bound;i++)
1002    {
[3a2985]1003      //int idx=idx_array[i];
1004      assume(bpos<256);
1005      //assume(!(npIsZero((number) buffer[bpos])));
[47e836b]1006      temp_array[i]=F4mat_to_number_type(n_Add((number)(long) temp_array[i], (number)(long) buffer[bpos++],currRing->cf));
[3a2985]1007      assume(i<temp_size);
1008    }
[384455]1009
[3a2985]1010  }
1011}
[2e4ec14]1012#ifdef NDEBUG
1013template <class number_type> void add_dense(number_type* const temp_array,
1014int /*temp_size*/,const number_type* row, int len)
1015#else
[3a2985]1016template <class number_type> void add_dense(number_type* const temp_array,
[384455]1017int temp_size,const number_type* row, int len)
[2e4ec14]1018#endif
[384455]1019{
[3a2985]1020  //int j;
[a41623]1021  //const number_type* const coef_array=row;
[3a2985]1022  //int* const idx_array=row->idx_array;
1023  //const int len=temp_size;
[a41623]1024  //tgb_uint32 buffer[256];
1025  //const tgb_uint32 prime=npPrimeM;
[3a2985]1026  //const tgb_uint32 c=F4mat_to_number_type(coef);
[384455]1027
[3a2985]1028  int i;
[384455]1029  for(i=0;i<len;i++)
1030  {
[47e836b]1031      temp_array[i]=F4mat_to_number_type(n_Add((number)(long) temp_array[i], (number)(long) row[i],currRing->cf));
[3a2985]1032      assume(i<temp_size);
1033  }
[384455]1034
1035}
[2e4ec14]1036#ifdef NDEBUG
1037template <class number_type> void sub_dense(number_type* const temp_array,
1038int /*temp_size*/,const number_type* row, int len)
1039#else
[3a2985]1040template <class number_type> void sub_dense(number_type* const temp_array,
[384455]1041int temp_size,const number_type* row, int len)
[2e4ec14]1042#endif
[384455]1043{
[3a2985]1044  //int j;
[a41623]1045  //const number_type* const coef_array=row;
[3a2985]1046  //int* const idx_array=row->idx_array;
1047  //const int len=temp_size;
[a41623]1048  //tgb_uint32 buffer[256];
1049  //const tgb_uint32 prime=npPrimeM;
[3a2985]1050  //const tgb_uint32 c=F4mat_to_number_type(coef);
[384455]1051
[3a2985]1052  int i;
[384455]1053  for(i=0;i<len;i++)
1054  {
1055
[47e836b]1056      temp_array[i]=F4mat_to_number_type(n_Sub((number)(long) temp_array[i], (number)(long) row[i],currRing->cf));
[3a2985]1057      assume(i<temp_size);
1058  }
1059
[384455]1060}
1061
[2e4ec14]1062#ifdef NDEBUG
1063template <class number_type> void add_sparse(number_type* const temp_array,int /*temp_size*/,SparseRow<number_type>* row)
1064#else
[384455]1065template <class number_type> void add_sparse(number_type* const temp_array,int temp_size,SparseRow<number_type>* row)
[2e4ec14]1066#endif
[384455]1067{
[8120f8]1068  int j;
1069
1070          number_type* const coef_array=row->coef_array;
1071          int* const idx_array=row->idx_array;
1072          const int len=row->len;
[384455]1073        for(j=0;j<len;j++)
1074        {
[8120f8]1075          int idx=idx_array[j];
[47e836b]1076          temp_array[idx]=F4mat_to_number_type(   (number_type)(long)n_Add((number) (long)temp_array[idx],(number)(long) coef_array[j],currRing->cf));
[8120f8]1077          assume(idx<temp_size);
1078        }
1079}
[2e4ec14]1080#ifdef NDEBUG
1081template <class number_type> void sub_sparse(number_type* const temp_array,int /*temp_size*/,SparseRow<number_type>* row)
1082#else
[384455]1083template <class number_type> void sub_sparse(number_type* const temp_array,int temp_size,SparseRow<number_type>* row)
[2e4ec14]1084#endif
[384455]1085{
[8120f8]1086  int j;
1087
1088          number_type* const coef_array=row->coef_array;
1089          int* const idx_array=row->idx_array;
1090          const int len=row->len;
[384455]1091        for(j=0;j<len;j++)
1092        {
[8120f8]1093          int idx=idx_array[j];
[47e836b]1094          temp_array[idx]=F4mat_to_number_type(  (number_type)(long) n_Sub((number) (long)temp_array[idx],(number)(long) coef_array[j],currRing->cf));
[8120f8]1095          assume(idx<temp_size);
1096        }
1097}
[384455]1098template <class number_type> SparseRow<number_type>* noro_red_to_non_poly_dense(MonRedResNP<number_type>* mon, int len,NoroCache<number_type>* cache)
1099{
[8120f8]1100  size_t temp_size_bytes=cache->nIrreducibleMonomials*sizeof(number_type)+8;//use 8bit int for testing
1101   assume(sizeof(int64)==8);
1102   cache->ensureTempBufferSize(temp_size_bytes);
1103   number_type* temp_array=(number_type*) cache->tempBuffer;//omalloc(cache->nIrreducibleMonomials*sizeof(number_type));
1104   int temp_size=cache->nIrreducibleMonomials;
1105   memset(temp_array,0,temp_size_bytes);
[47e836b]1106   number minus_one=n_Init(-1,currRing->cf);
[8120f8]1107   int i;
[384455]1108   for(i=0;i<len;i++)
1109   {
[8120f8]1110     MonRedResNP<number_type> red=mon[i];
[384455]1111     if ((red.ref))
1112     {
1113       if (red.ref->row)
1114       {
[8120f8]1115         SparseRow<number_type>* row=red.ref->row;
1116         number coef=red.coef;
[384455]1117         if (row->idx_array)
1118         {
[1327a0]1119           if (!((coef==(number)(long) 1)||(coef==minus_one)))
[384455]1120           {
1121             add_coef_times_sparse(temp_array,temp_size,row,coef);
1122           }
1123           else
1124           {
[1327a0]1125             if (coef==(number)(long) 1)
[384455]1126             {
1127               add_sparse(temp_array,temp_size,row);
1128             }
1129             else
1130             {
1131               sub_sparse(temp_array,temp_size,row);
1132             }
[8120f8]1133           }
1134         }
[384455]1135         else
1136         //TODO: treat, 1,-1
[1327a0]1137         if (!((coef==(number)(long) 1)||(coef==minus_one)))
[384455]1138         {
1139          add_coef_times_dense(temp_array,temp_size,row->coef_array,row->len,coef);
1140         }
1141         else
1142         {
[1327a0]1143           if (coef==(number)(long)1)
[384455]1144             add_dense(temp_array,temp_size,row->coef_array,row->len);
1145           else
1146           {
1147             assume(coef==minus_one);
1148             sub_dense(temp_array,temp_size,row->coef_array,row->len);
1149             //add_coef_times_dense(temp_array,temp_size,row->coef_array,row->len,coef);
1150           }
[3a2985]1151         }
1152       }
[384455]1153       else
1154       {
1155         if (red.ref->value_len==NoroCache<number_type>::backLinkCode)
1156         {
[47e836b]1157           temp_array[red.ref->term_index]=F4mat_to_number_type( n_Add((number)(long) temp_array[red.ref->term_index],red.coef,currRing->cf));
[384455]1158         }
1159         else
1160         {
[8120f8]1161           //PrintS("third case\n");
1162         }
1163       }
1164     }
1165   }
1166   int non_zeros=0;
[384455]1167   for(i=0;i<cache->nIrreducibleMonomials;i++)
1168   {
[8120f8]1169     //if (!(temp_array[i]==0)){
1170     //  non_zeros++;
1171     //}
1172     assume(((temp_array[i]!=0)==0)|| (((temp_array[i]!=0)==1)));
1173     non_zeros+=(temp_array[i]!=0);
1174   }
1175
[384455]1176   if (non_zeros==0)
1177   {
[8120f8]1178     //omfree(mon);
1179     return NULL;
1180   }
[3a2985]1181   SparseRow<number_type>* res=new SparseRow<number_type>(temp_size,temp_array);//convert_to_sparse_row(temp_array,temp_size, non_zeros);
[8120f8]1182
1183   //omfree(temp_array);
1184
[384455]1185
[8120f8]1186   return res;
1187}
[384455]1188template<class number_type> class CoefIdx
1189{
[8120f8]1190public:
1191  number_type coef;
1192  int idx;
[384455]1193  bool operator<(const CoefIdx<number_type>& other) const
1194  {
[89e45b]1195    return (idx<other.idx);
[8120f8]1196  }
1197};
[384455]1198template<class number_type> void write_coef_times_xx_idx_to_buffer(CoefIdx<number_type>* const pairs,int& pos,int* const idx_array, number_type* const coef_array,const int rlen, const number coef)
1199{
[89e45b]1200  int j;
[384455]1201  for(j=0;j<rlen;j++)
1202  {
[89e45b]1203    assume(coef_array[j]!=0);
1204    CoefIdx<number_type> ci;
[47e836b]1205    ci.coef=F4mat_to_number_type(n_Mult((number)(long) coef,(number)(long) coef_array[j],currRing->cf));
[89e45b]1206    ci.idx=idx_array[j];
1207    pairs[pos++]=ci;
1208  }
1209}
[384455]1210template<class number_type> void write_coef_times_xx_idx_to_buffer_dense(CoefIdx<number_type>* const pairs,int& pos, number_type* const coef_array,const int rlen, const number coef)
1211{
[3a2985]1212  int j;
[384455]1213
1214  for(j=0;j<rlen;j++)
1215  {
1216    if (coef_array[j]!=0)
1217    {
1218      assume(coef_array[j]!=0);
1219      CoefIdx<number_type> ci;
[47e836b]1220      ci.coef=F4mat_to_number_type(n_Mult((number)(long) coef,(number)(long) coef_array[j],currRing->cf));
[384455]1221      assume(ci.coef!=0);
1222      ci.idx=j;
1223      pairs[pos++]=ci;
1224    }
[3a2985]1225  }
1226}
[384455]1227template<class number_type> void write_coef_idx_to_buffer_dense(CoefIdx<number_type>* const pairs,int& pos, number_type* const coef_array,const int rlen)
1228{
[cb1222e]1229  int j;
[384455]1230
1231  for(j=0;j<rlen;j++)
1232  {
1233    if (coef_array[j]!=0)
1234    {
1235      assume(coef_array[j]!=0);
1236      CoefIdx<number_type> ci;
1237      ci.coef=coef_array[j];
1238      assume(ci.coef!=0);
1239      ci.idx=j;
1240      pairs[pos++]=ci;
1241    }
[cb1222e]1242  }
1243}
1244
[384455]1245template<class number_type> void write_minus_coef_idx_to_buffer_dense(CoefIdx<number_type>* const pairs,int& pos, number_type* const coef_array,const int rlen)
1246{
[cb1222e]1247  int j;
[384455]1248
1249  for(j=0;j<rlen;j++)
1250  {
1251    if (coef_array[j]!=0)
1252    {
1253      assume(coef_array[j]!=0);
1254      CoefIdx<number_type> ci;
[47e836b]1255      ci.coef=F4mat_to_number_type(n_Neg((number)(long) coef_array[j],currRing->cf));
[384455]1256      assume(ci.coef!=0);
1257      ci.idx=j;
1258      pairs[pos++]=ci;
1259    }
[cb1222e]1260  }
1261}
[384455]1262template<class number_type> void write_coef_idx_to_buffer(CoefIdx<number_type>* const pairs,int& pos,int* const idx_array, number_type* const coef_array,const int rlen)
1263{
[89e45b]1264  int j;
[384455]1265  for(j=0;j<rlen;j++)
1266  {
[89e45b]1267    assume(coef_array[j]!=0);
1268    CoefIdx<number_type> ci;
1269    ci.coef=coef_array[j];
1270    ci.idx=idx_array[j];
1271    pairs[pos++]=ci;
1272  }
1273}
1274
[384455]1275template<class number_type> void write_minus_coef_idx_to_buffer(CoefIdx<number_type>* const pairs,int& pos,int* const idx_array, number_type* const coef_array,const int rlen)
1276{
[89e45b]1277  int j;
[384455]1278  for(j=0;j<rlen;j++)
1279  {
[89e45b]1280    assume(coef_array[j]!=0);
1281    CoefIdx<number_type> ci;
[47e836b]1282    ci.coef=F4mat_to_number_type(n_Neg((number)coef_array[j],currRing->cf));
[89e45b]1283    ci.idx=idx_array[j];
1284    pairs[pos++]=ci;
1285  }
1286}
[384455]1287template <class number_type> SparseRow<number_type>* noro_red_to_non_poly_sparse(MonRedResNP<number_type>* mon, int len,NoroCache<number_type>* cache)
1288{
[8120f8]1289  int i;
[384455]1290  int together=0;
1291  for(i=0;i<len;i++)
1292  {
1293    MonRedResNP<number_type> red=mon[i];
1294    if ((red.ref) &&( red.ref->row))
1295    {
1296      together+=red.ref->row->len;
1297    }
1298    else
1299    {
[3a2985]1300      if ((red.ref) &&(red.ref->value_len==NoroCache<number_type>::backLinkCode))
[8120f8]1301      together++;
[384455]1302    }
[8120f8]1303  }
1304  //PrintS("here\n");
[384455]1305  if (together==0) return 0;
[8120f8]1306  //PrintS("there\n");
[384455]1307  cache->ensureTempBufferSize(together*sizeof(CoefIdx<number_type>));
1308  CoefIdx<number_type>* pairs=(CoefIdx<number_type>*) cache->tempBuffer; //omalloc(together*sizeof(CoefIdx<number_type>));
1309  int pos=0;
[47e836b]1310  const number one=n_Init(1, currRing->cf);
1311  const number minus_one=n_Init(-1, currRing->cf);
[384455]1312  for(i=0;i<len;i++)
1313  {
1314    MonRedResNP<number_type> red=mon[i];
1315    if ((red.ref) &&( red.ref->row))
1316    {
[8120f8]1317      //together+=red.ref->row->len;
[384455]1318      int* idx_array=red.ref->row->idx_array;
1319      number_type* coef_array=red.ref->row->coef_array;
1320      int rlen=red.ref->row->len;
1321      number coef=red.coef;
1322      if (idx_array)
1323      {
1324        if ((coef!=one)&&(coef!=minus_one))
1325        {
1326          write_coef_times_xx_idx_to_buffer(pairs,pos,idx_array, coef_array,rlen, coef);
1327        }
1328        else
[3a2985]1329        {
[384455]1330          if (coef==one)
1331          {
[3a2985]1332            write_coef_idx_to_buffer(pairs,pos,idx_array, coef_array,rlen);
[384455]1333          }
1334          else
1335          {
[3a2985]1336            assume(coef==minus_one);
1337            write_minus_coef_idx_to_buffer(pairs,pos,idx_array, coef_array,rlen);
1338          }
1339        }
[384455]1340      }
1341      else
1342      {
1343        if ((coef!=one)&&(coef!=minus_one))
1344        {
[cb1222e]1345          write_coef_times_xx_idx_to_buffer_dense(pairs,pos,coef_array,rlen,coef);
[384455]1346        }
1347        else
1348        {
[cb1222e]1349          if (coef==one)
1350            write_coef_idx_to_buffer_dense(pairs,pos,coef_array,rlen);
[384455]1351          else
1352          {
[cb1222e]1353            assume(coef==minus_one);
1354            write_minus_coef_idx_to_buffer_dense(pairs,pos,coef_array,rlen);
1355          }
1356        }
[8120f8]1357      }
[89e45b]1358    }
[384455]1359    else
1360    {
1361      if ((red.ref) &&(red.ref->value_len==NoroCache<number_type>::backLinkCode))
1362      {
[8120f8]1363        CoefIdx<number_type> ci;
1364        ci.coef=F4mat_to_number_type(red.coef);
1365        ci.idx=red.ref->term_index;
1366        pairs[pos++]=ci;
1367      }
1368    }
1369  }
[3a2985]1370  assume(pos<=together);
1371  together=pos;
1372
[8120f8]1373  std::sort(pairs,pairs+together);
[3a2985]1374
[8120f8]1375  int act=0;
[3a2985]1376
[8120f8]1377  assume(pairs[0].coef!=0);
[384455]1378  for(i=1;i<together;i++)
1379  {
1380    if (pairs[i].idx!=pairs[act].idx)
1381    {
1382      if (pairs[act].coef!=0)
1383      {
[8120f8]1384        act=act+1;
1385      }
1386      pairs[act]=pairs[i];
[384455]1387    }
1388    else
1389    {
[47e836b]1390      pairs[act].coef=F4mat_to_number_type(n_Add((number)(long)pairs[act].coef,(number)(long)pairs[i].coef,currRing->cf));
[8120f8]1391    }
1392  }
[3a2985]1393
[384455]1394  if (pairs[act].coef==0)
1395  {
[8120f8]1396    act--;
1397  }
1398  int sparse_row_len=act+1;
1399  //Print("res len:%d",sparse_row_len);
1400  if (sparse_row_len==0) {return NULL;}
1401  SparseRow<number_type>* res=new SparseRow<number_type>(sparse_row_len);
1402  {
1403    number_type* coef_array=res->coef_array;
1404    int* idx_array=res->idx_array;
[384455]1405    for(i=0;i<sparse_row_len;i++)
1406    {
[8120f8]1407      idx_array[i]=pairs[i].idx;
1408      coef_array[i]=pairs[i].coef;
1409    }
1410  }
1411  //omfree(pairs);
[3a2985]1412
[8120f8]1413  return res;
1414}
[5ac8e5]1415template<class number_type> SparseRow<number_type> * noro_red_to_non_poly_t(poly p, int &len, NoroCache<number_type>* cache,slimgb_alg* c){
[a7d970]1416  assume(len==pLength(p));
[8391d8]1417  if (p==NULL)
1418  {
[a7d970]1419    len=0;
1420    return NULL;
1421  }
[384455]1422
[5ac8e5]1423  MonRedResNP<number_type>* mon=(MonRedResNP<number_type>*) omalloc(len*sizeof(MonRedResNP<number_type>));
[a7d970]1424  int i=0;
[8120f8]1425  double max_density=0.0;
[8391d8]1426  while(p!=NULL)
1427  {
[a7d970]1428    poly t=p;
1429    pIter(p);
1430    pNext(t)=NULL;
[384455]1431
[5ac8e5]1432    MonRedResNP<number_type> red=noro_red_mon_to_non_poly(t,cache,c);
[a41623]1433    if ((red.ref) && (red.ref->row))
1434    {
[8120f8]1435      double act_density=(double) red.ref->row->len;
1436      act_density/=(double) cache->nIrreducibleMonomials;
[1b2d84]1437      max_density=std::max(act_density,max_density);
[8120f8]1438    }
[a7d970]1439    mon[i]=red;
1440    i++;
1441  }
[384455]1442
[a7d970]1443  assume(i==len);
1444  len=i;
[8120f8]1445  bool dense=true;
[cb1222e]1446  if (max_density<0.3) dense=false;
[8120f8]1447  if (dense){
1448    SparseRow<number_type>* res=noro_red_to_non_poly_dense(mon,len,cache);
[7b2896]1449    omfree(mon);
[8120f8]1450    return res;
1451  } else   {
1452      SparseRow<number_type>* res=noro_red_to_non_poly_sparse(mon,len,cache);
1453      omfree(mon);
1454      return res;
1455    }
1456  //in the loop before nIrreducibleMonomials increases, so position here is important
[384455]1457
[a7d970]1458}
1459#endif
[2fd387d]1460static wlen_type pair_weighted_length(int i, int j, slimgb_alg* c);
[e65be8e]1461wlen_type pELength(poly p, ring r);
[e9ade0f]1462int terms_sort_crit(const void* a, const void* b);
1463//void simplest_gauss_modp(number* a, int nrows,int ncols);
[44103a2]1464// a: a[0,0],a[0,1]....a[nrows-1,ncols-1]
1465// assume: field is Zp
[e9ade0f]1466#ifdef USE_NORO
[5ac8e5]1467
[e9ade0f]1468
1469template <class number_type > void write_poly_to_row(number_type* row, poly h, poly*terms, int tn, ring r){
1470  //poly* base=row;
1471  while(h!=NULL){
1472    //Print("h:%i\n",h);
1473    number coef=p_GetCoeff(h,r);
1474    poly* ptr_to_h=(poly*) bsearch(&h,terms,tn,sizeof(poly),terms_sort_crit);
1475    assume(ptr_to_h!=NULL);
1476    int pos=ptr_to_h-terms;
1477    row[pos]=F4mat_to_number_type(coef);
1478    //number_type_array[base+pos]=coef;
1479    pIter(h);
1480  }
1481}
1482template <class number_type > poly row_to_poly(number_type* row, poly* terms, int tn, ring r){
1483  poly h=NULL;
1484  int j;
1485  number_type zero=0;//;npInit(0);
1486  for(j=tn-1;j>=0;j--){
1487    if (!(zero==(row[j]))){
1488      poly t=terms[j];
1489      t=p_LmInit(t,r);
[1327a0]1490      p_SetCoeff(t,(number)(long) row[j],r);
[e9ade0f]1491      pNext(t)=h;
1492      h=t;
1493    }
[384455]1494
[e9ade0f]1495  }
1496  return h;
1497}
[384455]1498template <class number_type > int modP_lastIndexRow(number_type* row,int ncols)
1499{
[e9ade0f]1500  int lastIndex;
1501  const number_type zero=0;//npInit(0);
[384455]1502  for(lastIndex=ncols-1;lastIndex>=0;lastIndex--)
1503  {
1504    if (!(row[lastIndex]==zero))
1505    {
[e9ade0f]1506      return lastIndex;
1507    }
1508  }
1509  return -1;
1510}
[384455]1511template <class number_type> int term_nodes_sort_crit(const void* a, const void* b)
1512{
[5ac8e5]1513  return -pLmCmp(((TermNoroDataNode<number_type>*) a)->t,((TermNoroDataNode<number_type>*) b)->t);
1514}
1515
[e9ade0f]1516template <class number_type>class ModPMatrixBackSubstProxyOnArray;
[384455]1517template <class number_type > class ModPMatrixProxyOnArray
1518{
[e9ade0f]1519public:
1520  friend class ModPMatrixBackSubstProxyOnArray<number_type>;
[384455]1521
[e9ade0f]1522  int ncols,nrows;
[5f4463]1523  ModPMatrixProxyOnArray(number_type* array, int nnrows, int nncols)
1524  {
1525    this->ncols=nncols;
1526    this->nrows=nnrows;
1527    rows=(number_type**) omalloc(nnrows*sizeof(number_type*));
1528    startIndices=(int*)omalloc(nnrows*sizeof(int));
[e9ade0f]1529    int i;
[5f4463]1530    for(i=0;i<nnrows;i++)
[384455]1531    {
[5f4463]1532      rows[i]=array+(i*nncols);
[e9ade0f]1533      updateStartIndex(i,-1);
1534    }
1535  }
[384455]1536  ~ModPMatrixProxyOnArray()
1537  {
[e9ade0f]1538    omfree(rows);
1539    omfree(startIndices);
1540  }
[384455]1541
1542  void permRows(int i, int j)
1543  {
[e9ade0f]1544    number_type* h=rows[i];
1545    rows[i]=rows[j];
1546    rows[j]=h;
1547    int hs=startIndices[i];
1548    startIndices[i]=startIndices[j];
1549    startIndices[j]=hs;
1550  }
[384455]1551  void multiplyRow(int row, number_type coef)
1552  {
[e9ade0f]1553    int i;
1554    number_type* row_array=rows[row];
[384455]1555    for(i=startIndices[row];i<ncols;i++)
1556    {
[47e836b]1557      row_array[i]=F4mat_to_number_type(n_Mult((number)(long) row_array[i],(number)(long) coef,currRing->cf));
[e9ade0f]1558    }
1559  }
[384455]1560  void reduceOtherRowsForward(int r)
1561  {
[e9ade0f]1562    //assume rows "under r" have bigger or equal start index
1563    number_type* row_array=rows[r];
[47e836b]1564    number_type zero=F4mat_to_number_type((number)0 /*npInit(0, currRing)*/);
[e9ade0f]1565    int start=startIndices[r];
1566    number_type coef=row_array[start];
1567    assume(start<ncols);
1568    int other_row;
[40a823]1569    assume(!(n_IsZero((number)(long) row_array[start],currRing->cf)));
[47e836b]1570    if (!(n_IsOne((number)(long) coef,currRing->cf)))
1571      multiplyRow(r,F4mat_to_number_type(n_Invers((number)(long) coef,currRing->cf)));
1572    assume(n_IsOne((number)(long) row_array[start],currRing->cf));
[e9ade0f]1573    int lastIndex=modP_lastIndexRow(row_array, ncols);
[47e836b]1574    number minus_one=n_Init(-1, currRing->cf);
[384455]1575    for (other_row=r+1;other_row<nrows;other_row++)
1576    {
[e9ade0f]1577      assume(startIndices[other_row]>=start);
[384455]1578      if (startIndices[other_row]==start)
1579      {
[e9ade0f]1580        int i;
1581        number_type* other_row_array=rows[other_row];
[47e836b]1582        number coef2=n_Neg((number)(long) other_row_array[start],currRing->cf);
[384455]1583        if (coef2==minus_one)
1584        {
1585          for(i=start;i<=lastIndex;i++)
1586          {
[e9ade0f]1587            if (row_array[i]!=zero)
[47e836b]1588              other_row_array[i]=F4mat_to_number_type(n_Sub((number)(long) other_row_array[i], (number)(long) row_array[i],currRing->cf));
[e9ade0f]1589          }
[384455]1590      }
1591      else
1592      {
[e9ade0f]1593          //assume(FALSE);
[384455]1594          for(i=start;i<=lastIndex;i++)
1595          {
[e9ade0f]1596            if (row_array[i]!=zero)
[47e836b]1597            other_row_array[i]=F4mat_to_number_type(n_Add(n_Mult(coef2,(number)(long) row_array[i],currRing->cf),(number)(long) other_row_array[i],currRing->cf));
[e9ade0f]1598          }
1599        }
1600        updateStartIndex(other_row,start);
[40a823]1601        assume(n_IsZero((number)(long) other_row_array[start],currRing->cf));
[e9ade0f]1602      }
1603    }
1604  }
[384455]1605  void updateStartIndex(int row,int lower_bound)
1606  {
[e9ade0f]1607    number_type* row_array=rows[row];
[40a823]1608    assume((lower_bound<0)||(n_IsZero((number)(long) row_array[lower_bound],currRing->cf)));
[e9ade0f]1609    int i;
1610    //number_type zero=npInit(0);
[384455]1611    for(i=lower_bound+1;i<ncols;i++)
1612    {
[e9ade0f]1613      if (!(row_array[i]==0))
1614        break;
1615    }
1616    startIndices[row]=i;
1617  }
[384455]1618  int getStartIndex(int row)
1619  {
[e9ade0f]1620    return startIndices[row];
1621  }
[384455]1622  BOOLEAN findPivot(int &r, int &c)
1623  {
[e9ade0f]1624    //row>=r, col>=c
[384455]1625
1626    while(c<ncols)
1627    {
[e9ade0f]1628      int i;
[384455]1629      for(i=r;i<nrows;i++)
1630      {
[e9ade0f]1631        assume(startIndices[i]>=c);
[384455]1632        if (startIndices[i]==c)
1633        {
[e9ade0f]1634          //r=i;
1635          if (r!=i)
1636            permRows(r,i);
1637          return TRUE;
1638        }
1639      }
1640      c++;
1641    }
1642    return FALSE;
1643  }
1644protected:
1645  number_type** rows;
1646  int* startIndices;
1647};
[384455]1648template <class number_type > class ModPMatrixBackSubstProxyOnArray
1649{
[e9ade0f]1650  int *startIndices;
1651  number_type** rows;
1652  int *lastReducibleIndices;
1653  int ncols;
1654  int nrows;
1655  int nonZeroUntil;
1656public:
[384455]1657  void multiplyRow(int row, number_type coef)
1658  {
[e9ade0f]1659    int i;
1660    number_type* row_array=rows[row];
[384455]1661    for(i=startIndices[row];i<ncols;i++)
1662    {
[47e836b]1663      row_array[i]=F4mat_to_number_type(n_Mult((number)(long) row_array[i],(number)(long) coef,currRing->cf));
[e9ade0f]1664    }
1665  }
[384455]1666  ModPMatrixBackSubstProxyOnArray<number_type> (ModPMatrixProxyOnArray<number_type> & p)
1667  {
[e9ade0f]1668//  (number_type* array, int nrows, int ncols, int* startIndices, number_type** rows){
1669    //we borrow some parameters ;-)
1670    //we assume, that nobody changes the order of the rows
1671    this->startIndices=p.startIndices;
1672    this->rows=p.rows;
1673    this->ncols=p.ncols;
1674    this->nrows=p.nrows;
1675    lastReducibleIndices=(int*) omalloc(nrows*sizeof(int));
1676    nonZeroUntil=0;
[44fac1]1677    while(nonZeroUntil<nrows)
1678    {
1679      if (startIndices[nonZeroUntil]<ncols)
1680      {
[e9ade0f]1681        nonZeroUntil++;
[384455]1682      }
1683      else break;
[e9ade0f]1684    }
1685    if (TEST_OPT_PROT)
1686      Print("rank:%i\n",nonZeroUntil);
1687    nonZeroUntil--;
1688    int i;
[384455]1689    for(i=0;i<=nonZeroUntil;i++)
1690    {
[e9ade0f]1691      assume(startIndices[i]<ncols);
[40a823]1692      assume(!(n_IsZero((number)(long) rows[i][startIndices[i]],currRing->cf)));
[e9ade0f]1693      assume(startIndices[i]>=i);
1694      updateLastReducibleIndex(i,nonZeroUntil+1);
1695    }
1696  }
[384455]1697  void updateLastReducibleIndex(int r, int upper_bound)
1698  {
[e9ade0f]1699    number_type* row_array=rows[r];
1700    if (upper_bound>nonZeroUntil) upper_bound=nonZeroUntil+1;
1701    int i;
1702    const number_type zero=0;//npInit(0);
[384455]1703    for(i=upper_bound-1;i>r;i--)
1704    {
[e9ade0f]1705      int start=startIndices[i];
1706      assume(start<ncols);
[384455]1707      if (!(row_array[start]==zero))
1708      {
[e9ade0f]1709        lastReducibleIndices[r]=start;
1710        return;
1711      }
1712    }
1713    lastReducibleIndices[r]=-1;
1714  }
[384455]1715  void backwardSubstitute(int r)
1716  {
[e9ade0f]1717    int start=startIndices[r];
1718    assume(start<ncols);
1719    number_type zero=0;//npInit(0);
1720    number_type* row_array=rows[r];
[40a823]1721    assume((!(n_IsZero((number)(long) row_array[start],currRing->cf))));
[e9ade0f]1722    assume(start<ncols);
1723    int other_row;
[47e836b]1724    if (!(n_IsOne((number)(long) row_array[r],currRing->cf)))
[384455]1725    {
[e9ade0f]1726      //it should be one, but this safety is not expensive
[47e836b]1727      multiplyRow(r, F4mat_to_number_type(n_Invers((number)(long) row_array[start],currRing->cf)));
[e9ade0f]1728    }
1729    int lastIndex=modP_lastIndexRow(row_array, ncols);
1730    assume(lastIndex<ncols);
1731    assume(lastIndex>=0);
[384455]1732    for(other_row=r-1;other_row>=0;other_row--)
1733    {
[e9ade0f]1734      assume(lastReducibleIndices[other_row]<=start);
[384455]1735      if (lastReducibleIndices[other_row]==start)
1736      {
[e9ade0f]1737        number_type* other_row_array=rows[other_row];
[47e836b]1738        number coef=n_Neg((number)(long) other_row_array[start],currRing->cf);
[40a823]1739        assume(!(n_IsZero(coef,currRing->cf)));
[e9ade0f]1740        int i;
1741        assume(start>startIndices[other_row]);
[384455]1742        for(i=start;i<=lastIndex;i++)
1743        {
[e9ade0f]1744          if (row_array[i]!=zero)
[47e836b]1745            other_row_array[i]=F4mat_to_number_type(n_Add(n_Mult(coef,(number)(long)row_array[i],currRing->cf),(number)(long)other_row_array[i],currRing->cf));
[e9ade0f]1746        }
1747        updateLastReducibleIndex(other_row,r);
1748      }
1749    }
1750  }
[384455]1751  ~ModPMatrixBackSubstProxyOnArray<number_type>()
1752  {
[e9ade0f]1753    omfree(lastReducibleIndices);
1754  }
[384455]1755  void backwardSubstitute()
1756  {
[e9ade0f]1757    int i;
[384455]1758    for(i=nonZeroUntil;i>0;i--)
1759    {
[e9ade0f]1760      backwardSubstitute(i);
1761    }
1762  }
1763};
[384455]1764template <class number_type > void simplest_gauss_modp(number_type* a, int nrows,int ncols)
1765{
[e9ade0f]1766  //use memmoves for changing rows
[f2b5839]1767  //if (TEST_OPT_PROT)
1768  //    PrintS("StartGauss\n");
[e9ade0f]1769  ModPMatrixProxyOnArray<number_type> mat(a,nrows,ncols);
[384455]1770
[e9ade0f]1771  int c=0;
1772  int r=0;
1773  while(mat.findPivot(r,c)){
1774    //int pivot=find_pivot()
1775      mat.reduceOtherRowsForward(r);
1776    r++;
1777    c++;
1778  }
1779  ModPMatrixBackSubstProxyOnArray<number_type> backmat(mat);
1780  backmat.backwardSubstitute();
1781  //backward substitutions
[f2b5839]1782  //if (TEST_OPT_PROT)
1783  //PrintS("StopGauss\n");
[e9ade0f]1784}
[5ac8e5]1785//int term_nodes_sort_crit(const void* a, const void* b);
[abce2e]1786template <class number_type> void noro_step(poly*p,int &pn,slimgb_alg* c){
1787  //Print("Input rows %d\n",pn);
1788  int j;
[44fac1]1789  if (TEST_OPT_PROT)
1790  {
[abce2e]1791    Print("Input rows %d\n",pn);
1792  }
1793
[5ac8e5]1794  NoroCache<number_type> cache;
[abce2e]1795
[44fac1]1796  SparseRow<number_type> ** srows=(SparseRow<number_type>**) omAlloc(pn*sizeof(SparseRow<number_type>*));
[abce2e]1797  int non_zeros=0;
[44fac1]1798  for(j=0;j<pn;j++)
1799  {
[abce2e]1800    poly h=p[j];
1801    int h_len=pLength(h);
1802    //number coef;
1803    srows[non_zeros]=noro_red_to_non_poly_t<number_type>(h,h_len,&cache,c);
1804    if (srows[non_zeros]!=NULL) non_zeros++;
1805  }
[5ac8e5]1806  std::vector<DataNoroCacheNode<number_type>*> irr_nodes;
[abce2e]1807  cache.collectIrreducibleMonomials(irr_nodes);
1808  //now can build up terms array
1809  //Print("historic irred Mon%d\n",cache.nIrreducibleMonomials);
1810  int n=irr_nodes.size();//cache.countIrreducibleMonomials();
1811  cache.nIrreducibleMonomials=n;
[44fac1]1812  if (TEST_OPT_PROT)
1813  {
[abce2e]1814    Print("Irred Mon:%d\n",n);
1815    Print("red Mon:%d\n",cache.nReducibleMonomials);
1816  }
[5ac8e5]1817  TermNoroDataNode<number_type>* term_nodes=(TermNoroDataNode<number_type>*) omalloc(n*sizeof(TermNoroDataNode<number_type>));
[384455]1818
[44fac1]1819  for(j=0;j<n;j++)
1820  {
[abce2e]1821    assume(irr_nodes[j]!=NULL);
[5ac8e5]1822    assume(irr_nodes[j]->value_len==NoroCache<number_type>::backLinkCode);
[abce2e]1823    term_nodes[j].t=irr_nodes[j]->value_poly;
1824    assume(term_nodes[j].t!=NULL);
1825    term_nodes[j].node=irr_nodes[j];
1826  }
[384455]1827
[5ac8e5]1828  qsort(term_nodes,n,sizeof(TermNoroDataNode<number_type>),term_nodes_sort_crit<number_type>);
[abce2e]1829  poly* terms=(poly*) omalloc(n*sizeof(poly));
1830
1831  int* old_to_new_indices=(int*) omalloc(cache.nIrreducibleMonomials*sizeof(int));
[a41623]1832  for(j=0;j<n;j++)
1833  {
[abce2e]1834    old_to_new_indices[term_nodes[j].node->term_index]=j;
1835    term_nodes[j].node->term_index=j;
1836    terms[j]=term_nodes[j].t;
1837  }
1838
1839  //if (TEST_OPT_PROT)
1840  //  Print("Evaluate Rows \n");
1841  pn=non_zeros;
[44fac1]1842  number_type* number_array=(number_type*) omalloc0(n*pn*sizeof(number_type));
[abce2e]1843
[a41623]1844  for(j=0;j<pn;j++)
1845  {
[abce2e]1846    int i;
1847    number_type* row=number_array+n*j;
[a41623]1848    /*for(i=0;i<n;i++)
1849    {
[abce2e]1850      row[i]=zero;
1851    }*/
1852
[5ac8e5]1853    SparseRow<number_type>* srow=srows[j];
[8120f8]1854
[a41623]1855    if (srow)
1856    {
[8120f8]1857      int* const idx_array=srow->idx_array;
1858      number_type* const coef_array=srow->coef_array;
1859      const int len=srow->len;
[a41623]1860      if (srow->idx_array)
1861      {
1862        for(i=0;i<len;i++)
1863        {
[3a2985]1864         int idx=old_to_new_indices[idx_array[i]];
1865         row[idx]=F4mat_to_number_type(coef_array[i]);
[384455]1866        }
[3a2985]1867      }
[a41623]1868      else
1869      {
1870        for(i=0;i<len;i++)
1871        {
[3a2985]1872          row[old_to_new_indices[i]]=F4mat_to_number_type(coef_array[i]);
1873        }
1874      }
1875      delete srow;
[abce2e]1876    }
1877  }
[384455]1878
[a41623]1879  //static int export_n=0;
[abce2e]1880  //export_mat(number_array,pn,n,"mat%i.py",++export_n);
1881  simplest_gauss_modp(number_array,pn,n);
1882
1883  int p_pos=0;
1884  for(j=0;j<pn;j++){
1885    poly h=row_to_poly(number_array+j*n,terms,n,c->r);
1886    if(h!=NULL){
1887      p[p_pos++]=h;
1888    }
1889  }
1890  pn=p_pos;
1891  omfree(terms);
1892  omfree(term_nodes);
1893  omfree(number_array);
1894  #ifdef NORO_NON_POLY
1895  omfree(srows);
1896  omfree(old_to_new_indices);
1897  #endif
1898  //don't forget the rank
[384455]1899
[abce2e]1900}
[5ac8e5]1901
1902template <class number_type> void NoroCache<number_type>::collectIrreducibleMonomials( std::vector<DataNoroCacheNode<number_type> *>& res){
1903  int i;
1904  for(i=0;i<root.branches_len;i++){
1905    collectIrreducibleMonomials(1,root.branches[i],res);
1906  }
1907}
1908template <class number_type> void NoroCache<number_type>::collectIrreducibleMonomials(int level, NoroCacheNode* node, std::vector<DataNoroCacheNode<number_type>*>& res){
1909  assume(level>=0);
1910  if (node==NULL) return;
[1f637e]1911  if (level<(currRing->N))
[a41623]1912  {
1913    int i;
1914    for(i=0;i<node->branches_len;i++)
1915    {
[5ac8e5]1916      collectIrreducibleMonomials(level+1,node->branches[i],res);
1917    }
[a41623]1918  }
1919  else
1920  {
[5ac8e5]1921    DataNoroCacheNode<number_type>* dn=(DataNoroCacheNode<number_type>*) node;
[a41623]1922    if (dn->value_len==backLinkCode)
1923    {
[5ac8e5]1924      res.push_back(dn);
[384455]1925    }
[5ac8e5]1926  }
1927}
1928
1929template<class number_type> DataNoroCacheNode<number_type>* NoroCache<number_type>::getCacheReference(poly term){
1930  int i;
1931  NoroCacheNode* parent=&root;
[1f637e]1932  for(i=1;i<(currRing->N);i++){
[5ac8e5]1933    parent=parent->getBranch(p_GetExp(term,i,currRing));
1934    if (!(parent)){
1935      return NULL;
1936    }
1937  }
1938  DataNoroCacheNode<number_type>* res_holder=(DataNoroCacheNode<number_type>*) parent->getBranch(p_GetExp(term,i,currRing));
1939  return res_holder;
1940}
1941template<class number_type> poly NoroCache<number_type>::lookup(poly term, BOOLEAN& succ, int & len){
1942  int i;
1943  NoroCacheNode* parent=&root;
[1f637e]1944  for(i=1;i<(currRing->N);i++){
[5ac8e5]1945    parent=parent->getBranch(p_GetExp(term,i,currRing));
1946    if (!(parent)){
1947      succ=FALSE;
1948      return NULL;
1949    }
1950  }
1951  DataNoroCacheNode<number_type>* res_holder=(DataNoroCacheNode<number_type>*) parent->getBranch(p_GetExp(term,i,currRing));
1952  if (res_holder){
1953    succ=TRUE;
1954    if ((res_holder->value_len==backLinkCode)){
1955      len=1;
1956      return term;
1957    }
1958    len=res_holder->value_len;
1959    return res_holder->value_poly;
1960  } else {
1961    succ=FALSE;
1962    return NULL;
1963  }
1964}
[e9ade0f]1965#endif
1966
[f4adfcb]1967#endif
Note: See TracBrowser for help on using the repository browser.