1 /* emacs edit mode for this file is -*- C++ -*- */
2 
3 /**
4  *
5  * @file cf_hnf.cc
6  *
7  * HNF/LLL of NTL
8  *
9  * Header file: cf_hnf.h
10  *
11 **/
12 
13 
14 #include "config.h"
15 
16 #include "canonicalform.h"
17 #include "cf_defs.h"
18 #include "cf_hnf.h"
19 #include "cf_util.h"
20 
21 #ifdef HAVE_NTL
22 #include "NTLconvert.h"
23 #include <NTL/mat_ZZ.h>
24 #include <NTL/HNF.h>
25 #include <NTL/LLL.h>
26 #endif
27 
28 #ifdef HAVE_FLINT
29 #include "FLINTconvert.h"
30 #endif
31 
32 /**
33  * The input matrix A is an n x m matrix of rank m (so n >= m), and D
34  * is a multiple of the determinant of the lattice L spanned by the
35  * rows of A.  W is computed as the Hermite Normal Form of A; that is,
36  * W is the unique m x m matrix whose rows span L, such that
37  *
38  * - W is lower triangular,
39  * - the diagonal entries are positive,
40  * - any entry below the diagonal is a non-negative number
41  *   strictly less than the diagonal entry in its column.
42  *
43 **/
cf_HNF(CFMatrix & A)44 CFMatrix* cf_HNF(CFMatrix& A)
45 {
46 #ifdef HAVE_FLINT
47   fmpz_mat_t FLINTM;
48   convertFacCFMatrix2Fmpz_mat_t(FLINTM,A);
49   fmpz_mat_hnf(FLINTM,FLINTM);
50   CFMatrix *r=convertFmpz_mat_t2FacCFMatrix(FLINTM);
51   fmpz_mat_clear(FLINTM);
52   return r;
53 #elif defined(HAVE_NTL)
54   mat_ZZ *AA=convertFacCFMatrix2NTLmat_ZZ(A);
55   ZZ DD=convertFacCF2NTLZZ(determinant(A,A.rows()));
56   mat_ZZ WW;
57   HNF(WW,*AA,DD);
58   delete AA;
59   return convertNTLmat_ZZ2FacCFMatrix(WW);
60 #else
61   factoryError("NTL/FLINT missing: cf_HNF");
62   return NULL; // avoid warning
63 #endif
64 }
65 
cf_LLL(CFMatrix & A)66 CFMatrix* cf_LLL(CFMatrix& A)
67 {
68 #ifdef HAVE_FLINT
69   fmpz_mat_t FLINTM;
70   convertFacCFMatrix2Fmpz_mat_t(FLINTM,A);
71   fmpq_t delta,eta;
72   fmpq_init(delta); fmpq_set_si(delta,1,1);
73   fmpq_init(eta); fmpq_set_si(eta,3,4);
74   fmpz_mat_lll_storjohann(FLINTM,delta,eta);
75   CFMatrix *r=convertFmpz_mat_t2FacCFMatrix(FLINTM);
76   fmpz_mat_clear(FLINTM);
77   return r;
78 #elif defined(HAVE_NTL)
79   mat_ZZ *AA=convertFacCFMatrix2NTLmat_ZZ(A);
80   ZZ det2;
81   LLL(det2,*AA,0L);
82   CFMatrix *r= convertNTLmat_ZZ2FacCFMatrix(*AA);
83   delete AA;
84   return r;
85 #else
86   factoryError("NTL/FLINT missing: cf_LLL");
87   return NULL; // avoid warning
88 #endif
89 }
90