ADD file via upload

This commit is contained in:
p04128795 2023-11-22 00:31:56 +08:00
parent e04c13cf0d
commit 5ae15858dd
1 changed files with 304 additions and 0 deletions

304
matrix.h Normal file
View File

@ -0,0 +1,304 @@
#ifndef MATRIX_H
#define MATRIX_H
#include "conf.h"
#include "polynomial.h"
#include "polynomial_store.h"
struct Matrix {
Polynomial* R[reductors];
Sparse_Polynomial* SR[reductors];
int R_leader[reductors];
bool R_sparse[reductors]; //0稠密1稀疏
Polynomial* E[MAX_POLYS];
int end_elim[MAX_POLYS];
int reductor_rows;
int elim_poly_rows;
int reductor_block; //当前消元块首块算法以64位为单位进行消元
int reductors_not_null;
int reduce_record[MAX_POLYS][reductors];
int reduce_record_len[MAX_POLYS];
int reduce_record_sparse[MAX_POLYS][reductors];
int reduce_record_sparse_len[MAX_POLYS];
inline Matrix()
{
clear();
}
inline int add_reductor(Store& ss, Temp_Polynomial_Store& ps_temp, int begin, int end, int mode = 1) //添加消元子
{
ps_temp.clear();
memset(R, 0, sizeof(R));
memset(SR, 0, sizeof(SR));
memset(R_sparse, 0, sizeof(R_sparse));
reductors_not_null = 0;
//int now_row = 0; //添加消元子到now_row行
if (mode == 1)
{
parallel_for(begin, end, [&](int i) {
int now_row = i - begin;
if (ss[i].type == 0)
{
R[now_row] = ss[i].poly;
SR[now_row] = NULL;
}
else if (ss[i].type == 1)
{
int set_type = ps_temp.set(ss[i].mul_poly, ss[i].mul_mono, now_row);
if (set_type == 1)
{
R[now_row] = ps_temp.get_dense(now_row);
SR[now_row] = NULL;
}
else
{
R[now_row] = NULL;
SR[now_row] = ps_temp.get_sparse(now_row);
R_sparse[now_row] = 1;
}
}
else
{
R[now_row] = NULL;
SR[now_row] = NULL;
}
R_leader[now_row] = i;
});
}
if (mode == 2) //得到既约Groebner基默认约化得到最少的多项式
{
parallel_for(begin, end, [&](int i) {
int now_row = i - begin;
if (ss[i].type == 1)
{
int set_type = ps_temp.set(ss[i].mul_poly, ss[i].mul_mono, now_row);
if (set_type == 1)
{
R[now_row] = ps_temp.get_dense(now_row);
SR[now_row] = NULL;
}
else
{
R[now_row] = NULL;
SR[now_row] = ps_temp.get_sparse(now_row);
R_sparse[now_row] = 1;
}
}
else
{
R[now_row] = NULL;
SR[now_row] = NULL;
}
R_leader[now_row] = i;
});
}
reductor_rows = end - begin;
reductor_block = begin / 64;
for (int i = 0; i < reductor_rows; i++)
{
if (R[i] != NULL || SR[i] != NULL)
{
reductors_not_null++;
}
}
return end - begin;
}
inline int add_elim_poly(Polynomial_Store& ps, int begin = 0, int end = M, int degree = D) //添加被消元多项式
{
memset(E, 0, sizeof(E));
int row = 0;
for (int i = begin; i < end; i++)
{
if (ps[i].degree > degree)
continue;
if (!ps[i].iszero()) //不导入零多项式
{
E[row] = &(ps[i]);
row++;
}
}
elim_poly_rows = row;
return row;
}
inline void clear()
{
memset(end_elim, 0, sizeof(end_elim));
memset(R, 0, sizeof(R));
memset(R_leader, 0, sizeof(R_leader));
memset(E, 0, sizeof(E));
memset(SR, 0, sizeof(SR));
memset(R_sparse, 0, sizeof(R_sparse));
reductor_rows = 0;
elim_poly_rows = 0;
reductor_block = 0;
}
inline Polynomial*& get_elim_poly(int n)
{
return E[n];
}
inline void Gauss_elimination()
{
/*
memset(reduce_record, 0, sizeof(reduce_record));
memset(reduce_record_len, 0, sizeof(reduce_record_len));
memset(reduce_record_sparse, 0, sizeof(reduce_record_sparse));
memset(reduce_record_sparse_len, 0, sizeof(reduce_record_sparse_len));
*/
//只将不初始化会引起错误的内存初始化,没有初始化的内存并不会被直接读取
memset(reduce_record_len, 0, elim_poly_rows * sizeof(int));
memset(reduce_record_sparse_len, 0, elim_poly_rows * sizeof(int));
if (reductors_not_null == reductors) //消元子满编:本部分不会产生新首项
{
parallel_for(0, elim_poly_rows, [&](int i) {
uint64* temp_block = E[i]->mono.data + reductor_block;
bool zero_block = true;
if (end_elim[i])
return; //跳出本次循环相当于for循环中的continue
for (int j = 0; j < reductors / 64; j++)
{
if (temp_block[j] != 0)
{
zero_block = false;
break;
}
}
if (zero_block)
return;
for (int j = reductor_rows - 1; j >= 0; j--)
{
if (temp_block[j / 64] & (1ull << (j % 64)))
{
if (R_sparse[j]) //该位置一定存在一个稀疏多项式
{
xor_sparse(*E[i], *SR[j]);
}
else
{
E[i]->xor_only(*R[j], 0, reductor_block + reductors / 64);
}
}
}
if (E[i]->mono.data_len > reductor_block)
E[i]->mono.data_len = reductor_block;
});
}
else
{
for (int i = 0; i < elim_poly_rows; i++)
{
int& temp_count = reduce_record_len[i];
int& sparse_count = reduce_record_sparse_len[i];
uint64 temp_block[reductors / 64] = { 0 };
bool zero_block = true;
for (int j = 0; j < reductors / 64; j++)
temp_block[j] = E[i]->mono.data[reductor_block + j];
if (end_elim[i])
continue;
for (int j = 0; j < reductors / 64; j++)
{
if (temp_block[j] != 0)
{
zero_block = false;
break;
}
}
for (int j = reductor_rows - 1; j >= 0; j--)
{
if (temp_block[j / 64] & (1ull << (j % 64)))
{
if (R_sparse[j]) //该位置一定存在一个稀疏多项式
{
for (int k = 0; k < reductors / 64; k++)
{
temp_block[k] ^= SR[j]->leader_block[k];
}
reduce_record_sparse[i][sparse_count] = j;
sparse_count++;
}
else
{
if (R[j] == NULL)
{
//该行会消元得出新首项,将其直接计算出
for (int k = 0; k < reduce_record_len[i]; k++)
{
E[i]->xor_only(*R[reduce_record[i][k]], 0, reductor_block + reductors / 64);
}
for (int k = 0; k < reduce_record_sparse_len[i]; k++)
{
xor_sparse(*E[i], *SR[reduce_record_sparse[i][k]]);
}
E[i]->set_leader_degree(reductor_block * 64 + reductors - 1);
R[j] = E[i];
reduce_record_len[i] = 0;
reduce_record_sparse_len[i] = 0;
end_elim[i] = true;
break;
}
else
{
for (int k = 0; k < reductors / 64; k++)
temp_block[k] ^= R[j]->mono.data[reductor_block + k];
//temp_block ^= R[j]->mono.data[reductor_block];
reduce_record[i][temp_count] = j;
temp_count++;
}
}
}
}
if (!end_elim[i])
{
if (E[i]->mono.data_len > reductor_block)
E[i]->mono.data_len = reductor_block;
}
}
parallel_for(0, 96, [&](int index) {
for (int i = 0; i < elim_poly_rows; i++)
{
for (int j = 0; j < reduce_record_len[i]; j++)
{
int blocks = reductor_block + reductors / 64;
E[i]->xor_only(*R[reduce_record[i][j]], index * blocks / 96, (index + 1) * blocks / 96);
}
}
});
parallel_for(0, 240, [&](int index) {
for (int i = index; i < elim_poly_rows; i += 240)
{
for (int j = 0; j < reduce_record_sparse_len[i]; j++)
{
xor_sparse(*E[i], *SR[reduce_record_sparse[i][j]]);
}
}
});
}
if (reductor_block == 0)
{
for (int i = 0; i < elim_poly_rows; i++)
{
if (!end_elim[i]) //说明该行已被消到0
{
E[i]->leader_order = -1;
}
}
}
}
inline int get_max_leader()
{
int max_leader = -1;
for (int i = 0; i < elim_poly_rows; i++)
{
if (E[i] != 0)
{
if (max_leader < E[i]->leader_order)
{
max_leader = E[i]->leader_order;
}
}
}
return max_leader;
}
};
#endif