1 /*
2 Copyright (C) 2011 Fredrik Johansson
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 <http://www.gnu.org/licenses/>.
10 */
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <gmp.h>
15 #include "flint.h"
16 #include "fmpq.h"
17 #include "fmpq_mat.h"
18
19 int
main(void)20 main(void)
21 {
22 int i;
23 FLINT_TEST_INIT(state);
24
25
26 flint_printf("inv....");
27 fflush(stdout);
28
29 for (i = 0; i < 100 * flint_test_multiplier(); i++)
30 {
31 fmpq_mat_t A, B, C;
32 fmpq_t d;
33
34 int success1, success2;
35 slong n, bits;
36
37 n = n_randint(state, 10);
38 bits = 1 + n_randint(state, 100);
39
40 fmpq_mat_init(A, n, n);
41 fmpq_mat_init(B, n, n);
42 fmpq_mat_init(C, n, n);
43
44 fmpq_init(d);
45
46 /* XXX: replace with a randtest function */
47 {
48 slong k;
49
50 for (k = 0; (k < 100) && fmpq_is_zero(d); k++)
51 {
52 fmpq_mat_randtest(A, state, bits);
53 fmpq_mat_det(d, A);
54 }
55 if (fmpq_is_zero(d))
56 {
57 fmpq_mat_one(A);
58 }
59 }
60
61 fmpq_clear(d);
62
63 success1 = fmpq_mat_inv(B, A);
64 success2 = fmpq_mat_inv(C, B);
65
66 if (!fmpq_mat_equal(A, C) || !success1 || !success2)
67 {
68 flint_printf("FAIL!\n");
69 flint_printf("A:\n");
70 fmpq_mat_print(A);
71 flint_printf("B:\n");
72 fmpq_mat_print(B);
73 flint_printf("C:\n");
74 fmpq_mat_print(C);
75 abort();
76 }
77
78 fmpq_mat_clear(A);
79 fmpq_mat_clear(B);
80 fmpq_mat_clear(C);
81 }
82
83 /* Test aliasing */
84 for (i = 0; i < 10 * flint_test_multiplier(); i++)
85 {
86 fmpq_mat_t A, B;
87 fmpq_t d;
88
89 int success1, success2;
90 slong n, bits;
91
92 n = n_randint(state, 10);
93 bits = 1 + n_randint(state, 100);
94
95 fmpq_mat_init(A, n, n);
96 fmpq_mat_init(B, n, n);
97
98 fmpq_init(d);
99
100 /* XXX: replace with a randtest function */
101 do {
102 fmpq_mat_randtest(A, state, bits);
103 fmpq_mat_det(d, A);
104 } while (fmpq_is_zero(d));
105
106 fmpq_clear(d);
107
108 success1 = fmpq_mat_inv(B, A);
109 success2 = fmpq_mat_inv(A, A);
110
111 if (!fmpq_mat_equal(A, B) || !success1 || !success2)
112 {
113 flint_printf("FAIL!\n");
114 flint_printf("A:\n");
115 fmpq_mat_print(A);
116 flint_printf("B:\n");
117 fmpq_mat_print(B);
118 abort();
119 }
120
121 fmpq_mat_clear(A);
122 fmpq_mat_clear(B);
123 }
124
125 /* Test singular matrices */
126 for (i = 0; i < 100 * flint_test_multiplier(); i++)
127 {
128 slong n, r, b, d;
129 fmpq_mat_t A, B;
130 fmpz_mat_t M;
131 fmpz_t den;
132 int success;
133
134 n = n_randint(state, 10);
135
136 fmpz_init(den);
137
138 for (r = 0; r < n; r++)
139 {
140 b = 1 + n_randint(state, 10) * n_randint(state, 10);
141 d = n_randint(state, 2*n*n + 1);
142
143 fmpz_mat_init(M, n, n);
144 fmpq_mat_init(A, n, n);
145 fmpq_mat_init(B, n, n);
146
147 fmpz_mat_randrank(M, state, r, b);
148
149 if (i % 2 == 0)
150 fmpz_mat_randops(M, state, d);
151
152 fmpz_randtest_not_zero(den, state, b);
153 fmpq_mat_set_fmpz_mat_div_fmpz(A, M, den);
154
155 success = fmpq_mat_inv(B, A);
156
157 if (success)
158 {
159 flint_printf("FAIL:\n");
160 flint_printf("matrix reported as invertible:\n");
161 fmpq_mat_print(A);
162 abort();
163 }
164
165 fmpz_mat_clear(M);
166 fmpq_mat_clear(A);
167 fmpq_mat_clear(B);
168 }
169
170 fmpz_clear(den);
171 }
172
173 FLINT_TEST_CLEANUP(state);
174
175 flint_printf("PASS\n");
176 return 0;
177 }
178