-
Notifications
You must be signed in to change notification settings - Fork 11
/
ca_mat.h
371 lines (272 loc) · 12.1 KB
/
ca_mat.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
/*
Copyright (C) 2020 Fredrik Johansson
This file is part of Calcium.
Calcium is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. See <http://www.gnu.org/licenses/>.
*/
#ifndef CA_MAT_H
#define CA_MAT_H
#ifdef CA_MAT_INLINES_C
#define CA_MAT_INLINE
#else
#define CA_MAT_INLINE static __inline__
#endif
#include <stdio.h>
#include "flint/flint.h"
#include "flint/fmpz_mat.h"
#include "flint/fmpq_mat.h"
#include "flint/perm.h"
#include "arb_mat.h"
#include "acb_mat.h"
#include "antic/nf.h"
#include "antic/nf_elem.h"
#include "ca.h"
#include "ca_vec.h"
#include "ca_poly.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Matrix object */
typedef struct
{
ca_ptr entries;
slong r;
slong c;
ca_ptr * rows;
}
ca_mat_struct;
typedef ca_mat_struct ca_mat_t[1];
#define ca_mat_entry(mat,i,j) ((mat)->rows[i] + (j))
#define ca_mat_nrows(mat) ((mat)->r)
#define ca_mat_ncols(mat) ((mat)->c)
CA_MAT_INLINE ca_ptr
ca_mat_entry_ptr(ca_mat_t mat, slong i, slong j)
{
return ca_mat_entry(mat, i, j);
}
/* Memory management */
void ca_mat_init(ca_mat_t mat, slong r, slong c, ca_ctx_t ctx);
void ca_mat_clear(ca_mat_t mat, ca_ctx_t ctx);
CA_MAT_INLINE void
ca_mat_swap(ca_mat_t mat1, ca_mat_t mat2, ca_ctx_t ctx)
{
ca_mat_struct t = *mat1;
*mat1 = *mat2;
*mat2 = t;
}
/* Window matrices */
void ca_mat_window_init(ca_mat_t window, const ca_mat_t mat, slong r1, slong c1, slong r2, slong c2, ca_ctx_t ctx);
CA_MAT_INLINE void
ca_mat_window_clear(ca_mat_t window, ca_ctx_t ctx)
{
flint_free(window->rows);
}
/* Shape */
CA_MAT_INLINE int
ca_mat_is_empty(const ca_mat_t mat)
{
return (mat->r == 0) || (mat->c == 0);
}
CA_MAT_INLINE int
ca_mat_is_square(const ca_mat_t mat)
{
return (mat->r == mat->c);
}
/* Conversions */
void ca_mat_set(ca_mat_t dest, const ca_mat_t src, ca_ctx_t ctx);
void ca_mat_set_fmpz_mat(ca_mat_t dest, const fmpz_mat_t src, ca_ctx_t ctx);
void ca_mat_set_fmpq_mat(ca_mat_t dest, const fmpq_mat_t src, ca_ctx_t ctx);
void ca_mat_set_ca(ca_mat_t y, const ca_t x, ca_ctx_t ctx);
void ca_mat_transfer(ca_mat_t res, ca_ctx_t res_ctx, const ca_mat_t src, ca_ctx_t src_ctx);
/* Random generation */
void ca_mat_randtest(ca_mat_t mat, flint_rand_t state, slong len, slong bits, ca_ctx_t ctx);
void ca_mat_randtest_rational(ca_mat_t mat, flint_rand_t state, slong bits, ca_ctx_t ctx);
void ca_mat_randops(ca_mat_t mat, flint_rand_t state, slong count, ca_ctx_t ctx);
/* I/O */
void ca_mat_print(const ca_mat_t mat, ca_ctx_t ctx);
void ca_mat_printn(const ca_mat_t mat, slong digits, ca_ctx_t ctx);
/* Special matrices */
void ca_mat_zero(ca_mat_t mat, ca_ctx_t ctx);
void ca_mat_one(ca_mat_t mat, ca_ctx_t ctx);
void ca_mat_ones(ca_mat_t mat, ca_ctx_t ctx);
void ca_mat_pascal(ca_mat_t mat, int triangular, ca_ctx_t ctx);
void ca_mat_stirling(ca_mat_t mat, int kind, ca_ctx_t ctx);
void ca_mat_hilbert(ca_mat_t mat, ca_ctx_t ctx);
void ca_mat_dft(ca_mat_t res, int type, ca_ctx_t ctx);
/* Comparisons and properties */
truth_t ca_mat_check_equal(const ca_mat_t A, const ca_mat_t B, ca_ctx_t ctx);
truth_t ca_mat_check_is_zero(const ca_mat_t A, ca_ctx_t ctx);
truth_t ca_mat_check_is_one(const ca_mat_t A, ca_ctx_t ctx);
/* Conjugate and transpose */
void ca_mat_transpose(ca_mat_t B, const ca_mat_t A, ca_ctx_t ctx);
void ca_mat_conj(ca_mat_t B, const ca_mat_t A, ca_ctx_t ctx);
void ca_mat_conj_transpose(ca_mat_t mat1, const ca_mat_t mat2, ca_ctx_t ctx);
/* Arithmetic */
void ca_mat_add_ca(ca_mat_t y, const ca_mat_t a, const ca_t x, ca_ctx_t ctx);
void ca_mat_sub_ca(ca_mat_t y, const ca_mat_t a, const ca_t x, ca_ctx_t ctx);
void ca_mat_addmul_ca(ca_mat_t y, const ca_mat_t a, const ca_t x, ca_ctx_t ctx);
void ca_mat_submul_ca(ca_mat_t y, const ca_mat_t a, const ca_t x, ca_ctx_t ctx);
void ca_mat_neg(ca_mat_t dest, const ca_mat_t src, ca_ctx_t ctx);
void ca_mat_add(ca_mat_t res, const ca_mat_t mat1, const ca_mat_t mat2, ca_ctx_t ctx);
void ca_mat_sub(ca_mat_t res, const ca_mat_t mat1, const ca_mat_t mat2, ca_ctx_t ctx);
void ca_mat_mul(ca_mat_t C, const ca_mat_t A, const ca_mat_t B, ca_ctx_t ctx);
void ca_mat_mul_classical(ca_mat_t C, const ca_mat_t A, const ca_mat_t B, ca_ctx_t ctx);
void ca_mat_mul_same_nf(ca_mat_t C, const ca_mat_t A, const ca_mat_t B, ca_field_t K, ca_ctx_t ctx);
CA_MAT_INLINE void
ca_mat_mul_si(ca_mat_t B, const ca_mat_t A, slong c, ca_ctx_t ctx)
{
slong i, j;
for (i = 0; i < ca_mat_nrows(A); i++)
for (j = 0; j < ca_mat_ncols(A); j++)
ca_mul_si(ca_mat_entry(B, i, j), ca_mat_entry(A, i, j), c, ctx);
}
CA_MAT_INLINE void
ca_mat_mul_fmpz(ca_mat_t B, const ca_mat_t A, const fmpz_t c, ca_ctx_t ctx)
{
slong i, j;
for (i = 0; i < ca_mat_nrows(A); i++)
for (j = 0; j < ca_mat_ncols(A); j++)
ca_mul_fmpz(ca_mat_entry(B, i, j), ca_mat_entry(A, i, j), c, ctx);
}
CA_MAT_INLINE void
ca_mat_mul_fmpq(ca_mat_t B, const ca_mat_t A, const fmpq_t c, ca_ctx_t ctx)
{
slong i, j;
for (i = 0; i < ca_mat_nrows(A); i++)
for (j = 0; j < ca_mat_ncols(A); j++)
ca_mul_fmpq(ca_mat_entry(B, i, j), ca_mat_entry(A, i, j), c, ctx);
}
CA_MAT_INLINE void
ca_mat_mul_ca(ca_mat_t B, const ca_mat_t A, const ca_t c, ca_ctx_t ctx)
{
slong i, j;
for (i = 0; i < ca_mat_nrows(A); i++)
for (j = 0; j < ca_mat_ncols(A); j++)
ca_mul(ca_mat_entry(B, i, j), ca_mat_entry(A, i, j), c, ctx);
}
CA_MAT_INLINE void
ca_mat_div_si(ca_mat_t B, const ca_mat_t A, slong c, ca_ctx_t ctx)
{
slong i, j;
for (i = 0; i < ca_mat_nrows(A); i++)
for (j = 0; j < ca_mat_ncols(A); j++)
ca_div_si(ca_mat_entry(B, i, j), ca_mat_entry(A, i, j), c, ctx);
}
CA_MAT_INLINE void
ca_mat_div_fmpz(ca_mat_t B, const ca_mat_t A, const fmpz_t c, ca_ctx_t ctx)
{
slong i, j;
for (i = 0; i < ca_mat_nrows(A); i++)
for (j = 0; j < ca_mat_ncols(A); j++)
ca_div_fmpz(ca_mat_entry(B, i, j), ca_mat_entry(A, i, j), c, ctx);
}
CA_MAT_INLINE void
ca_mat_div_fmpq(ca_mat_t B, const ca_mat_t A, const fmpq_t c, ca_ctx_t ctx)
{
slong i, j;
for (i = 0; i < ca_mat_nrows(A); i++)
for (j = 0; j < ca_mat_ncols(A); j++)
ca_div_fmpq(ca_mat_entry(B, i, j), ca_mat_entry(A, i, j), c, ctx);
}
CA_MAT_INLINE void
ca_mat_div_ca(ca_mat_t B, const ca_mat_t A, const ca_t c, ca_ctx_t ctx)
{
slong i, j;
for (i = 0; i < ca_mat_nrows(A); i++)
for (j = 0; j < ca_mat_ncols(A); j++)
ca_div(ca_mat_entry(B, i, j), ca_mat_entry(A, i, j), c, ctx);
}
CA_MAT_INLINE void
ca_mat_sqr(ca_mat_t res, const ca_mat_t A, ca_ctx_t ctx)
{
ca_mat_mul(res, A, A, ctx);
}
void ca_mat_pow_ui_binexp(ca_mat_t B, const ca_mat_t A, ulong exp, ca_ctx_t ctx);
/* Polynomial evaluation */
void _ca_mat_ca_poly_evaluate(ca_mat_t y, ca_srcptr poly, slong len, const ca_mat_t x, ca_ctx_t ctx);
void ca_mat_ca_poly_evaluate(ca_mat_t res, const ca_poly_t f, const ca_mat_t a, ca_ctx_t ctx);
/* Trace */
void ca_mat_trace(ca_t trace, const ca_mat_t mat, ca_ctx_t ctx);
/* Gaussian elimination, solving and inverse */
truth_t ca_mat_find_pivot(slong * pivot_row, ca_mat_t mat, slong start_row, slong end_row, slong column, ca_ctx_t ctx);
CA_MAT_INLINE void
_ca_mat_swap_rows(ca_mat_t mat, slong * perm, slong r, slong s)
{
if (r != s)
{
ca_ptr u;
slong t;
if (perm != NULL)
{
t = perm[s];
perm[s] = perm[r];
perm[r] = t;
}
u = mat->rows[s];
mat->rows[s] = mat->rows[r];
mat->rows[r] = u;
}
}
int ca_mat_lu_classical(slong * rank, slong * P, ca_mat_t LU, const ca_mat_t A, int rank_check, ca_ctx_t ctx);
int ca_mat_lu_recursive(slong * rank, slong * P, ca_mat_t LU, const ca_mat_t A, int rank_check, ca_ctx_t ctx);
int ca_mat_lu(slong * rank, slong * P, ca_mat_t LU, const ca_mat_t A, int rank_check, ca_ctx_t ctx);
int ca_mat_fflu(slong * rank, slong * P, ca_mat_t LU, ca_t den, const ca_mat_t A, int rank_check, ca_ctx_t ctx);
int ca_mat_rref_fflu(slong * rank, ca_mat_t R, const ca_mat_t A, ca_ctx_t ctx);
int ca_mat_rref_lu(slong * rank, ca_mat_t R, const ca_mat_t A, ca_ctx_t ctx);
int ca_mat_rref(slong * rank, ca_mat_t R, const ca_mat_t A, ca_ctx_t ctx);
truth_t ca_mat_nonsingular_lu(slong * P, ca_mat_t LU, const ca_mat_t A, ca_ctx_t ctx);
truth_t ca_mat_nonsingular_fflu(slong * P, ca_mat_t LU, ca_t den, const ca_mat_t A, ca_ctx_t ctx);
truth_t ca_mat_nonsingular_solve_adjugate(ca_mat_t X, const ca_mat_t A, const ca_mat_t B, ca_ctx_t ctx);
truth_t ca_mat_nonsingular_solve_fflu(ca_mat_t X, const ca_mat_t A, const ca_mat_t B, ca_ctx_t ctx);
truth_t ca_mat_nonsingular_solve_lu(ca_mat_t X, const ca_mat_t A, const ca_mat_t B, ca_ctx_t ctx);
truth_t ca_mat_nonsingular_solve(ca_mat_t X, const ca_mat_t A, const ca_mat_t B, ca_ctx_t ctx);
truth_t ca_mat_inv(ca_mat_t X, const ca_mat_t A, ca_ctx_t ctx);
void ca_mat_solve_tril_classical(ca_mat_t X, const ca_mat_t L, const ca_mat_t B, int unit, ca_ctx_t ctx);
void ca_mat_solve_tril_recursive(ca_mat_t X, const ca_mat_t L, const ca_mat_t B, int unit, ca_ctx_t ctx);
void ca_mat_solve_tril(ca_mat_t X, const ca_mat_t L, const ca_mat_t B, int unit, ca_ctx_t ctx);
void ca_mat_solve_triu_classical(ca_mat_t X, const ca_mat_t U, const ca_mat_t B, int unit, ca_ctx_t ctx);
void ca_mat_solve_triu_recursive(ca_mat_t X, const ca_mat_t U, const ca_mat_t B, int unit, ca_ctx_t ctx);
void ca_mat_solve_triu(ca_mat_t X, const ca_mat_t U, const ca_mat_t B, int unit, ca_ctx_t ctx);
void ca_mat_solve_lu_precomp(ca_mat_t X, const slong * perm, const ca_mat_t A, const ca_mat_t B, ca_ctx_t ctx);
void ca_mat_solve_fflu_precomp(ca_mat_t X, const slong * perm, const ca_mat_t A, const ca_t den, const ca_mat_t B, ca_ctx_t ctx);
/* Rank and kernel */
int ca_mat_rank(slong * rank, const ca_mat_t A, ca_ctx_t ctx);
int ca_mat_right_kernel(ca_mat_t X, const ca_mat_t A, ca_ctx_t ctx);
/* Determinant */
void ca_mat_det_berkowitz(ca_t det, const ca_mat_t A, ca_ctx_t ctx);
int ca_mat_det_lu(ca_t det, const ca_mat_t A, ca_ctx_t ctx);
int ca_mat_det_bareiss(ca_t det, const ca_mat_t A, ca_ctx_t ctx);
void ca_mat_det_cofactor(ca_t det, const ca_mat_t A, ca_ctx_t ctx);
void ca_mat_det(ca_t det, const ca_mat_t A, ca_ctx_t ctx);
void ca_mat_adjugate_cofactor(ca_mat_t adj, ca_t det, const ca_mat_t A, ca_ctx_t ctx);
void ca_mat_adjugate_charpoly(ca_mat_t adj, ca_t det, const ca_mat_t A, ca_ctx_t ctx);
void ca_mat_adjugate(ca_mat_t adj, ca_t det, const ca_mat_t A, ca_ctx_t ctx);
/* Characteristic polynomial */
void _ca_mat_charpoly_berkowitz(ca_ptr cp, const ca_mat_t mat, ca_ctx_t ctx);
void ca_mat_charpoly_berkowitz(ca_poly_t cp, const ca_mat_t mat, ca_ctx_t ctx);
int _ca_mat_charpoly_danilevsky(ca_ptr p, const ca_mat_t A, ca_ctx_t ctx);
int ca_mat_charpoly_danilevsky(ca_poly_t cp, const ca_mat_t mat, ca_ctx_t ctx);
void _ca_mat_charpoly(ca_ptr cp, const ca_mat_t mat, ca_ctx_t ctx);
void ca_mat_charpoly(ca_poly_t cp, const ca_mat_t mat, ca_ctx_t ctx);
int ca_mat_companion(ca_mat_t A, const ca_poly_t poly, ca_ctx_t ctx);
/* Eigenvalues and eigenvectors */
int ca_mat_eigenvalues(ca_vec_t lambda, ulong * exp, const ca_mat_t mat, ca_ctx_t ctx);
/* Diagonalization */
truth_t ca_mat_diagonalization(ca_mat_t D, ca_mat_t P, const ca_mat_t A, ca_ctx_t ctx);
void ca_mat_set_jordan_blocks(ca_mat_t mat, const ca_vec_t lambda, slong num_blocks, slong * block_lambda, slong * block_size, ca_ctx_t ctx);
int ca_mat_jordan_blocks(ca_vec_t lambda, slong * num_blocks, slong * block_lambda, slong * block_size, const ca_mat_t A, ca_ctx_t ctx);
int ca_mat_jordan_transformation(ca_mat_t mat, const ca_vec_t lambda, slong num_blocks, slong * block_lambda, slong * block_size, const ca_mat_t A, ca_ctx_t ctx);
int ca_mat_jordan_form(ca_mat_t J, ca_mat_t P, const ca_mat_t A, ca_ctx_t ctx);
/* Matrix functions */
int ca_mat_exp(ca_mat_t res, const ca_mat_t A, ca_ctx_t ctx);
truth_t ca_mat_log(ca_mat_t res, const ca_mat_t A, ca_ctx_t ctx);
/* Internal representation */
/* todo: document, make consistent */
ca_field_ptr _ca_mat_same_field(const ca_mat_t A, ca_ctx_t ctx);
ca_field_ptr _ca_mat_same_field2(const ca_mat_t A, const ca_mat_t B, ca_ctx_t ctx);
#ifdef __cplusplus
}
#endif
#endif