1 /*
2     Copyright (C) 2014 Alex J. Best
3 
4     This file is part of FLINT.
5 
6     FLINT is free software: you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License (LGPL) as published
8     by the Free Software Foundation; either version 2.1 of the License, or
9     (at your option) any later version.  See <https://www.gnu.org/licenses/>.
10 */
11 
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <gmp.h>
15 #include "flint.h"
16 #include "fmpz.h"
17 #include "fmpz_mat.h"
18 
19 int
main(void)20 main(void)
21 {
22     slong iter;
23     FLINT_TEST_INIT(state);
24 
25     flint_printf("hnf_pernet_stein....");
26     fflush(stdout);
27 
28     /* matrices of random rank */
29     for (iter = 0; iter < 1000 * flint_test_multiplier(); iter++)
30     {
31         fmpz_mat_t A, B, H, H2;
32         slong m, n, r, b, d;
33         int equal;
34 
35         n = 1 + n_randint(state, 10);
36         m = 1 + n_randint(state, 10);
37         r = n_randint(state, FLINT_MIN(m, n) + 1);
38 
39         fmpz_mat_init(A, m, n);
40         fmpz_mat_init(B, m, n);
41         fmpz_mat_init(H, m, n);
42         fmpz_mat_init(H2, m, n);
43 
44         /* sparse */
45         b = 1 + n_randint(state, 10) * n_randint(state, 10);
46         d = n_randint(state, 2*m*n + 1);
47         fmpz_mat_randrank(A, state, r, b);
48 
49         /* dense */
50         if (n_randint(state, 2))
51             fmpz_mat_randops(A, state, d);
52 
53         fmpz_mat_hnf_pernet_stein(H, A, state);
54 
55         if (!fmpz_mat_is_in_hnf(H))
56         {
57             flint_printf("FAIL:\n");
58             flint_printf("matrix not in hnf!\n");
59             fmpz_mat_print_pretty(A); flint_printf("\n\n");
60             fmpz_mat_print_pretty(H); flint_printf("\n\n");
61             abort();
62         }
63 
64         fmpz_mat_hnf_classical(H2, A);
65         equal = fmpz_mat_equal(H, H2);
66 
67         if (!equal)
68         {
69             flint_printf("FAIL:\n");
70             flint_printf("hnfs produced by different methods should be the same!\n");
71             fmpz_mat_print_pretty(A); flint_printf("\n\n");
72             fmpz_mat_print_pretty(H); flint_printf("\n\n");
73             fmpz_mat_print_pretty(H2); flint_printf("\n\n");
74             abort();
75         }
76 
77         fmpz_mat_hnf_pernet_stein(H2, H, state);
78         equal = fmpz_mat_equal(H, H2);
79 
80         if (!equal)
81         {
82             flint_printf("FAIL:\n");
83             flint_printf("hnf of a matrix in hnf should be the same!\n");
84             fmpz_mat_print_pretty(A); flint_printf("\n\n");
85             fmpz_mat_print_pretty(H); flint_printf("\n\n");
86             fmpz_mat_print_pretty(H2); flint_printf("\n\n");
87             abort();
88         }
89 
90         fmpz_mat_clear(H2);
91         fmpz_mat_clear(H);
92         fmpz_mat_clear(B);
93         fmpz_mat_clear(A);
94     }
95 
96     /* matrices with random entries */
97     for (iter = 0; iter < 1000 * flint_test_multiplier(); iter++)
98     {
99         fmpz_mat_t A, B, H, H2;
100         slong m, n, b;
101         int equal;
102 
103         n = 1 + n_randint(state, 10);
104         m = 1 + n_randint(state, 10);
105 
106         fmpz_mat_init(A, m, n);
107         fmpz_mat_init(B, m, n);
108         fmpz_mat_init(H, m, n);
109         fmpz_mat_init(H2, m, n);
110 
111         b = 1 + n_randint(state, 8) * n_randint(state, 8);
112         fmpz_mat_randtest(A, state, b);
113 
114         fmpz_mat_hnf_pernet_stein(H, A, state);
115 
116         if (!fmpz_mat_is_in_hnf(H))
117         {
118             flint_printf("FAIL:\n");
119             flint_printf("matrix not in hnf!\n");
120             fmpz_mat_print_pretty(A); flint_printf("\n\n");
121             fmpz_mat_print_pretty(H); flint_printf("\n\n");
122             abort();
123         }
124 
125         fmpz_mat_hnf_classical(H2, A);
126         equal = fmpz_mat_equal(H, H2);
127 
128         if (!equal)
129         {
130             flint_printf("FAIL:\n");
131             flint_printf("hnfs produced by different methods should be the same!\n");
132             fmpz_mat_print_pretty(A); flint_printf("\n\n");
133             fmpz_mat_print_pretty(H); flint_printf("\n\n");
134             fmpz_mat_print_pretty(H2); flint_printf("\n\n");
135             abort();
136         }
137 
138         fmpz_mat_hnf_pernet_stein(H2, H, state);
139         equal = fmpz_mat_equal(H, H2);
140 
141         if (!equal)
142         {
143             flint_printf("FAIL:\n");
144             flint_printf("hnf of a matrix in hnf should be the same!\n");
145             fmpz_mat_print_pretty(A); flint_printf("\n\n");
146             fmpz_mat_print_pretty(H); flint_printf("\n\n");
147             fmpz_mat_print_pretty(H2); flint_printf("\n\n");
148             abort();
149         }
150 
151         fmpz_mat_clear(H2);
152         fmpz_mat_clear(H);
153         fmpz_mat_clear(B);
154         fmpz_mat_clear(A);
155     }
156 
157     FLINT_TEST_CLEANUP(state);
158 
159     flint_printf("PASS\n");
160     return 0;
161 }
162