| version 1.10, 2018/12/10 22:24:42 |
version 1.17, 2020/01/09 01:47:41 |
|
|
| /* $OpenXM: OpenXM_contrib2/asir2018/engine/Q.c,v 1.9 2018/10/19 23:27:38 noro Exp $ */ |
/* $OpenXM: OpenXM_contrib2/asir2018/engine/Q.c,v 1.16 2019/05/22 02:41:16 noro Exp $ */ |
| #include "ca.h" |
#include "ca.h" |
| #include "gmp.h" |
#include "gmp.h" |
| #include "base.h" |
#include "base.h" |
| #include "inline.h" |
#include "inline.h" |
| |
|
| mpz_t ONEMPZ; |
mpz_t ONEMPZ; |
| Z ONE; |
extern Z ONE; |
| int lf_lazy; |
int lf_lazy; |
| Z current_mod_lf; |
Z current_mod_lf; |
| int current_mod_lf_size; |
int current_mod_lf_size; |
| Line 515 void factorialz(unsigned int n,Z *nr) |
|
| Line 515 void factorialz(unsigned int n,Z *nr) |
|
| { |
{ |
| mpz_t a; |
mpz_t a; |
| mpz_init(a); |
mpz_init(a); |
| mpz_fac_ui(a,n); |
mpz_fac_ui(a,(unsigned long)n); |
| MPZTOZ(a,*nr); |
MPZTOZ(a,*nr); |
| } |
} |
| |
|
| Line 558 void subq(Q n1,Q n2,Q *nr) |
|
| Line 558 void subq(Q n1,Q n2,Q *nr) |
|
| |
|
| if ( !n1 ) { |
if ( !n1 ) { |
| if ( !n2 ) *nr = 0; |
if ( !n2 ) *nr = 0; |
| else if ( n1->z ) chsgnz((Z)n1,(Z *)nr); |
else if ( n2->z ) chsgnz((Z)n2,(Z *)nr); |
| else { |
else { |
| mpq_init(t); mpq_neg(t,BDY(n2)); MPQTOQ(t,*nr); |
mpq_init(t); mpq_neg(t,BDY(n2)); MPQTOQ(t,*nr); |
| } |
} |
| Line 762 void lgp(P p,Z *g,Z *l); |
|
| Line 762 void lgp(P p,Z *g,Z *l); |
|
| |
|
| void ptozp(P p,int sgn,Q *c,P *pr) |
void ptozp(P p,int sgn,Q *c,P *pr) |
| { |
{ |
| Z nm,dn; |
Z nm,dn,nm1; |
| |
|
| if ( !p ) { |
if ( !p ) { |
| *c = 0; *pr = 0; |
*c = 0; *pr = 0; |
| } else { |
} else { |
| lgp(p,&nm,&dn); |
lgp(p,&nm,&dn); |
| |
if ( sgn < 0 ) { |
| |
chsgnz(nm,&nm1); nm = nm1; |
| |
} |
| divz(nm,dn,(Z *)c); |
divz(nm,dn,(Z *)c); |
| divsp(CO,p,(P)*c,pr); |
divsp(CO,p,(P)*c,pr); |
| } |
} |
| Line 1229 int intmtoratm(MAT mat,Z md,MAT nm,Z *dn) |
|
| Line 1232 int intmtoratm(MAT mat,Z md,MAT nm,Z *dn) |
|
| return 0; |
return 0; |
| row = mat->row; col = mat->col; |
row = mat->row; col = mat->col; |
| bshiftz(md,1,&t); |
bshiftz(md,1,&t); |
| isqrtz(t,&s); |
isqrt(t,&s); |
| bshiftz(s,64,&b); |
bshiftz(s,64,&b); |
| if ( !b ) b = ONE; |
if ( !b ) b = ONE; |
| dn0 = ONE; |
dn0 = ONE; |
| Line 1337 int mpz_inttorat(mpz_t c,mpz_t m,mpz_t b,mpz_t nm,mpz_ |
|
| Line 1340 int mpz_inttorat(mpz_t c,mpz_t m,mpz_t b,mpz_t nm,mpz_ |
|
| } |
} |
| if ( mpz_cmp(v1,b) >= 0 ) return 0; |
if ( mpz_cmp(v1,b) >= 0 ) return 0; |
| else { |
else { |
| |
mpz_gcd(t,v1,v2); |
| |
if ( UNIMPZ(t) ) |
| |
mpz_set_ui(r1,0); |
| |
else { |
| |
/* v1 /= t, v2 /= t, t=c*v1-v2, r1=t%m */ |
| |
mpz_divexact(v1,v1,t); mpz_divexact(v2,v2,t); |
| |
mpz_mul(t,c,v1); mpz_sub(t,t,v2); mpz_mod(r1,t,m); |
| |
} |
| |
if ( mpz_sgn(r1) ) return 0; |
| if ( mpz_sgn(v1)<0 ) { |
if ( mpz_sgn(v1)<0 ) { |
| mpz_neg(dn,v1); mpz_neg(nm,v2); |
mpz_neg(dn,v1); mpz_neg(nm,v2); |
| } else { |
} else { |
| Line 1348 int mpz_inttorat(mpz_t c,mpz_t m,mpz_t b,mpz_t nm,mpz_ |
|
| Line 1360 int mpz_inttorat(mpz_t c,mpz_t m,mpz_t b,mpz_t nm,mpz_ |
|
| |
|
| int inttorat(Z c,Z m,Z b,Z *nmp,Z *dnp) |
int inttorat(Z c,Z m,Z b,Z *nmp,Z *dnp) |
| { |
{ |
| Z qq,t,u1,v1,r1; |
Z qq,t,s,r,u1,v1,r1; |
| Z q,u2,v2,r2; |
Z q,u2,v2,r2; |
| |
|
| u1 = 0; v1 = ONE; u2 = m; v2 = c; |
u1 = 0; v1 = ONE; u2 = m; v2 = c; |
| Line 1358 int inttorat(Z c,Z m,Z b,Z *nmp,Z *dnp) |
|
| Line 1370 int inttorat(Z c,Z m,Z b,Z *nmp,Z *dnp) |
|
| } |
} |
| if ( cmpz(v1,b) >= 0 ) return 0; |
if ( cmpz(v1,b) >= 0 ) return 0; |
| else { |
else { |
| if ( mpz_sgn(BDY(v1))<0 ) { |
/* reduction and check */ |
| chsgnz(v1,dnp); chsgnz(v2,nmp); |
/* v2/v1 = u2/u1, c*u1-u2 = 0 mod m? */ |
| |
gcdz(v1,v2,&t); |
| |
if ( UNIZ(t) ) { |
| |
u1 = v1; u2 = v2; r = 0; |
| } else { |
} else { |
| *dnp = v1; *nmp = v2; |
divsz(v1,t,&u1); divsz(v2,t,&u2); |
| |
mulz(c,u1,&t); subz(t,u2,&s); remz(s,m,&r); |
| } |
} |
| |
if ( r ) return 0; |
| |
if ( mpz_sgn(BDY(u1))<0 ) { |
| |
chsgnz(u1,dnp); chsgnz(u2,nmp); |
| |
} else { |
| |
*dnp = u1; *nmp = u2; |
| |
} |
| return 1; |
return 1; |
| } |
} |
| } |
} |
| |
|
| extern int f4_nocheck; |
extern int f4_nocheck; |
| |
|
| int mpz_gensolve_check(MAT mat,mpz_t **nm,mpz_t dn,int rank,int *rind,int *cind) |
int mpz_gensolve_check(MAT mat,mpz_t **nm,mpz_t dn,int rank,int clen,int *rind,int *cind) |
| { |
{ |
| int row,col,clen,i,j,k,l; |
int row,col,i,j,k,l; |
| mpz_t t; |
mpz_t t; |
| mpz_t *w; |
mpz_t *w; |
| Z *mati; |
Z *mati; |
| mpz_t *nmk; |
mpz_t *nmk; |
| |
|
| if ( f4_nocheck ) return 1; |
if ( f4_nocheck ) return 1; |
| row = mat->row; col = mat->col; clen = col-rank; |
row = mat->row; col = mat->col; |
| w = (mpz_t *)MALLOC(clen*sizeof(mpz_t)); |
w = (mpz_t *)MALLOC(clen*sizeof(mpz_t)); |
| mpz_init(t); |
mpz_init(t); |
| for ( i = 0; i < clen; i++ ) mpz_init(w[i]); |
for ( i = 0; i < clen; i++ ) mpz_init(w[i]); |
| Line 1469 void isqrtz(Z a,Z *r) |
|
| Line 1491 void isqrtz(Z a,Z *r) |
|
| Z two; |
Z two; |
| |
|
| if ( !a ) *r = 0; |
if ( !a ) *r = 0; |
| else if ( UNIQ(a) ) *r = ONE; |
else if ( UNIZ(a) ) *r = ONE; |
| else { |
else { |
| k = z_bits((Q)a); /* a <= 2^k-1 */ |
k = z_bits((Q)a); /* a <= 2^k-1 */ |
| bshiftz(ONE,-((k>>1)+(k&1)),&x); /* a <= x^2 */ |
bshiftz(ONE,-((k>>1)+(k&1)),&x); /* a <= x^2 */ |
| Line 1592 int generic_gauss_elim_hensel(MAT mat,MAT *nmmat,Z *dn |
|
| Line 1614 int generic_gauss_elim_hensel(MAT mat,MAT *nmmat,Z *dn |
|
| Z wq; |
Z wq; |
| |
|
| #if SIZEOF_LONG == 8 |
#if SIZEOF_LONG == 8 |
| return generic_gauss_elim_hensel64(mat,nmmat,dn,rindp,cindp); |
return generic_gauss_elim_hensel64(mat,nmmat,dn,rindp,cindp,0); |
| #endif |
#endif |
| init_eg(&eg_mul1); init_eg(&eg_mul2); |
init_eg(&eg_mul1); init_eg(&eg_mul2); |
| a0 = (Z **)mat->body; |
a0 = (Z **)mat->body; |
| Line 1706 get_eg(&tmp2); add_eg(&eg_mul2,&tmp1,&tmp2); |
|
| Line 1728 get_eg(&tmp2); add_eg(&eg_mul2,&tmp1,&tmp2); |
|
| if ( !cinfo[j] ) |
if ( !cinfo[j] ) |
| cind[k++] = j; |
cind[k++] = j; |
| return rank; |
return rank; |
| } |
} else |
| |
goto reset; |
| } else { |
} else { |
| |
reset: |
| period = period*3/2; |
period = period*3/2; |
| count = 0; |
count = 0; |
| } |
} |
| Line 1743 int generic_gauss_elim_hensel_dalg(MAT mat,DP *mb,MAT |
|
| Line 1767 int generic_gauss_elim_hensel_dalg(MAT mat,DP *mb,MAT |
|
| Z wq; |
Z wq; |
| DP m; |
DP m; |
| |
|
| |
#if SIZEOF_LONG == 8 |
| |
return generic_gauss_elim_hensel64(mat,nmmat,dn,rindp,cindp,mb); |
| |
#endif |
| a0 = (Z **)mat->body; |
a0 = (Z **)mat->body; |
| row = mat->row; col = mat->col; |
row = mat->row; col = mat->col; |
| w = (int **)almat(row,col); |
w = (int **)almat(row,col); |
| Line 1815 int generic_gauss_elim_hensel_dalg(MAT mat,DP *mb,MAT |
|
| Line 1842 int generic_gauss_elim_hensel_dalg(MAT mat,DP *mb,MAT |
|
| for ( i = 0; i < rank; i++ ) |
for ( i = 0; i < rank; i++ ) |
| for ( j = 0, bi = b[i], wi = wc[i]; j < ri; j++ ) |
for ( j = 0, bi = b[i], wi = wc[i]; j < ri; j++ ) |
| wi[j] = remqi((Q)bi[j],md); |
wi[j] = remqi((Q)bi[j],md); |
| /* wc = A^(-1)wc; wc is normalized */ |
/* wc = A^(-1)wc; wc is not normalized */ |
| solve_by_lu_mod(w,rank,md,wc,ri,1); |
solve_by_lu_mod(w,rank,md,wc,ri,0); |
| /* x += q*wc */ |
/* x += q*wc */ |
| for ( i = 0; i < rank; i++ ) |
for ( i = 0; i < rank; i++ ) |
| for ( j = 0, wi = wc[i]; j < ri; j++ ) mul1addtoz(q,wi[j],&x[i][j]); |
for ( j = 0, wi = wc[i]; j < ri; j++ ) mul1addtoz(q,wi[j],&x[i][j]); |
| Line 1829 int generic_gauss_elim_hensel_dalg(MAT mat,DP *mb,MAT |
|
| Line 1856 int generic_gauss_elim_hensel_dalg(MAT mat,DP *mb,MAT |
|
| mpz_init_set(uz,BDY(b[i][j])); |
mpz_init_set(uz,BDY(b[i][j])); |
| else |
else |
| mpz_init_set_ui(uz,0); |
mpz_init_set_ui(uz,0); |
| for ( k = 0; k < rank; k++ ) { |
for ( k = 0; k < rank; k++ ) |
| if ( a[i][k] && wc[k][j] ) { |
if ( a[i][k] && wc[k][j] ) |
| if ( wc[k][j] < 0 ) |
|
| mpz_addmul_ui(uz,BDY(a[i][k]),-wc[k][j]); |
|
| else |
|
| mpz_submul_ui(uz,BDY(a[i][k]),wc[k][j]); |
mpz_submul_ui(uz,BDY(a[i][k]),wc[k][j]); |
| } |
|
| } |
|
| MPZTOZ(uz,u); |
MPZTOZ(uz,u); |
| divsz(u,mdq,&b[i][j]); |
divsz(u,mdq,&b[i][j]); |
| } |
} |
| |
|
| count++; |
count++; |
| /* q = q*md */ |
/* q = q*md */ |
| mulz(q,mdq,&u); q = u; |
mulz(q,mdq,&u); q = u; |
| Line 1859 int generic_gauss_elim_hensel_dalg(MAT mat,DP *mb,MAT |
|
| Line 1882 int generic_gauss_elim_hensel_dalg(MAT mat,DP *mb,MAT |
|
| if ( !cinfo[j] ) |
if ( !cinfo[j] ) |
| cind[k++] = j; |
cind[k++] = j; |
| return rank; |
return rank; |
| } |
} else |
| |
goto reset; |
| } else { |
} else { |
| |
reset: |
| period = period*3/2; |
period = period*3/2; |
| count = 0; |
count = 0; |
| } |
} |
|
|
| for ( j = k = l = 0; j < col; j++ ) |
for ( j = k = l = 0; j < col; j++ ) |
| if ( colstat[j] ) rind[k++] = j; |
if ( colstat[j] ) rind[k++] = j; |
| else cind[l++] = j; |
else cind[l++] = j; |
| if ( mpz_gensolve_check(mat,num,den,rank,rind,cind) ) { |
if ( mpz_gensolve_check(mat,num,den,rank,col-rank,rind,cind) ) { |
| MKMAT(r,rank,col-rank); *nm = r; |
MKMAT(r,rank,col-rank); *nm = r; |
| for ( i = 0; i < rank; i++ ) |
for ( i = 0; i < rank; i++ ) |
| for ( j = 0; j < col-rank; j++ ) { |
for ( j = 0; j < col-rank; j++ ) { |
|
|
| } |
} |
| #endif |
#endif |
| |
|
| int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z *dn,int **rindp,int **cindp) |
int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z *dn,int **rindp,int **cindp,DP *mb) |
| { |
{ |
| MAT r; |
MAT r; |
| Z z; |
Z z; |
| Line 2151 int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z * |
|
| Line 2176 int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z * |
|
| int count; |
int count; |
| int ret; |
int ret; |
| int period; |
int period; |
| |
DP m; |
| |
|
| a0 = (Z **)mat->body; |
a0 = (Z **)mat->body; |
| row = mat->row; col = mat->col; |
row = mat->row; col = mat->col; |
| Line 2168 int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z * |
|
| Line 2194 int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z * |
|
| if ( DP_Print > 3 ) { |
if ( DP_Print > 3 ) { |
| fprintf(asir_out,"done.\n"); fflush(asir_out); |
fprintf(asir_out,"done.\n"); fflush(asir_out); |
| } |
} |
| |
|
| |
if ( mb ) { |
| |
/* this part is added for inv_or_split_dalg */ |
| |
for ( i = 0; i < col-1; i++ ) { |
| |
if ( !cinfo[i] ) { |
| |
m = mb[i]; |
| |
for ( j = i+1; j < col-1; j++ ) |
| |
if ( dp_redble(mb[j],m) ) |
| |
cinfo[j] = -1; |
| |
} |
| |
} |
| |
} |
| |
|
| a = (mpz_t **)mpz_allocmat(rank,rank); /* lhs mat */ |
a = (mpz_t **)mpz_allocmat(rank,rank); /* lhs mat */ |
| b = (mpz_t **)mpz_allocmat(rank,col-rank); |
b = (mpz_t **)mpz_allocmat(rank,col-rank); |
| for ( j = li = ri = 0; j < col; j++ ) |
for ( j = li = ri = 0; j < col; j++ ) |
| if ( cinfo[j] ) { |
if ( cinfo[j] > 0 ) { |
| /* the column is in lhs */ |
/* the column is in lhs */ |
| for ( i = 0; i < rank; i++ ) { |
for ( i = 0; i < rank; i++ ) { |
| w[i][li] = w[i][j]; |
w[i][li] = w[i][j]; |
| Line 2181 int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z * |
|
| Line 2220 int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z * |
|
| mpz_set_ui(a[i][li],0); |
mpz_set_ui(a[i][li],0); |
| } |
} |
| li++; |
li++; |
| } else { |
} else if ( !cinfo[j] ) { |
| /* the column is in rhs */ |
/* the column is in rhs */ |
| for ( i = 0; i < rank; i++ ) { |
for ( i = 0; i < rank; i++ ) { |
| if ( a0[rinfo[i]][j] ) |
if ( a0[rinfo[i]][j] ) |
| Line 2249 int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z * |
|
| Line 2288 int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z * |
|
| count++; |
count++; |
| /* q = q*md */ |
/* q = q*md */ |
| mpz_mul_ui(q,q,md); |
mpz_mul_ui(q,q,md); |
| fprintf(stderr,"."); |
|
| if ( count == period ) { |
if ( count == period ) { |
| ret = mpz_intmtoratm(x,rank,ri,q,nm,den); |
ret = mpz_intmtoratm(x,rank,ri,q,nm,den); |
| if ( ret ) { |
if ( ret ) { |
| for ( j = k = l = 0; j < col; j++ ) |
for ( j = k = l = 0; j < col; j++ ) |
| if ( cinfo[j] ) |
if ( cinfo[j] > 0 ) |
| rind[k++] = j; |
rind[k++] = j; |
| else |
else if ( !cinfo[j] ) |
| cind[l++] = j; |
cind[l++] = j; |
| ret = mpz_gensolve_check(mat,nm,den,rank,rind,cind); |
ret = mpz_gensolve_check(mat,nm,den,rank,ri,rind,cind); |
| if ( ret ) { |
if ( ret ) { |
| *rindp = rind; |
*rindp = rind; |
| *cindp = cind; |
*cindp = cind; |
| Line 2272 int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z * |
|
| Line 2310 int generic_gauss_elim_hensel64(MAT mat,MAT *nmmat,Z * |
|
| } |
} |
| MPZTOZ(den,*dn); |
MPZTOZ(den,*dn); |
| return rank; |
return rank; |
| } |
} else |
| |
goto reset; |
| } else { |
} else { |
| |
reset: |
| fprintf(stderr,"F"); |
fprintf(stderr,"F"); |
| period = period*3/2; |
period = period*3/2; |
| count = 0; |
count = 0; |