1 /*
2 Copyright (C) 2012 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 "fmpz_mat.h"
13
14 void
fmpz_mat_pow(fmpz_mat_t B,const fmpz_mat_t A,ulong exp)15 fmpz_mat_pow(fmpz_mat_t B, const fmpz_mat_t A, ulong exp)
16 {
17 slong d = fmpz_mat_nrows(A);
18
19 if (exp <= 2 || d <= 1)
20 {
21 if (exp == 0 || d == 0)
22 {
23 fmpz_mat_one(B);
24 }
25 else if (d == 1)
26 {
27 fmpz_pow_ui(fmpz_mat_entry(B, 0, 0),
28 fmpz_mat_entry(A, 0, 0), exp);
29 }
30 else if (exp == 1)
31 {
32 fmpz_mat_set(B, A);
33 }
34 else if (exp == 2)
35 {
36 fmpz_mat_sqr(B, A);
37 }
38 }
39 else
40 {
41 fmpz_mat_t T, U;
42 slong i;
43
44 fmpz_mat_init_set(T, A);
45 fmpz_mat_init(U, d, d);
46
47 for (i = ((slong) FLINT_BIT_COUNT(exp)) - 2; i >= 0; i--)
48 {
49 fmpz_mat_sqr(U, T);
50
51 if (exp & (WORD(1) << i))
52 fmpz_mat_mul(T, U, A);
53 else
54 fmpz_mat_swap(T, U);
55 }
56
57 fmpz_mat_swap(B, T);
58 fmpz_mat_clear(T);
59 fmpz_mat_clear(U);
60 }
61 }
62