version 1.7, 2001/10/09 01:36:11 |
version 1.8, 2002/08/08 10:57:01 |
|
|
* DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, |
* DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE, |
* PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. |
* PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE. |
* |
* |
* $OpenXM: OpenXM_contrib2/asir2000/engine/Q.c,v 1.6 2000/12/08 06:43:10 noro Exp $ |
* $OpenXM: OpenXM_contrib2/asir2000/engine/Q.c,v 1.7 2001/10/09 01:36:11 noro Exp $ |
*/ |
*/ |
#include "ca.h" |
#include "ca.h" |
#include "base.h" |
#include "base.h" |
Line 415 void mkwcm(int k,int l,int m,int *t) |
|
Line 415 void mkwcm(int k,int l,int m,int *t) |
|
} |
} |
} |
} |
|
|
|
#if 0 |
void factorial(int n,Q *r) |
void factorial(int n,Q *r) |
{ |
{ |
Q t,iq,s; |
Q t,iq,s; |
Line 437 void factorial(int n,Q *r) |
|
Line 438 void factorial(int n,Q *r) |
|
} |
} |
*r = t; |
*r = t; |
} |
} |
|
} |
|
#endif |
|
|
|
void partial_factorial(int s,int e,N *r); |
|
|
|
void factorial(int n,Q *r) |
|
{ |
|
N nm; |
|
|
|
if ( !n ) |
|
*r = ONE; |
|
else if ( n < 0 ) |
|
*r = 0; |
|
else { |
|
partial_factorial(1,n,&nm); |
|
NTOQ(nm,1,*r); |
|
} |
|
} |
|
|
|
/* s*(s+1)*...*e */ |
|
void partial_factorial(int s,int e,N *r) |
|
{ |
|
unsigned int len,i,m,m0,c; |
|
unsigned int *p,*p1,*p2; |
|
N nm,r1,r2; |
|
|
|
/* XXX */ |
|
if ( e-s > 2000 ) { |
|
m = (e+s)/2; |
|
partial_factorial(s,m,&r1); |
|
partial_factorial(m+1,e,&r2); |
|
kmuln(r1,r2,r); |
|
return; |
|
} |
|
/* find i s.t. 2^(i-1) < m <= 2^i */ |
|
for ( i = 0, m = 1; m < e; m <<=1, i++ ); |
|
/* XXX estimate of word length of the result */ |
|
len = (i*(e-s+1)+1+31)/32; |
|
p = ALLOCA(len*sizeof(int)); |
|
p1 = ALLOCA(len*sizeof(int)); |
|
p[0] = s; |
|
len = 1; |
|
for ( i = s+1; (int)i <= e; ) { |
|
for ( m0 = m = 1, c = 0; ((int)i <= e) && !c; i++ ) { |
|
m0 = m; DM(m0,i,c,m) |
|
} |
|
if ( c ) { |
|
m = m0; i--; |
|
} |
|
bzero(p1,(len+1)*sizeof(int)); |
|
muln_1(p,len,m,p1); |
|
if ( p1[len] ) |
|
len++; |
|
p2 = p; p = p1; p1 = p2; |
|
} |
|
*r = nm = NALLOC(len); |
|
bcopy(p,BD(nm),sizeof(int)*len); |
|
PL(nm) = len; |
} |
} |
|
|
void invl(Q a,Q mod,Q *ar) |
void invl(Q a,Q mod,Q *ar) |