source: git/kernel/GBEngine/tgb_internal.h @ 4f8fd1d

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