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