=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/gmpq.c,v retrieving revision 1.3 retrieving revision 1.8 diff -u -p -r1.3 -r1.8 --- OpenXM_contrib2/asir2000/engine/gmpq.c 2014/08/19 06:35:01 1.3 +++ OpenXM_contrib2/asir2000/engine/gmpq.c 2017/08/31 02:36:21 1.8 @@ -5,6 +5,9 @@ mpz_t ONEMPZ; GZ ONEGZ; +int lf_lazy; +GZ current_mod_lf; +int current_mod_lf_size; void isqrtgz(GZ a,GZ *r); void bshiftgz(GZ a,int n,GZ *r); @@ -21,7 +24,7 @@ void gc_free(void *p,size_t size) void init_gmpq() { - mp_set_memory_functions(Risa_GC_malloc_atomic,gc_realloc,gc_free); + mp_set_memory_functions(Risa_GC_malloc,gc_realloc,gc_free); mpz_init(ONEMPZ); mpz_set_ui(ONEMPZ,1); MPZTOGZ(ONEMPZ,ONEGZ); } @@ -81,12 +84,23 @@ Q gztoz(GZ a) if ( !a ) return 0; len = WORDSIZE_IN_N(BDY((GZ)a)); nm = NALLOC(len); + fprintf(stderr,"%d ",len); mpz_export(BD(nm),&len,-1,sizeof(int),0,0,BDY((GZ)a)); PL(nm) = len; sgn = mpz_sgn(BDY((GZ)a)); NTOQ(nm,sgn,q); return q; } +void dupgz(GZ a,GZ *b) +{ + mpz_t t; + + if ( !a ) *b = a; + else { + mpz_init(t); mpz_set(t,BDY(a)); MPZTOGZ(t,*b); + } +} + int n_bits_gz(GZ a) { return a ? mpz_sizeinbase(BDY(a),2) : 0; @@ -211,15 +225,31 @@ void mulgz(GZ n1,GZ n2,GZ *nr) mpz_t t; if ( !n1 || !n2 ) *nr = 0; +#if 1 else if ( UNIGZ(n1) ) *nr = n2; else if ( UNIGZ(n2) ) *nr = n1; else if ( MUNIGZ(n1) ) chsgngz(n2,nr); else if ( MUNIGZ(n2) ) chsgngz(n1,nr); +#endif else { mpz_init(t); mpz_mul(t,BDY(n1),BDY(n2)); MPZTOGZ(t,*nr); } } +/* nr += n1*n2 */ + +void muladdtogz(GZ n1,GZ n2,GZ *nr) +{ + GZ t; + + if ( n1 && n2 ) { + if ( !(*nr) ) { + NEWGZ(t); mpz_init(BDY(t)); *nr = t; + } + mpz_addmul(BDY(*nr),BDY(n1),BDY(n2)); + } +} + void mul1gz(GZ n1,int n2,GZ *nr) { mpz_t t; @@ -248,6 +278,23 @@ void divgz(GZ n1,GZ n2,GZ *nq) } } +void remgz(GZ n1,GZ n2,GZ *nr) +{ + mpz_t r; + + if ( !n2 ) { + error("division by 0"); + *nr = 0; + } else if ( !n1 || n1 == n2 ) + *nr = 0; + else { + mpz_init(r); + mpz_mod(r,BDY(n1),BDY(n2)); + if ( !mpz_sgn(r) ) *nr = 0; + else MPZTOGZ(r,*nr); + } +} + void divqrgz(GZ n1,GZ n2,GZ *nq,GZ *nr) { mpz_t t, a, b, q, r; @@ -351,6 +398,14 @@ void gcdgz(GZ n1,GZ n2,GZ *nq) } } +void invgz(GZ n1,GZ *nq) +{ + mpz_t t; + + mpz_init(t); mpz_invert(t,BDY(n1),BDY(current_mod_lf)); + MPZTOGZ(t,*nq); +} + void lcmgz(GZ n1,GZ n2,GZ *nq) { GZ g,t; @@ -1215,3 +1270,78 @@ void bshiftgz(GZ a,int n,GZ *r) } } +void addlf(GZ a,GZ b,GZ *c) +{ + GZ t; + + addgz(a,b,c); + if ( !lf_lazy ) { + remgz(*c,current_mod_lf,&t); *c = t; + } +} + +void sublf(GZ a,GZ b,GZ *c) +{ + GZ t; + + subgz(a,b,c); + if ( !lf_lazy ) { + remgz(*c,current_mod_lf,&t); *c = t; + } +} + +void mullf(GZ a,GZ b,GZ *c) +{ + GZ t; + + mulgz(a,b,c); + if ( !lf_lazy ) { + remgz(*c,current_mod_lf,&t); *c = t; + } +} + +void divlf(GZ a,GZ b,GZ *c) +{ + GZ t,inv; + + invgz(b,&inv); + mulgz(a,inv,c); + if ( !lf_lazy ) { + remgz(*c,current_mod_lf,&t); *c = t; + } +} + +void chsgnlf(GZ a,GZ *c) +{ + GZ t; + + chsgngz(a,c); + if ( !lf_lazy ) { + remgz(*c,current_mod_lf,&t); *c = t; + } +} + +void lmtolf(LM a,GZ *b) +{ + Q q; + + if ( !a ) *b = 0; + else { + NTOQ(BDY(a),1,q); *b = ztogz(q); + } +} + +void setmod_lf(N p) +{ + Q q; + + NTOQ(p,1,q); current_mod_lf = ztogz(q); + current_mod_lf_size = mpz_size(BDY(current_mod_lf))+1; +} + +void simplf_force(GZ a,GZ *b) +{ + GZ t; + + remgz(a,current_mod_lf,&t); *b = t; +}