/* This auxiliary subroutine performs a smaller dgemm operation * C := C + A * B * where C is M-by-N, A is M-by-K, and B is K-by-N. */ static inline void do_block (int lda, int M, int N, int K, double* A, double* B, double* C, double* A_block, double* B_block) { //double A_block[M*K], B_block[K*N]; //double *A_block, *B_block; double *a_ptr, *b_ptr, *c; int residue1 = M % 4; int residue2 = N % 4; int M_floor = M - residue1; int N_floor = N - residue2; int i = 0, j = 0, p = 0; /* For each column of B */ for (j = 0 ; j < N_floor; j += 4) { b_ptr = &B_block[K * j]; // copy and transpose B_block copy_b(lda, K, B + j*lda, b_ptr); /* For each row of A */ for (i = 0; i < M_floor; i += 4) { a_ptr = &A_block[i * K]; if (j == 0){ copy_a(lda, K, A + i, a_ptr); } c = C + i + j*lda; matmul_4xkxkx4(lda, K, a_ptr, b_ptr, c); } } if (residue1 != 0) { /* For each row of A */ for ( ; i < M; ++i) /* For each column of B */ for (p = 0; p < N; ++p) { /* Compute C[i,j] */ double c_ip = ARRAY(C,i,p); for (int k = 0; k < K; ++k) c_ip += ARRAY(A,i,k) * ARRAY(B,k,p); ARRAY(C,i,p) = c_ip; } } if (residue2 != 0) { /* For each column of B */ for ( ; j < N; ++j) /* For each row of A */ for (i = 0; i < M_floor; ++i) { /* Compute C[i,j] */ double cij = ARRAY(C,i,j); for (int k = 0; k < K; ++k) cij += ARRAY(A,i,k) * ARRAY(B,k,j); ARRAY(C,i,j) = cij; } } }
Polynom Matrix::SolveLinearEquationSystem(const Matrix & A, const Polynom & b) { Polynom copy_b(b), result; Matrix copy_A(A); copy_A.gausRightDiagForEquation(copy_b); // перестановка битов в противоположном порядке (можно будет избавиться если приводить к главной диагоняли) for(uint i = 0; i < copy_A.RowCount; i++) result.setBit(i, copy_b.getBit(copy_A.RowCount - i - 1)); return result; }
//****************************** Операция вычитания ************************************** NumberVector operator-(const NumberVector &a, const NumberVector &b) { NumberVector result, copy_a(a), copy_b(b); return result.Sub(copy_a, copy_b); }
PolynomN6& PolynomN6::Mul(PolynomN6 &a, PolynomN6 &b) { if(a.getModulePolynom() != b.getModulePolynom() || a.getModule() != b.getModule()) throw std::out_of_range("модулярные многочлены должны быть равны"); _modulePolynom = a._modulePolynom; _module = a._module; PolynomN6 copy_a(a), copy_b(b); PolynomGF3 c6Coef, c7Coef,c8Coef, c9Coef, c10Coef, temp1, temp2,temp3,temp4,temp5,temp6,temp7,temp8,temp9,temp10; PolynomGF3 module(_module),modulePolynom(_modulePolynom); // умножение многочленов и приведение по модулю _a1.ModMul(copy_a._a1, copy_b._a1, module); temp1.ModMul(copy_a._a1, copy_b._a2, module); temp2.ModMul(copy_a._a2, copy_b._a1, module); _a2.ModAdd(temp1, temp2, module); temp1.ModMul(copy_a._a1, copy_b._a3, module); temp2.ModMul(copy_a._a2, copy_b._a2, module); temp3.ModMul(copy_a._a3, copy_b._a1, module); temp4.ModAdd(temp1,temp2,module); _a3.ModAdd(temp4,temp3,module); temp1.ModMul(copy_a._a1, copy_b._a4, module); temp2.ModMul(copy_a._a2, copy_b._a3, module); temp3.ModMul(copy_a._a3, copy_b._a2, module); temp4.ModMul(copy_a._a4, copy_b._a1, module); temp5.ModAdd(temp1,temp2,module); temp6.ModAdd(temp3,temp4,module); _a4.ModAdd(temp5,temp6,module); temp1.ModMul(copy_a._a1, copy_b._a5, module); temp2.ModMul(copy_a._a2, copy_b._a4, module); temp3.ModMul(copy_a._a3, copy_b._a3, module); temp4.ModMul(copy_a._a4, copy_b._a2, module); temp5.ModMul(copy_a._a5, copy_b._a1, module); temp6.ModAdd(temp1,temp2,module); temp7.ModAdd(temp3,temp4,module); temp8.ModAdd(temp5,temp6,module); _a5.ModAdd(temp7,temp8,module); temp1.ModMul(copy_a._a1, copy_b._a6, module); temp2.ModMul(copy_a._a2, copy_b._a5, module); temp3.ModMul(copy_a._a3, copy_b._a4, module); temp4.ModMul(copy_a._a4, copy_b._a3, module); temp5.ModMul(copy_a._a5, copy_b._a2, module); temp6.ModMul(copy_a._a6, copy_b._a1, module); temp7.ModAdd(temp1, temp2, module); temp8.ModAdd(temp3, temp4, module); temp9.ModAdd(temp5, temp6, module); temp10.ModAdd(temp7, temp8, module); _a6.ModAdd(temp9,temp10,module); temp1.ModMul(copy_a._a2, copy_b._a6, module); temp2.ModMul(copy_a._a3, copy_b._a5, module); temp3.ModMul(copy_a._a4, copy_b._a4, module); temp4.ModMul(copy_a._a5, copy_b._a3, module); temp5.ModMul(copy_a._a6, copy_b._a2, module); temp6.ModAdd(temp1,temp2,module); temp7.ModAdd(temp3,temp4,module); temp8.ModAdd(temp5,temp6,module); c6Coef.ModAdd(temp7,temp8,module); temp1.ModMul(copy_a._a3, copy_b._a6, module); temp2.ModMul(copy_a._a4, copy_b._a5, module); temp3.ModMul(copy_a._a5, copy_b._a4, module); temp4.ModMul(copy_a._a6, copy_b._a3, module); temp5.ModAdd(temp1,temp2,module); temp6.ModAdd(temp3,temp4,module); c7Coef.ModAdd(temp5,temp6,module); temp1.ModMul(copy_a._a4, copy_b._a6, module); temp2.ModMul(copy_a._a5, copy_b._a5, module); temp3.ModMul(copy_a._a6, copy_b._a4, module); temp4.ModAdd(temp1,temp2,module); c8Coef.ModAdd(temp4,temp3,module); temp1.ModMul(copy_a._a5, copy_b._a6, module); temp2.ModMul(copy_a._a6, copy_b._a5, module); c9Coef.ModAdd(temp1, temp2, module); c10Coef.ModMul(copy_a._a6, copy_b._a6, module); if(c10Coef.isZero() && c9Coef.isZero() && c8Coef.isZero()&&c7Coef.isZero()&&c6Coef.isZero()) return *this; // редуцирование //s-i-1 Polynom one("1"); if((((modulePolynom.A1>>(5))&one).isOne())) c9Coef.ModAdd(c9Coef, c10Coef, module); if((((modulePolynom.A0>>(5))&one).isOne())) c9Coef.ModAdd(c9Coef, c10Coef+c10Coef, module); if((((modulePolynom.A1>>(4))&one).isOne())) c8Coef.ModAdd(c8Coef, c10Coef, module); if((((modulePolynom.A0>>(4))&one).isOne())) c8Coef.ModAdd(c8Coef, c10Coef+c10Coef, module); if((((modulePolynom.A1>>(3))&one).isOne())) c7Coef.ModAdd(c7Coef, c10Coef, module); if((((modulePolynom.A0>>(3))&one).isOne())) c7Coef.ModAdd(c7Coef, c10Coef+c10Coef, module); if((((modulePolynom.A1>>(2))&one).isOne())) c6Coef.ModAdd(c6Coef, c10Coef, module); if((((modulePolynom.A0>>(2))&one).isOne())) c6Coef.ModAdd(c6Coef, c10Coef+c10Coef, module); if((((modulePolynom.A1>>(1))&one).isOne())) _a6.ModAdd(_a6, c10Coef, module); if((((modulePolynom.A0>>(1))&one).isOne())) _a6.ModAdd(_a6, c10Coef+c10Coef, module); if((((modulePolynom.A1>>(0))&one).isOne())) _a5.ModAdd(_a5, c10Coef, module); if((((modulePolynom.A0>>(0))&one).isOne())) _a5.ModAdd(_a5, c10Coef+c10Coef, module); if(c9Coef.isZero() && c8Coef.isZero()&&c7Coef.isZero()&&c6Coef.isZero()) return *this; if((((modulePolynom.A1>>(5))&one).isOne())) c8Coef.ModAdd(c8Coef, c9Coef, module); if((((modulePolynom.A0>>(5))&one).isOne())) c8Coef.ModAdd(c8Coef, c9Coef+c9Coef, module); if((((modulePolynom.A1>>(4))&one).isOne())) c7Coef.ModAdd(c7Coef, c9Coef, module); if((((modulePolynom.A0>>(4))&one).isOne())) c7Coef.ModAdd(c7Coef, c9Coef+c9Coef, module); if((((modulePolynom.A1>>(3))&one).isOne())) c6Coef.ModAdd(c6Coef, c9Coef, module); if((((modulePolynom.A0>>(3))&one).isOne())) c6Coef.ModAdd(c6Coef, c9Coef+c9Coef, module); if((((modulePolynom.A1>>(2))&one).isOne())) _a6.ModAdd(_a6, c9Coef, module); if((((modulePolynom.A0>>(2))&one).isOne())) _a6.ModAdd(_a6, c9Coef+c9Coef, module); if((((modulePolynom.A1>>(1))&one).isOne())) _a5.ModAdd(_a5, c9Coef, module); if((((modulePolynom.A0>>(1))&one).isOne())) _a5.ModAdd(_a5, c9Coef+c9Coef, module); if((((modulePolynom.A1>>(0))&one).isOne())) _a4.ModAdd(_a4, c9Coef, module); if((((modulePolynom.A0>>(0))&one).isOne())) _a4.ModAdd(_a4, c9Coef+c9Coef, module); if(c8Coef.isZero()&&c7Coef.isZero()&&c6Coef.isZero()) return *this; if((((modulePolynom.A1>>(5))&one).isOne())) c7Coef.ModAdd(c7Coef, c8Coef, module); if((((modulePolynom.A0>>(5))&one).isOne())) c7Coef.ModAdd(c7Coef, c8Coef+c8Coef, module); if((((modulePolynom.A1>>(4))&one).isOne())) c6Coef.ModAdd(c6Coef, c8Coef, module); if((((modulePolynom.A0>>(4))&one).isOne())) c6Coef.ModAdd(c6Coef, c8Coef+c8Coef, module); if((((modulePolynom.A1>>(3))&one).isOne())) _a6.ModAdd(_a6, c8Coef, module); if((((modulePolynom.A0>>(3))&one).isOne())) _a6.ModAdd(_a6, c8Coef+c8Coef, module); if((((modulePolynom.A1>>(2))&one).isOne())) _a5.ModAdd(_a5, c8Coef, module); if((((modulePolynom.A0>>(2))&one).isOne())) _a5.ModAdd(_a5, c8Coef+c8Coef, module); if((((modulePolynom.A1>>(1))&one).isOne())) _a4.ModAdd(_a4, c8Coef, module); if((((modulePolynom.A0>>(1))&one).isOne())) _a4.ModAdd(_a4, c8Coef+c8Coef, module); if((((modulePolynom.A1>>(0))&one).isOne())) _a3.ModAdd(_a3, c8Coef, module); if((((modulePolynom.A0>>(0))&one).isOne())) _a3.ModAdd(_a3, c8Coef+c8Coef, module); if(c7Coef.isZero()&&c6Coef.isZero()) return *this; if((((modulePolynom.A1>>(5))&one).isOne())) c6Coef.ModAdd(c6Coef, c7Coef, module); if((((modulePolynom.A0>>(5))&one).isOne())) c6Coef.ModAdd(c6Coef, c7Coef+c7Coef, module); if((((modulePolynom.A1>>(4))&one).isOne())) _a6.ModAdd(_a6, c7Coef, module); if((((modulePolynom.A0>>(4))&one).isOne())) _a6.ModAdd(_a6, c7Coef+c7Coef, module); if((((modulePolynom.A1>>(3))&one).isOne())) _a5.ModAdd(_a5, c7Coef, module); if((((modulePolynom.A0>>(3))&one).isOne())) _a5.ModAdd(_a5, c7Coef+c7Coef, module); if((((modulePolynom.A1>>(2))&one).isOne())) _a4.ModAdd(_a4, c7Coef, module); if((((modulePolynom.A0>>(2))&one).isOne())) _a4.ModAdd(_a4, c7Coef+c7Coef, module); if((((modulePolynom.A1>>(1))&one).isOne())) _a3.ModAdd(_a3, c7Coef, module); if((((modulePolynom.A0>>(1))&one).isOne())) _a3.ModAdd(_a3, c7Coef+c7Coef, module); if((((modulePolynom.A1>>(0))&one).isOne())) _a2.ModAdd(_a2, c7Coef, module); if((((modulePolynom.A0>>(0))&one).isOne())) _a2.ModAdd(_a2, c7Coef+c7Coef, module); if(c6Coef.isZero()) return *this; if((((modulePolynom.A1>>(5))&one).isOne())) _a6.ModAdd(_a6, c6Coef, module); if((((modulePolynom.A0>>(5))&one).isOne())) _a6.ModAdd(_a6, c6Coef+c6Coef, module); if((((modulePolynom.A1>>(4))&one).isOne())) _a5.ModAdd(_a5, c6Coef, module); if((((modulePolynom.A0>>(4))&one).isOne())) _a5.ModAdd(_a5, c6Coef+c6Coef, module); if((((modulePolynom.A1>>(3))&one).isOne())) _a4.ModAdd(_a4, c6Coef, module); if((((modulePolynom.A0>>(3))&one).isOne())) _a4.ModAdd(_a4, c6Coef+c6Coef, module); if((((modulePolynom.A1>>(2))&one).isOne())) _a3.ModAdd(_a3, c6Coef, module); if((((modulePolynom.A0>>(2))&one).isOne())) _a3.ModAdd(_a3, c6Coef+c6Coef, module); if((((modulePolynom.A1>>(1))&one).isOne())) _a2.ModAdd(_a2, c6Coef, module); if((((modulePolynom.A0>>(1))&one).isOne())) _a2.ModAdd(_a2, c6Coef+c6Coef, module); if((((modulePolynom.A1>>(0))&one).isOne())) _a1.ModAdd(_a1, c6Coef, module); if((((modulePolynom.A0>>(0))&one).isOne())) _a1.ModAdd(_a1, c6Coef+c6Coef, module); return *this; }
PolynomN6 operator*(const PolynomN6 &a, const PolynomN6 &b) { PolynomN6 result, copy_a(a), copy_b(b); return result.Mul(copy_a, copy_b); }