Пример #1
0
/** \brief 整系数多项式的容度.
\param f 整系数多项式.
\param r 整数容度,包含正负号,使得本原部分lc为正整数.
*/
void UniContZ(mpz_ptr r,const poly_z & f)
{
	if(f.size()==0)
	{
		mpz_set_ui(r,1);
		return ;
	}
	mpz_set(r,f[f.size()-1]);
	if(f.size()==1)
	{
		return ;
	}
	int sign;
	sign=mpz_sgn(r);
	mpz_gcd(r,f[0],f[1]);
	if(mpz_cmp_ui(r,1)==0)
	{
		if(sign<0)mpz_neg(r,r);
		return ;
	}
	for(uint i=2;i<f.size();i++)
	{
		mpz_gcd(r,r,f[i]);
		if(mpz_cmp_ui(r,1)==0)
		{
			if(sign<0)mpz_neg(r,r);
			return ;
		}
	}
	if(sign<0)mpz_neg(r,r);
	return ;
}
Пример #2
0
bool factor_compare(const poly_z & f,const poly_z & g)
{
	if(f.size()<g.size())return 1;
	if(f.size()>g.size())return 0;
	for(size_t i=f.size()-1;i>=0;i--)
	{
		if(mpz_cmp(f[i],g[i])<0)return 1;
		if(mpz_cmp(f[i],g[i])>0)return 0;
	}
	return 0;
}
Пример #3
0
/** \brief 整系数多项式本原部分.
\param f 整系数多项式.
\param r 本原部分.
\return 本原部分,其lc为正整数.
*/
void UniPPZ(poly_z & r,const poly_z & f)
{
	mpz_t a;
	mpz_init(a);
	UniContZ(a,f);
	r.resize(f.size());
	for(size_t i=0;i<f.size();i++)
	{
		mpz_divexact(r[i],f[i],a);
	}
	mpz_clear(a);
}
Пример #4
0
/** \brief Fp域上多项式GCD.
\param f,g 域上多项式.
\param r 最大公因子.
\note Euclid算法.
*/
void UniGcdZp(poly_z & r,const poly_z & f,const poly_z & g,mpz_ptr p)
{
	poly_z u,v;
	poly_z q;
	copy_poly_z(u,f);
	copy_poly_z(v,g);
	while(v.size()> 0){
		UniDivModZp(q,r,u,v,p);
		UniPolynomialMod(r,r,p);
		u.resize(0);
		u=v;v=r;
		r=poly_z();
	}
	static mpz_t lc;
	mpz_init_set(lc,u[u.size()-1]);
	mpz_invert(lc,lc,p);
	r.resize(u.size());
	for(size_t i=0;i<u.size();i++)
	{
		mpz_mul(r[i],u[i],lc);
	}
	UniPolynomialMod(r,r,p);
	mpz_clear(lc);
	u.resize(0);v.resize(0);q.resize(0);
}
Пример #5
0
void poly_z_to_poly_fc(poly_fc & r, poly_z & f)
{
	r.resize(f.size());
	for(uint i=0;i<r.size();++i)
	{
		mpfc_set_z(r[i],f[i]);
	}
	return ;
}
Пример #6
0
/** \brief Fp域上多项式GCD.
\param f,g 域上多项式.
\param r,s,t 其中r为最大公因子,s,t为Bezout系数多项式.
*/
void UniGcdZp_Ext(poly_z & r,poly_z & s,poly_z & t,const poly_z & f,const poly_z & g,mpz_ptr p)
{
	poly_z u,v;
	poly_z q;
	poly_z s1,s2,t1,t2,l1,l2;
	copy_poly_z(u,f);
	copy_poly_z(v,g);
	s1.resize(1);mpz_set_si(s1[0],1);
	s2.resize(0);
	t1.resize(0);
	t2.resize(1);mpz_set_si(t2[0],1);
	while(v.size()> 0){
		UniDivModZp(q,r,u,v,p);
		UniPolynomialMod(r,r,p);
		UniMulZ(l1,q,t1);UniSubZ(l1,s1,l1);
		UniMulZ(l2,q,t2);UniSubZ(l2,s2,l2);
		u.resize(0);u=v;v=r;r=poly_z();
		s1.resize(0);s1=t1;t1=l1;l1=poly_z();
		s2.resize(0);s2=t2;t2=l2;l2=poly_z();
	}
	static mpz_t lc;
	mpz_init_set(lc,u[u.size()-1]);
	mpz_invert(lc,lc,p);
	r.resize(u.size());
	for(size_t i=0;i<u.size();i++)
	{
		mpz_mul(r[i],u[i],lc);
	}
	UniPolynomialMod(r,r,p);
	s.resize(s1.size());
	for(size_t i=0;i<s1.size();i++)
	{
		mpz_mul(s[i],s1[i],lc);
	}
	UniPolynomialMod(s,s,p);
	t.resize(s2.size());
	for(size_t i=0;i<s2.size();i++)
	{
		mpz_mul(t[i],s2[i],lc);
	}
	UniPolynomialMod(t,t,p);
	mpz_clear(lc);
	u.resize(0);v.resize(0);q.resize(0);s1.resize(0);s2.resize(0);t1.resize(0);t2.resize(0);l1.resize(0);l2.resize(0);
}
Пример #7
0
/** \brief 整系数多项式1-范数.
\param f 整系数多项式.
\return 系数向量的1-范数.
*/
void UniOneNormZ(mpz_ptr r,const poly_z & f)
{
	mpz_set_ui(r,0);
	static mpz_t temp;
	mpz_init(temp);
	for(int i=0;i<f.size();i++)
	{
		mpz_abs(temp,f[i]);
		mpz_add(r,r,temp);
	}
	mpz_clear(temp);
}
Пример #8
0
/** \brief 整系数多项式无穷范数.
\param f 整系数多项式.
\param r 系数向量的无穷范数.
*/
void UniMaxNormZ(mpz_ptr r,const poly_z & f)
{
	mpz_set_ui(r,0);
	mpz_t tempz;
	mpz_init(tempz);
	for(int i=0;i<f.size();i++)
	{
		mpz_abs(tempz,f[i]);
		if(mpz_cmp(r,tempz)<0)mpz_set(r,tempz);
	}
	mpz_clear(tempz);
	return ;
}
Пример #9
0
/** 
\brief 整系数多项式最大公因子.
\param f,g 整系数多项式.
\return 最大公因子.
\note 调用大素数算法或小素数算法.
*/
void UniGcdZ(poly_z & r,const poly_z & f,const poly_z & g)
{
	uint option=1;
	if(f.size()==0)
	{
		copy_poly_z(r,g);
		return ;
	}
	if(g.size()==0)
	{
		copy_poly_z(r,f);
		return ;
	}
	mpz_t contf,contg,b;
	mpz_init(contf);mpz_init(contg);mpz_init(b);
	UniContZ(contf,f);UniContZ(contg,g);
	mpz_gcd(b,contf,contg);
	poly_z _f,_g,h;
	UniPPZ(_f,f);UniPPZ(_g,g);
	int n=_f.deg(),m=_g.deg();
	if(n==0||m==0)
	{
		h.resize(1);
		mpz_set_ui(h[0],1);
	}
	else
	{
		if(n<m)UniGcdZ_SmallPrime1(h,_g,_f);
		else UniGcdZ_SmallPrime1(h,_f,_g);
	}
	r.resize(h.size());
	for(size_t i=0;i<h.size();i++)
	{
		mpz_mul(r[i],h[i],b);
	}
	_f.resize(0);_g.resize(0);h.resize(0);
	mpz_clear(contf);mpz_clear(contg);mpz_clear(b);
	return ;
}
Пример #10
0
/**
\brief 整系数多项式的整数根(不含重数).
\param f 整系数多项式.
\return 整根的list.
\note 利用Zp中的根.
*/
void UniZRootZ_ByZp(std::vector<mpz_ptr> & rootlist,const poly_z & f)
{
    static mpz_t A,B,p,z_temp,nA;
    mpz_init(A);
    mpz_init(B);
    mpz_init(p);
    mpz_init(z_temp);
    mpz_init(nA);
    UniMaxNormZ(A,f);
    uint n=f.size()-1;
    mpz_mul(B,A,A);
    mpz_add(B,B,A);
    mpz_mul_ui(B,B,2*n);
    mpz_add_ui(p,B,1);
    mpz_nextprime(p,p);
    poly_z fp,vi,ui;
    std::vector<mpz_ptr> ulist;
    uint totalroot=0;
    UniPolynomialMod(fp,f,p);
    UniZpRootZp(ulist,fp,p);
    mpz_mul_ui(nA,A,n);
    ui.resize(2);
    mpz_set_ui(ui[1],1);
    for(uint i=0; i<ulist.size(); i++)
    {
        if(mpz_cmpabs(ulist[i],A)<=0)
        {
            mpz_neg(ui[0],ulist[i]);
            UniDivZp(vi,fp,ui,p);
            UniMaxNormZ(z_temp,vi);
            if(mpz_cmp(z_temp,nA)<=0)
            {
                totalroot++;
                resize_z_list(rootlist,totalroot);
                mpz_set(rootlist[totalroot-1],ulist[i]);
            }
        }
    }
    mpz_clear(A);
    mpz_clear(B);
    mpz_clear(p);
    mpz_clear(z_temp);
    mpz_clear(nA);
    fp.resize(0);
    vi.resize(0);
    ui.resize(0);
    resize_z_list(ulist,0);
    std::sort(rootlist.begin(),rootlist.end(),mpz_ptr_less);
    return ;
}
Пример #11
0
void UniEqlDegFacZp(std::vector<poly_z> & eqlfactorlist,const poly_z & f,mpz_ptr p,uint d,uint & current)
{
	uint n=f.size()-1;
	if(n==d)
	{
		copy_poly_z(eqlfactorlist[current],f);
		current++;
		return ;
	}
	poly_z g,h;
	while(1)
	{
		UniEqlDegFacZp_Odd(g,f,p,d);
		if(g.size()>=d)break;
	}
	UniEqlDegFacZp(eqlfactorlist,g,p,d,current);
	UniDivZp(h,f,g,p);
	UniEqlDegFacZp(eqlfactorlist,h,p,d,current);
	g.resize(0);h.resize(0);
	return ;
}
Пример #12
0
//todo using iterated frobenius alg. to improve it?
void UniEqlDegFacZp_Odd(poly_z & factor,const poly_z & f,mpz_ptr p,uint d)
{
	uint deg_bound=f.size()-2;
	poly_z a;
	while(1)
	{
		UniRandomZp(a,deg_bound,p);
		if(a.size()>1)break;
	}
	UniGcdZp(factor,a,f,p);
	if(factor.size()>1&&factor.size()<f.size())
	{
		a.resize(0);
		return ;
	}

	power_specially_for_eqldegfactorization(a,f,p,d);

	//static mpz_t exp;
	//mpz_init(exp);
	//mpz_pow_ui(exp,p,d);
	//mpz_sub_ui(exp,exp,1);
	//mpz_divexact_ui(exp,exp,2);
	//PowerMod(a,exp,f,p);
	//mpz_clear(exp);

	mpz_sub_ui(a[0],a[0],1);
	UniGcdZp(factor,a,f,p);
	if(factor.size()>1&&factor.size()<f.size())
	{
		a.resize(0);
		return; 
	}
	a.resize(0);
	factor.resize(0);
	return ;
}
Пример #13
0
/** 
\brief 整系数多项式最大公因子.
\param f,g 整系数本原多项式,且\f$\deg f=n\ge\deg g\ge 1\f$.
\param r 最大公因子.
\note 小素数模方法.
\todo 理论文档此处有误.
*/
void UniGcdZ_SmallPrime1(poly_z & r,const poly_z & f,const poly_z & g)
{
	poly_z fp,gp,vp,v1;
	poly_z fstar,gstar;
	mpz_t c,s,t;
	mpz_init(c);mpz_init(s);mpz_init(t);
	mpz_t A,b,B,z_temp,k,p_bound,p,p_low_bound,p1,B2;
	mpf_t float_temp;
	mpz_init(A);mpz_init(b);mpz_init(B);mpz_init(z_temp);mpz_init(k);mpz_init(p_bound);mpz_init(p);mpz_init(p1);mpz_init(p_low_bound);mpf_init(float_temp);mpz_init(B2);
	UniMaxNormZ(A,f);UniMaxNormZ(b,g);
	int n=f.size()-1,m=g.size()-1;
	if(mpz_cmp(A,b)<0)mpz_set(A,b);
	mpz_gcd(b,f[n],g[m]);
	mpz_ui_pow_ui(B,2,n);
	mpz_mul(B,B,A);
	mpz_mul(B,B,b);
	mpf_sqrt_ui(float_temp,n+1);
	mpz_set_f(z_temp,float_temp);
	mpz_mul(B,B,z_temp);
	mpz_mul_ui(B2,B,2);
	mpz_set_si(z_temp,n);
	int tempint;
	tempint=2*n*mpz_sizeinbase(z_temp,2)+2*mpz_sizeinbase(b,2)+4*n*mpz_sizeinbase(A,2);
	//tempint=2*n*Modules::NumberTheory::IntegerLength(Z(n),2)+2*Modules::NumberTheory::IntegerLength(b,2)+4*n*Modules::NumberTheory::IntegerLength(A,2);
	mpz_set_si(k,tempint);
	mpz_mul_ui(p_bound,k,2);
	mpz_mul_ui(p_bound,p_bound,mpz_sizeinbase(k,2));
	mpz_set_ui(p_low_bound,3);
	fstar.resize(n+1);
	for(size_t i=0;i<=n;i++)
	{
		mpz_mul(fstar[i],f[i],b);
	}
	gstar.resize(m+1);
	for(size_t i=0;i<=m;i++)
	{
		mpz_mul(gstar[i],g[i],b);
	}
	while(1)
	{
		while(1)
		{
			random::randominteger(p,p_low_bound,p_bound);
			if(mpz_probab_prime_p(p,10)>0&&mpz_divisible_p(b,p)==0)break;
		}
		UniPolynomialMod(fp,f,p);
		UniPolynomialMod(gp,g,p);
		UniGcdZp(vp,fp,gp,p);
		if(vp.size()==1)
		{
			r.resize(1);
			mpz_set_si(r[0],1);
			fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
			fstar.resize(0);gstar.resize(0);
			mpz_clear(c);mpz_clear(s);mpz_clear(t);
			mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
			return ;
		}
		mpz_set(p1,p);
		copy_poly_z(v1,vp);
		while(mpz_cmp(p1,B2)<0)
		{
			while(1)
			{
				random::randominteger(p,p_low_bound,p_bound);
				if(mpz_probab_prime_p(p,10)>0&&mpz_divisible_p(b,p)==0)break;
			}
			UniPolynomialMod(fp,f,p);
			UniPolynomialMod(gp,g,p);
			UniGcdZp(vp,fp,gp,p);
			if(vp.size()==1)
			{
				r.resize(1);
				mpz_set_si(r[0],1);
				fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
				fstar.resize(0);gstar.resize(0);
				mpz_clear(c);mpz_clear(s);mpz_clear(t);
				mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
				return ;
			}
			if(vp.size()<v1.size())
			{
				mpz_set(p1,p);
				copy_poly_z(v1,vp);
				continue;
			}
			if(vp.size()==v1.size())
			{
				mpz_gcdext(c,s,t,p1,p);
				mpz_mul(t,p,t);
				mpz_mul(s,p1,s);
				mpz_mul(p1,p1,p);
				for(size_t i=0;i<vp.size();i++)
				{
					mpz_mul(c,v1[i],t);
					mpz_addmul(c,vp[i],s);
					mpz_set(v1[i],c);
				}
				UniPolynomialMod(v1,v1,p1);
			}
		}
		for(size_t i=0;i<v1.size();i++)mpz_mul(v1[i],v1[i],b);
		UniPolynomialMod(v1,v1,p1);
		if(poly_z_divisible(fstar,v1)&&poly_z_divisible(gstar,v1))
		{
			UniPPZ(r,v1);break;
		}
	}
	fp.resize(0);gp.resize(0);vp.resize(0);v1.resize(0);
	fstar.resize(0);gstar.resize(0);
	mpz_clear(c);mpz_clear(s);mpz_clear(t);
	mpz_clear(A);mpz_clear(b);mpz_clear(B);mpz_clear(z_temp);mpz_clear(k);mpz_clear(p_bound);mpz_clear(p);mpz_clear(p1);mpz_clear(p_low_bound);mpf_clear(float_temp);
	return ;
}
Пример #14
0
/**
\brief Berlekamp算法.
\param f 有限域上多项式.monic
\param p characteristic. small prime
\param faclist 返回因子list.
*/
void BerlekampZp_SmallPrime(const poly_z & f,mpz_ptr p,std::vector<poly_z> & faclist)
{
	int n=f.size()-1;
	clear_poly_z_list(faclist);
	std::vector<poly_int> basis_int;
	int k,r;
	mat_int matq;
	int p_int=mpz_get_si(p);
	poly_int f_int;
	poly_z_to_poly_int(f_int,f);
	//str("matrix begin").print();
	UniPetriMatrixZp_SmallPrime(matq,f_int,p_int);

	//for(int i=0;i<n;i++)
	//{
	//	for(int j=0;j<n;j++)
	//	{
	//		std::cout<<matq[i][j]<<" ";
	//	}
	//	std::cout<<"\n";
	//}

	//str("matrix end").print();
	for(int i=0;i<n;i++)matq[i][i]=matq[i][i]-1;
	NullSpaceZp_SmallPrime(basis_int,matq,n,p_int);
	//str("nullspace end").print();

	r=basis_int.size();
	//for(size_t i=0;i<r;i++)
	//{
	//	poly_z test;
	//	poly_int_to_poly_z(test,basis_int[i]);
	//	test.print();
	//}
	//
	mat_int result_int;
	poly_int bk_int,g_int;
	int a_int;
	int r_temp;
	result_int.push_back(f_int);
	while(result_int.size()<r)
	{
		random::randominteger(k,0,r-1);
		bk_int=basis_int[k];
		random::randominteger(a_int,0,p_int-1);
		if(bk_int.size()<=1)continue;
		bk_int[0]-=a_int;
		r_temp=result_int.size();
		for(int i=0;i<r_temp;i++)
		{
			UniGcdZp_SmallPrime(g_int,bk_int,result_int[i],p_int);
			if(g_int.size()>1&&result_int[i].size()>g_int.size())
			{
				UniDivZp_SmallPrime(result_int[i],result_int[i],g_int,p_int);
				result_int.push_back(g_int);
			}
		}
	}
	faclist.resize(r);
	for(size_t i=0;i<r;i++)
	{
		poly_int_to_poly_z(faclist[i],result_int[i]);
	}
	//str("berlekamp end").print();
}