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 <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 "fmpz.h"
17 #include "fmpz_vec.h"
18 #include "fmpz_mod_mat.h"
19 #include "ulong_extras.h"
20 
main(void)21 int main(void)
22 {
23     fmpz_mod_mat_t A, B, B1, B2, C, C1, C2, D;
24     slong i;
25     FLINT_TEST_INIT(state);
26 
27     flint_printf("mul....");
28     fflush(stdout);
29 
30     /* test A*(B1+B1) = A*B1 + A*B2 */
31     for (i = 0; i < 1000 * flint_test_multiplier(); i++)
32     {
33         slong m, n, k;
34 
35         fmpz_t mod;
36 
37         fmpz_init(mod);
38         fmpz_randtest_not_zero(mod, state, 200);
39         fmpz_abs(mod, mod);
40 
41         if (n_randint(state, 10) == 0)
42         {
43             m = n_randint(state, 50);
44             n = n_randint(state, 50);
45             k = n_randint(state, 50);
46         }
47         else
48         {
49             m = n_randint(state, 8);
50             n = n_randint(state, 8);
51             k = n_randint(state, 8);
52         }
53 
54         fmpz_mod_mat_init(A, m, n, mod);
55         fmpz_mod_mat_init(B, n, k, mod);
56         fmpz_mod_mat_init(B1, n, k, mod);
57         fmpz_mod_mat_init(B2, n, k, mod);
58         fmpz_mod_mat_init(C, m, k, mod);
59         fmpz_mod_mat_init(C1, m, k, mod);
60         fmpz_mod_mat_init(C2, m, k, mod);
61         fmpz_mod_mat_init(D, m, k, mod);
62 
63         fmpz_mod_mat_randtest(A, state);
64         fmpz_mod_mat_randtest(B1, state);
65         fmpz_mod_mat_randtest(B2, state);
66 
67         /* Make sure noise in the output is ok */
68         fmpz_mod_mat_randtest(C, state);
69         fmpz_mod_mat_randtest(C1, state);
70         fmpz_mod_mat_randtest(C2, state);
71 
72         fmpz_mod_mat_mul(C1, A, B1);
73         fmpz_mod_mat_mul(C2, A, B2);
74 	fmpz_mod_mat_add(B, B1, B2);
75 	fmpz_mod_mat_mul(C, A, B);
76         fmpz_mod_mat_add(D, C1, C2);
77 
78         if (!fmpz_mod_mat_equal(C, D))
79         {
80             flint_printf("FAIL: results not equal\n\n");
81             fmpz_mod_mat_print_pretty(A); flint_printf("\n\n");
82             fmpz_mod_mat_print_pretty(B1); flint_printf("\n\n");
83             fmpz_mod_mat_print_pretty(B2); flint_printf("\n\n");
84             fmpz_mod_mat_print_pretty(C); flint_printf("\n\n");
85             fmpz_mod_mat_print_pretty(D); flint_printf("\n\n");
86             flint_abort();
87         }
88 
89         if (n == k)
90         {
91             fmpz_mod_mat_mul(A, A, B);
92 
93             if (!fmpz_mod_mat_equal(A, C))
94             {
95                 flint_printf("FAIL: aliasing failed\n");
96                 flint_abort();
97             }
98         }
99 
100         fmpz_mod_mat_clear(A);
101         fmpz_mod_mat_clear(B);
102         fmpz_mod_mat_clear(B1);
103         fmpz_mod_mat_clear(B2);
104         fmpz_mod_mat_clear(C);
105         fmpz_mod_mat_clear(C1);
106         fmpz_mod_mat_clear(C2);
107         fmpz_mod_mat_clear(D);
108         fmpz_clear(mod);
109     }
110 
111     FLINT_TEST_CLEANUP(state);
112 
113     flint_printf("PASS\n");
114     return 0;
115 }
116