Groebner_HFE80/polynomial.cpp

225 lines
3.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "polynomial.h"
Polynomial::Polynomial()
{
mono.clear();
leader_order = -1;
degree = -1;
}
bool Polynomial::input(istream& in)
{
int state = 0; //0记录1记录变量编号2忽略3零单项式
char vari[D] = { 0 };
int vari_place = 0;
int now_vari = 0;
Monomial m;
bool first = true;
while (1)
{
char c;
in.get(c);
if (c == 'x')
{
state = 1;
first = false;
}
else if (c >= '0' && c <= '9')
{
if (state == 0) //单独的数字:奇数不做处理,偶数将该单项式置为零单项式
{
if (c % 2 == 0)
state = 3;
else
state = 4;
}
if (state == 1)
{
now_vari *= 10;
now_vari += c - '0';
}
first = false;
}
else if (c == '*')
{
state = 0;
vari[vari_place++] = now_vari;
now_vari = 0;
}
else if (c == '+')
{
if (state == 4)
{
m.from_factor(vari, vari_place);
mono.add(m.order);
}
else if (state != 3)
{
vari[vari_place++] = now_vari;
m.from_factor(vari, vari_place);
mono.add(m.order);
}
state = 0;
now_vari = 0;
vari_place = 0;
}
else if (c == '^')
{
state = 2;
}
else if (c == ' '); //不进行任何操作
else if (c == '\n' || c == '\r')
{
if (!first)
{
if (state == 4)
{
m.from_factor(vari, vari_place);
mono.add(m.order);
}
else if (state != 3)
{
vari[vari_place++] = now_vari;
m.from_factor(vari, vari_place);
mono.add(m.order);
}
state = 0;
now_vari = 0;
vari_place = 0;
}
else
{
state = 0;
now_vari = 0;
vari_place = 0;
}
break;
}
else
break;
}
set_leader_degree();
return !first;
}
void Polynomial::input_order(istream& in)
{
int max = -1;
while (!in.eof())
{
int temp = 0;
in >> temp;
if (temp != -1)
{
mono.set(temp);
if (max < temp)
max = temp;
}
else
break;
}
leader_order = max;
}
void Polynomial::print(ostream& out)
{
Monomial m;
bool first = true;
for (int i = M - 1; i >= 0; i--)
{
if (mono.get(i))
{
m.from_order(i);
if (!first)
out << '+';
else
first = false;
m.print(out);
}
}
out << endl;
}
void Polynomial::print_order(ostream& out)
{
for (int i = M - 1; i >= 0; i--)
{
if (mono.get(i))
out << setw(4) << i;
}
out << endl;
}
bool Polynomial::get(int n)
{
return mono.get(n);
}
void Polynomial::add(int n) //添加项序第n小的单项式如果该单项式已存在则抵消
{
mono.add(n); //将位图对应位置取反
}
void polynomial_mul(Polynomial& ret, Polynomial& p, Monomial& m)
{
Monomial mtemp;
for (int i = 0; i < M; i++)
{
if (p.get(i))
{
ret.add(mult_res[m.order][i]);
}
}
}
void Polynomial::set_leader_degree(int max_leader)
{
leader_order = mono.getleader();
if (leader_order != -1)
{
for (int i = 0; i <= D; i++)
{
degree = i;
if (leader_order < grevlex_degree_interval[i])
break;
}
}
else
{
degree = -1;
}
}
Polynomial& Polynomial::operator ^=(Polynomial& p)
{
this->mono.xor_part(p.mono, 0, (max(leader_order, p.leader_order) - 1) / 64 + 2);
set_leader_degree(max(this->leader_order, p.leader_order));
return *this;
}
Polynomial& Polynomial::operator ^=(Sparse_Polynomial& p)
{
for (int i = 0; i < p.length; i++)
{
mono.add(p.sparse_mono[i]);
}
set_leader_degree(max(this->leader_order, p.leader_order));
return *this;
}
bool Polynomial::iszero()
{
if (mono.data_len <= 0 || leader_order < 0)
return true;
return false;
}
Monomial Polynomial::get_leader()
{
Monomial ret;
ret.from_order(leader_order);
return ret;
}
bool operator > (Polynomial& p, Polynomial& q)
{
return p.mono > q.mono;
}
bool operator < (Polynomial& p, Polynomial& q)
{
return p.mono < q.mono;
}