1 /*
2     Copyright (C) 2010 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 <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_vec.h"
18 #include "fmpz_mat.h"
19 #include "ulong_extras.h"
20 
21 int
main(void)22 main(void)
23 {
24     fmpz_mat_t A, X, B, AX, AXm, Bm;
25     fmpz_t mod;
26     slong i, m, n, r;
27     int success;
28 
29     FLINT_TEST_INIT(state);
30 
31     flint_printf("solve_dixon....");
32     fflush(stdout);
33 
34     for (i = 0; i < 100 * flint_test_multiplier(); i++)
35     {
36         m = n_randint(state, 20);
37         n = n_randint(state, 20);
38 
39         fmpz_mat_init(A, m, m);
40         fmpz_mat_init(B, m, n);
41         fmpz_mat_init(Bm, m, n);
42         fmpz_mat_init(X, m, n);
43         fmpz_mat_init(AX, m, n);
44         fmpz_mat_init(AXm, m, n);
45         fmpz_init(mod);
46 
47         fmpz_mat_randrank(A, state, m, 1+n_randint(state, 2)*n_randint(state, 100));
48         fmpz_mat_randtest(B, state, 1+n_randint(state, 2)*n_randint(state, 100));
49 
50         /* Dense */
51         if (n_randint(state, 2))
52             fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m));
53 
54         success = fmpz_mat_solve_dixon(X, mod, A, B);
55 
56         fmpz_mat_set(AXm, X);
57 
58         fmpz_mat_mul(AX, A, AXm);
59 
60         fmpz_mat_scalar_mod_fmpz(AXm, AX, mod);
61         fmpz_mat_scalar_mod_fmpz(Bm, B, mod);
62 
63         if (!fmpz_mat_equal(AXm, Bm) || !success)
64         {
65             flint_printf("FAIL:\n");
66             flint_printf("AX != B!\n");
67             flint_printf("A:\n"),      fmpz_mat_print_pretty(A),  flint_printf("\n");
68             flint_printf("B:\n"),      fmpz_mat_print_pretty(B),  flint_printf("\n");
69             flint_printf("X:\n"),      fmpz_mat_print_pretty(X),  flint_printf("\n");
70             flint_printf("mod = "),    fmpz_print(mod),           flint_printf("\n");
71             flint_printf("AX:\n"),     fmpz_mat_print_pretty(AX), flint_printf("\n");
72             abort();
73         }
74 
75         fmpz_mat_clear(A);
76         fmpz_mat_clear(B);
77         fmpz_mat_clear(Bm);
78         fmpz_mat_clear(X);
79         fmpz_mat_clear(AX);
80         fmpz_mat_clear(AXm);
81         fmpz_clear(mod);
82     }
83 
84     /* Test singular systems */
85     for (i = 0; i < 100 * flint_test_multiplier(); i++)
86     {
87         m = 1 + n_randint(state, 10);
88         n = 1 + n_randint(state, 10);
89         r = n_randint(state, m);
90 
91         fmpz_mat_init(A, m, m);
92         fmpz_mat_init(B, m, n);
93         fmpz_mat_init(X, m, n);
94         fmpz_init(mod);
95 
96         fmpz_mat_randrank(A, state, r, 1+n_randint(state, 2)*n_randint(state, 100));
97         fmpz_mat_randtest(B, state, 1+n_randint(state, 2)*n_randint(state, 100));
98 
99         /* Dense */
100         if (n_randint(state, 2))
101             fmpz_mat_randops(A, state, 1+n_randint(state, 1 + m*m));
102 
103         if (fmpz_mat_solve_dixon(X, mod, A, B) != 0)
104         {
105             flint_printf("FAIL:\n");
106             flint_printf("singular system, returned nonzero\n");
107             abort();
108         }
109 
110         fmpz_mat_clear(A);
111         fmpz_mat_clear(B);
112         fmpz_mat_clear(X);
113         fmpz_clear(mod);
114     }
115 
116     FLINT_TEST_CLEANUP(state);
117 
118     flint_printf("PASS\n");
119     return 0;
120 }
121