| 6 | // subroutines for the LLL-algorithms |
| 7 | |
| 8 | void REDI_KB(const short& k, const short& l, BigInt** b, |
| 9 | const short& number_of_vectors, const short& vector_dimension, |
| 10 | BigInt** H, BigInt* d, BigInt** lambda) |
| 11 | // the REDI procedure for relations(...) (to compute the Kernel Basis, |
| 12 | // algorithm 2.7.2 in Cohen's book) |
| 13 | { |
| 14 | #ifdef GMP |
| 15 | if(abs(BigInt(2)*lambda[k][l])<=d[l+1]) |
| 16 | #else // GMP |
| 17 | if(labs(2*lambda[k][l])<=d[l+1]) |
| 18 | // labs is the abs-function for long ints |
| 19 | #endif // GMP |
| 20 | return; |
| 21 | |
| 22 | #ifdef GMP |
| 23 | BigInt q=(BigInt(2)*lambda[k][l]+d[l+1])/(BigInt(2)*d[l+1]); |
| 24 | #else // GMP |
| 25 | long q=(long int) floor(((float)(2*lambda[k][l]+d[l+1]))/(2*d[l+1])); |
| 26 | #endif // GMP |
| 27 | |
| 28 | // q is the integer quotient of the division |
| 29 | // (2*lambda[k][l]+d[l+1])/(2*d[l+1]). |
| 30 | // Because of the rounding mode (always towards zero) of GNU C++, |
| 31 | // we cannot use the built-in integer division |
| 32 | // here; it causes errors when dealing with negative numbers. Therefore |
| 33 | // the complicated casts: The divident is first casted to a float which |
| 34 | // causes the division result to be a float. This result is explicitly |
| 35 | // rounded downwards. As the floor-function returns a double (for range |
| 36 | // reasons), this has to be casted to an integer again. |
| 37 | |
| 38 | for(short n=0;n<number_of_vectors;n++) |
| 39 | H[k][n]-=q*H[l][n]; |
| 40 | // H[k]=H[k]-q*H[l] |
| 41 | |
| 42 | for(short m=0;m<vector_dimension;m++) |
| 43 | b[k][m]-=q*b[l][m]; |
| 44 | // b[k]=b[k]-q*b[l] |
| 45 | |
| 46 | lambda[k][l]-=q*d[l+1]; |
| 47 | |
| 48 | for(short i=0;i<=l-1;i++) |
| 49 | lambda[k][i]-=q*lambda[l][i]; |
| 50 | } |
| 51 | |
| 52 | |
| 53 | |