Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:15:18

0001 /*
0002     Copyright (C) 2021 William Hart
0003     Copyright (C) 2021 Daniel Schultz
0004 
0005     This file is part of FLINT.
0006 
0007     FLINT is free software: you can redistribute it and/or modify it under
0008     the terms of the GNU Lesser General Public License (LGPL) as published
0009     by the Free Software Foundation; either version 3 of the License, or
0010     (at your option) any later version.  See <https://www.gnu.org/licenses/>.
0011 */
0012 
0013 #ifndef FQ_DEFAULT_MAT_H
0014 #define FQ_DEFAULT_MAT_H
0015 
0016 #ifdef FQ_DEFAULT_MAT_INLINES_C
0017 #define FQ_DEFAULT_MAT_INLINE
0018 #else
0019 #define FQ_DEFAULT_MAT_INLINE static inline
0020 #endif
0021 
0022 #include "nmod_mat.h"
0023 #include "fmpz_mod.h"
0024 #include "fmpz_mod_mat.h"
0025 #include "fq_mat.h"
0026 #include "fq_nmod_mat.h"
0027 #include "fq_zech_mat.h"
0028 #include "fq_default.h"
0029 #include "gr.h"
0030 #include "gr_mat.h"
0031 
0032 #ifdef __cplusplus
0033  extern "C" {
0034 #endif
0035 
0036 typedef union fq_default_mat_struct
0037 {
0038     fq_mat_t fq;
0039     fq_nmod_mat_t fq_nmod;
0040     fq_zech_mat_t fq_zech;
0041     nmod_mat_t nmod;
0042     fmpz_mod_mat_t fmpz_mod;
0043 } fq_default_mat_struct;
0044 
0045 typedef fq_default_mat_struct fq_default_mat_t[1];
0046 
0047 /* Memory management  ********************************************************/
0048 
0049 FQ_DEFAULT_MAT_INLINE void fq_default_mat_init(fq_default_mat_t mat,
0050                             slong rows, slong cols, const fq_default_ctx_t ctx)
0051 {
0052     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0053     {
0054         fq_zech_mat_init(mat->fq_zech, rows, cols, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0055     }
0056     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0057     {
0058         fq_nmod_mat_init(mat->fq_nmod, rows, cols, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0059     }
0060     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0061     {
0062         nmod_mat_init(mat->nmod, rows, cols, FQ_DEFAULT_CTX_NMOD(ctx).n);
0063     }
0064     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0065     {
0066         fmpz_mod_mat_init(mat->fmpz_mod, rows, cols, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0067     }
0068     else
0069     {
0070         fq_mat_init(mat->fq, rows, cols, FQ_DEFAULT_CTX_FQ(ctx));
0071     }
0072 }
0073 
0074 FQ_DEFAULT_MAT_INLINE void fq_default_mat_init_set(fq_default_mat_t mat,
0075                         const fq_default_mat_t src, const fq_default_ctx_t ctx)
0076 {
0077     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0078     {
0079         fq_zech_mat_init_set(mat->fq_zech, src->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0080     }
0081     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0082     {
0083         fq_nmod_mat_init_set(mat->fq_nmod, src->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0084     }
0085     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0086     {
0087         nmod_mat_init_set(mat->nmod, src->nmod);
0088     }
0089     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0090     {
0091         fmpz_mod_mat_init_set(mat->fmpz_mod, src->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0092     }
0093     else
0094     {
0095         fq_mat_init_set(mat->fq, src->fq, FQ_DEFAULT_CTX_FQ(ctx));
0096     }
0097 }
0098 
0099 FQ_DEFAULT_MAT_INLINE void fq_default_mat_swap(fq_default_mat_t mat1,
0100                                fq_default_mat_t mat2, const fq_default_ctx_t ctx)
0101 {
0102     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0103     {
0104         fq_zech_mat_swap(mat1->fq_zech, mat2->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0105     }
0106     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0107     {
0108         fq_nmod_mat_swap(mat1->fq_nmod, mat2->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0109     }
0110     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0111     {
0112         nmod_mat_swap(mat1->nmod, mat2->nmod);
0113     }
0114     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0115     {
0116         fmpz_mod_mat_swap(mat1->fmpz_mod, mat2->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0117     }
0118     else
0119     {
0120         fq_mat_swap(mat1->fq, mat2->fq, FQ_DEFAULT_CTX_FQ(ctx));
0121     }
0122 }
0123 
0124 FQ_DEFAULT_MAT_INLINE void fq_default_mat_set(fq_default_mat_t mat1,
0125                        const fq_default_mat_t mat2, const fq_default_ctx_t ctx)
0126 {
0127     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0128     {
0129         fq_zech_mat_set(mat1->fq_zech, mat2->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0130     }
0131     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0132     {
0133         fq_nmod_mat_set(mat1->fq_nmod, mat2->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0134     }
0135     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0136     {
0137         nmod_mat_set(mat1->nmod, mat2->nmod);
0138     }
0139     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0140     {
0141         fmpz_mod_mat_set(mat1->fmpz_mod, mat2->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0142     }
0143     else
0144     {
0145         fq_mat_set(mat1->fq, mat2->fq, FQ_DEFAULT_CTX_FQ(ctx));
0146     }
0147 }
0148 
0149 FQ_DEFAULT_MAT_INLINE void fq_default_mat_clear(fq_default_mat_t mat,
0150                                                     const fq_default_ctx_t ctx)
0151 {
0152     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0153     {
0154         fq_zech_mat_clear(mat->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0155     }
0156     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0157     {
0158         fq_nmod_mat_clear(mat->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0159     }
0160     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0161     {
0162         nmod_mat_clear(mat->nmod);
0163     }
0164     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0165     {
0166         fmpz_mod_mat_clear(mat->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0167     }
0168     else
0169     {
0170         fq_mat_clear(mat->fq, FQ_DEFAULT_CTX_FQ(ctx));
0171     }
0172 }
0173 
0174 FQ_DEFAULT_MAT_INLINE int fq_default_mat_equal(const fq_default_mat_t mat1,
0175                        const fq_default_mat_t mat2, const fq_default_ctx_t ctx)
0176 {
0177     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0178     {
0179         return fq_zech_mat_equal(mat1->fq_zech, mat2->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0180     }
0181     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0182     {
0183         return fq_nmod_mat_equal(mat1->fq_nmod, mat2->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0184     }
0185     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0186     {
0187         return nmod_mat_equal(mat1->nmod, mat2->nmod);
0188     }
0189     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0190     {
0191         return fmpz_mod_mat_equal(mat1->fmpz_mod, mat2->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0192     }
0193     else
0194     {
0195         return fq_mat_equal(mat1->fq, mat2->fq, FQ_DEFAULT_CTX_FQ(ctx));
0196     }
0197 }
0198 
0199 FQ_DEFAULT_MAT_INLINE int fq_default_mat_is_zero(const fq_default_mat_t mat,
0200                                                     const fq_default_ctx_t ctx)
0201 {
0202     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0203     {
0204         return fq_zech_mat_is_zero(mat->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0205     }
0206     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0207     {
0208         return fq_nmod_mat_is_zero(mat->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0209     }
0210     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0211     {
0212         return nmod_mat_is_zero(mat->nmod);
0213     }
0214     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0215     {
0216         return fmpz_mod_mat_is_zero(mat->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0217     }
0218     else
0219     {
0220         return fq_mat_is_zero(mat->fq, FQ_DEFAULT_CTX_FQ(ctx));
0221     }
0222 }
0223 
0224 FQ_DEFAULT_MAT_INLINE int fq_default_mat_is_one(const fq_default_mat_t mat,
0225                                                     const fq_default_ctx_t ctx)
0226 {
0227     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0228     {
0229         return fq_zech_mat_is_one(mat->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0230     }
0231     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0232     {
0233         return fq_nmod_mat_is_one(mat->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0234     }
0235     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0236     {
0237         return nmod_mat_is_one(mat->nmod);
0238     }
0239     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0240     {
0241         return fmpz_mod_mat_is_one(mat->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0242     }
0243     else
0244     {
0245         return fq_mat_is_one(mat->fq, FQ_DEFAULT_CTX_FQ(ctx));
0246     }
0247 }
0248 
0249 FQ_DEFAULT_MAT_INLINE int
0250 fq_default_mat_is_empty(const fq_default_mat_t mat, const fq_default_ctx_t ctx)
0251 {
0252     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0253     {
0254         return fq_zech_mat_is_empty(mat->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0255     }
0256     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0257     {
0258         return fq_nmod_mat_is_empty(mat->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0259     }
0260     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0261     {
0262         return nmod_mat_is_empty(mat->nmod);
0263     }
0264     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0265     {
0266         return fmpz_mod_mat_is_empty(mat->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0267     }
0268     else
0269     {
0270         return fq_mat_is_empty(mat->fq, FQ_DEFAULT_CTX_FQ(ctx));
0271     }
0272 }
0273 
0274 FQ_DEFAULT_MAT_INLINE int
0275 fq_default_mat_is_square(const fq_default_mat_t mat,
0276                                                     const fq_default_ctx_t ctx)
0277 {
0278     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0279     {
0280         return fq_zech_mat_is_square(mat->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0281     }
0282     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0283     {
0284         return fq_nmod_mat_is_square(mat->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0285     }
0286     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0287     {
0288         return nmod_mat_is_square(mat->nmod);
0289     }
0290     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0291     {
0292         return fmpz_mod_mat_is_square(mat->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0293     }
0294     else
0295     {
0296         return fq_mat_is_square(mat->fq, FQ_DEFAULT_CTX_FQ(ctx));
0297     }
0298 }
0299 
0300 FQ_DEFAULT_MAT_INLINE void
0301 fq_default_mat_transpose(fq_default_mat_t B, const fq_default_mat_t A, const fq_default_ctx_t ctx)
0302 {
0303     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0304     {
0305         nmod_mat_transpose(B->nmod, A->nmod);
0306     }
0307     else
0308     {
0309         GR_MUST_SUCCEED(gr_mat_transpose((gr_mat_struct *) B, (const gr_mat_struct *) A, FQ_DEFAULT_GR_CTX(ctx)));
0310     }
0311 }
0312 
0313 FQ_DEFAULT_MAT_INLINE void
0314 fq_default_mat_entry(fq_default_t val, const fq_default_mat_t mat,
0315                           slong i, slong j, const fq_default_ctx_t ctx)
0316 {
0317     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0318     {
0319         fq_zech_set(val->fq_zech,
0320                         fq_zech_mat_entry(mat->fq_zech, i, j), FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0321     }
0322     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0323     {
0324         fq_nmod_set(val->fq_nmod,
0325                         fq_nmod_mat_entry(mat->fq_nmod, i, j), FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0326     }
0327     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0328     {
0329         val->nmod = nmod_mat_entry(mat->nmod, i, j);
0330     }
0331     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0332     {
0333         fmpz_set(val->fmpz_mod, fmpz_mod_mat_entry(mat->fmpz_mod, i, j));
0334     }
0335     else
0336     {
0337         fq_set(val->fq, fq_mat_entry(mat->fq, i, j), FQ_DEFAULT_CTX_FQ(ctx));
0338     }
0339 }
0340 
0341 FQ_DEFAULT_MAT_INLINE void
0342 fq_default_mat_entry_set(fq_default_mat_t mat, slong i, slong j,
0343                               const fq_default_t x, const fq_default_ctx_t ctx)
0344 {
0345     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0346     {
0347         fq_zech_mat_entry_set(mat->fq_zech, i, j, x->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0348     }
0349     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0350     {
0351         fq_nmod_mat_entry_set(mat->fq_nmod, i, j, x->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0352     }
0353     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0354     {
0355         nmod_mat_entry(mat->nmod, i, j) = x->nmod;
0356     }
0357     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0358     {
0359         fmpz_set(fmpz_mod_mat_entry(mat->fmpz_mod, i, j), x->fmpz_mod);
0360     }
0361     else
0362     {
0363         fq_mat_entry_set(mat->fq, i, j, x->fq, FQ_DEFAULT_CTX_FQ(ctx));
0364     }
0365 }
0366 
0367 FQ_DEFAULT_MAT_INLINE void
0368 fq_default_mat_entry_set_fmpz(fq_default_mat_t mat, slong i, slong j,
0369                                     const fmpz_t x, const fq_default_ctx_t ctx)
0370 {
0371    fq_default_t c;
0372    fq_default_init(c, ctx);
0373    fq_default_set_fmpz(c, x, ctx);
0374    fq_default_mat_entry_set(mat, i, j, c, ctx);
0375    fq_default_clear(c, ctx);
0376 }
0377 
0378 FQ_DEFAULT_MAT_INLINE slong
0379 fq_default_mat_nrows(const fq_default_mat_t mat, const fq_default_ctx_t ctx)
0380 {
0381     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0382     {
0383         return fq_zech_mat_nrows(mat->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0384     }
0385     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0386     {
0387         return fq_nmod_mat_nrows(mat->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0388     }
0389     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0390     {
0391         return nmod_mat_nrows(mat->nmod);
0392     }
0393     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0394     {
0395         return fmpz_mod_mat_nrows(mat->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0396     }
0397     else
0398     {
0399         return fq_mat_nrows(mat->fq, FQ_DEFAULT_CTX_FQ(ctx));
0400     }
0401 }
0402 
0403 FQ_DEFAULT_MAT_INLINE slong
0404 fq_default_mat_ncols(const fq_default_mat_t mat, const fq_default_ctx_t ctx)
0405 {
0406     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0407     {
0408         return fq_zech_mat_ncols(mat->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0409     }
0410     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0411     {
0412         return fq_nmod_mat_ncols(mat->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0413     }
0414     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0415     {
0416         return nmod_mat_ncols(mat->nmod);
0417     }
0418     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0419     {
0420         return fmpz_mod_mat_ncols(mat->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0421     }
0422     else
0423     {
0424         return fq_mat_ncols(mat->fq, FQ_DEFAULT_CTX_FQ(ctx));
0425     }
0426 }
0427 
0428 FQ_DEFAULT_MAT_INLINE void
0429 fq_default_mat_swap_rows(fq_default_mat_t mat,
0430                     slong * perm, slong r, slong s, const fq_default_ctx_t ctx)
0431 {
0432     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0433     {
0434         fq_zech_mat_swap_rows(mat->fq_zech, perm, r, s, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0435     }
0436     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0437     {
0438         fq_nmod_mat_swap_rows(mat->fq_nmod, perm, r, s, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0439     }
0440     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0441     {
0442         nmod_mat_swap_rows(mat->nmod, perm, r, s);
0443     }
0444     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0445     {
0446         fmpz_mod_mat_swap_rows(mat->fmpz_mod, perm, r, s, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0447     }
0448     else
0449     {
0450         fq_mat_swap_rows(mat->fq, perm, r, s, FQ_DEFAULT_CTX_FQ(ctx));
0451     }
0452 }
0453 
0454 FQ_DEFAULT_MAT_INLINE void
0455 fq_default_mat_invert_rows(fq_default_mat_t mat,
0456                                       slong * perm, const fq_default_ctx_t ctx)
0457 {
0458     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0459     {
0460         fq_zech_mat_invert_rows(mat->fq_zech, perm, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0461     }
0462     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0463     {
0464         fq_nmod_mat_invert_rows(mat->fq_nmod, perm, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0465     }
0466     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0467     {
0468         nmod_mat_invert_rows(mat->nmod, perm);
0469     }
0470     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0471     {
0472         fmpz_mod_mat_invert_rows(mat->fmpz_mod, perm, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0473     }
0474     else
0475     {
0476         fq_mat_invert_rows(mat->fq, perm, FQ_DEFAULT_CTX_FQ(ctx));
0477     }
0478 }
0479 
0480 FQ_DEFAULT_MAT_INLINE void
0481 fq_default_mat_swap_cols(fq_default_mat_t mat,
0482                     slong * perm, slong r, slong s, const fq_default_ctx_t ctx)
0483 {
0484     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0485     {
0486         fq_zech_mat_swap_cols(mat->fq_zech, perm, r, s, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0487     }
0488     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0489     {
0490         fq_nmod_mat_swap_cols(mat->fq_nmod, perm, r, s, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0491     }
0492     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0493     {
0494         nmod_mat_swap_cols(mat->nmod, perm, r, s);
0495     }
0496     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0497     {
0498         fmpz_mod_mat_swap_cols(mat->fmpz_mod, perm, r, s, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0499     }
0500     else
0501     {
0502         fq_mat_swap_cols(mat->fq, perm, r, s, FQ_DEFAULT_CTX_FQ(ctx));
0503     }
0504 }
0505 
0506 FQ_DEFAULT_MAT_INLINE void
0507 fq_default_mat_invert_cols(fq_default_mat_t mat,
0508                                       slong * perm, const fq_default_ctx_t ctx)
0509 {
0510     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0511     {
0512         fq_zech_mat_invert_cols(mat->fq_zech, perm, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0513     }
0514     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0515     {
0516         fq_nmod_mat_invert_cols(mat->fq_nmod, perm, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0517     }
0518     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0519     {
0520         nmod_mat_invert_cols(mat->nmod, perm);
0521     }
0522     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0523     {
0524         fmpz_mod_mat_invert_cols(mat->fmpz_mod, perm, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0525     }
0526     else
0527     {
0528         fq_mat_invert_cols(mat->fq, perm, FQ_DEFAULT_CTX_FQ(ctx));
0529     }
0530 }
0531 
0532 /* Assignment  ***************************************************************/
0533 
0534 FQ_DEFAULT_MAT_INLINE void fq_default_mat_zero(fq_default_mat_t A,
0535                                                     const fq_default_ctx_t ctx)
0536 {
0537     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0538     {
0539         fq_zech_mat_zero(A->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0540     }
0541     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0542     {
0543         fq_nmod_mat_zero(A->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0544     }
0545     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0546     {
0547         nmod_mat_zero(A->nmod);
0548     }
0549     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0550     {
0551         fmpz_mod_mat_zero(A->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0552     }
0553     else
0554     {
0555         fq_mat_zero(A->fq, FQ_DEFAULT_CTX_FQ(ctx));
0556     }
0557 }
0558 
0559 FQ_DEFAULT_MAT_INLINE void fq_default_mat_one(fq_default_mat_t A,
0560                                                     const fq_default_ctx_t ctx)
0561 {
0562     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0563     {
0564         fq_zech_mat_one(A->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0565     }
0566     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0567     {
0568         fq_nmod_mat_one(A->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0569     }
0570     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0571     {
0572         nmod_mat_one(A->nmod);
0573     }
0574     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0575     {
0576         fmpz_mod_mat_one(A->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0577     }
0578     else
0579     {
0580         fq_mat_one(A->fq, FQ_DEFAULT_CTX_FQ(ctx));
0581     }
0582 }
0583 
0584 /* Conversions ***************************************************************/
0585 
0586 FQ_DEFAULT_MAT_INLINE
0587 void fq_default_mat_set_nmod_mat(fq_default_mat_t mat1,
0588                      const nmod_mat_t mat2, const fq_default_ctx_t ctx)
0589 {
0590     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0591     {
0592         fq_zech_mat_set_nmod_mat(mat1->fq_zech, mat2, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0593     }
0594     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0595     {
0596         fq_nmod_mat_set_nmod_mat(mat1->fq_nmod, mat2, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0597     }
0598     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0599     {
0600         nmod_mat_set(mat1->nmod, mat2);
0601     }
0602     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0603     {
0604         fmpz_mod_mat_set_nmod_mat(mat1->fmpz_mod, mat2, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0605     }
0606     else
0607     {
0608         fq_mat_set_nmod_mat(mat1->fq, mat2, FQ_DEFAULT_CTX_FQ(ctx));
0609     }
0610 }
0611 
0612 FQ_DEFAULT_MAT_INLINE
0613 void fq_default_mat_set_fmpz_mod_mat(fq_default_mat_t mat1,
0614                          const fmpz_mod_mat_t mat2, const fq_default_ctx_t ctx)
0615 {
0616     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0617     {
0618         fq_zech_mat_set_fmpz_mod_mat(mat1->fq_zech, mat2, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0619     }
0620     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0621     {
0622         fq_nmod_mat_set_fmpz_mod_mat(mat1->fq_nmod, mat2, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0623     }
0624     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0625     {
0626         fmpz_mat_get_nmod_mat(mat1->nmod, mat2);
0627     }
0628     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0629     {
0630         fmpz_mod_mat_set(mat1->fmpz_mod, mat2, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0631     }
0632     else
0633     {
0634         fq_mat_set_fmpz_mod_mat(mat1->fq, mat2, FQ_DEFAULT_CTX_FQ(ctx));
0635     }
0636 }
0637 
0638 FQ_DEFAULT_MAT_INLINE
0639 void fq_default_mat_set_fmpz_mat(fq_default_mat_t mat1,
0640                      const fmpz_mat_t mat2, const fq_default_ctx_t ctx)
0641 {
0642     fmpz_mod_mat_t mod_mat;
0643 
0644     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0645     {
0646         fmpz_mod_ctx_t ctx2;
0647         fmpz_t prime;
0648         fmpz_init_set_ui(prime, fq_zech_ctx_prime(FQ_DEFAULT_CTX_FQ_ZECH(ctx)));
0649         fmpz_mod_ctx_init(ctx2, prime);
0650         fmpz_mod_mat_init(mod_mat, mat2->r, mat2->c, ctx2);
0651         fmpz_mod_mat_set_fmpz_mat(mod_mat, mat2, ctx2);
0652         fq_zech_mat_set_fmpz_mod_mat(mat1->fq_zech, mod_mat, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0653         fmpz_mod_mat_clear(mod_mat, ctx2);
0654         fmpz_mod_ctx_clear(ctx2);
0655         fmpz_clear(prime);
0656     }
0657     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0658     {
0659 
0660         fmpz_mod_ctx_t ctx2;
0661         fmpz_t prime;
0662         fmpz_init_set_ui(prime, fq_nmod_ctx_prime(FQ_DEFAULT_CTX_FQ_NMOD(ctx)));
0663         fmpz_mod_ctx_init(ctx2, prime);
0664         fmpz_mod_mat_init(mod_mat, mat2->r, mat2->c, ctx2);
0665         fmpz_mod_mat_set_fmpz_mat(mod_mat, mat2, ctx2);
0666         fq_nmod_mat_set_fmpz_mod_mat(mat1->fq_nmod, mod_mat, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0667         fmpz_mod_mat_clear(mod_mat, ctx2);
0668         fmpz_mod_ctx_clear(ctx2);
0669         fmpz_clear(prime);
0670     }
0671     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0672     {
0673         fmpz_mat_get_nmod_mat(mat1->nmod, mat2);
0674         return;
0675     }
0676     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0677     {
0678         fmpz_mod_mat_set_fmpz_mat(mat1->fmpz_mod, mat2, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0679         return;
0680     }
0681     else
0682     {
0683         fmpz_mod_ctx_t ctx2;
0684         fmpz_mod_ctx_init(ctx2, fq_ctx_prime(FQ_DEFAULT_CTX_FQ(ctx)));
0685         fmpz_mod_mat_init(mod_mat, mat2->r, mat2->c, ctx2);
0686         fmpz_mod_mat_set_fmpz_mat(mod_mat, mat2, ctx2);
0687         fq_mat_set_fmpz_mod_mat(mat1->fq, mod_mat, FQ_DEFAULT_CTX_FQ(ctx));
0688         fmpz_mod_mat_clear(mod_mat, ctx2);
0689         fmpz_mod_ctx_clear(ctx2);
0690     }
0691 }
0692 
0693 /* Windows and concatenation */
0694 
0695 FQ_DEFAULT_MAT_INLINE
0696 void fq_default_mat_window_init(fq_default_mat_t window,
0697     const fq_default_mat_t mat, slong r1, slong c1, slong r2, slong c2,
0698                                                     const fq_default_ctx_t ctx)
0699 {
0700     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0701     {
0702         fq_zech_mat_window_init(window->fq_zech,
0703                                mat->fq_zech, r1, c1, r2, c2, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0704     }
0705     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0706     {
0707         fq_nmod_mat_window_init(window->fq_nmod,
0708                                mat->fq_nmod, r1, c1, r2, c2, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0709     }
0710     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0711     {
0712         nmod_mat_window_init(window->nmod,
0713                                mat->nmod, r1, c1, r2, c2);
0714     }
0715     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0716     {
0717         fmpz_mod_mat_window_init(window->fmpz_mod,
0718                                mat->fmpz_mod, r1, c1, r2, c2, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0719     }
0720     else
0721     {
0722         fq_mat_window_init(window->fq,
0723                                          mat->fq, r1, c1, r2, c2, FQ_DEFAULT_CTX_FQ(ctx));
0724     }
0725 }
0726 
0727 FQ_DEFAULT_MAT_INLINE
0728 void fq_default_mat_window_clear(fq_default_mat_t window,
0729                                                     const fq_default_ctx_t ctx)
0730 {
0731     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0732     {
0733         fq_zech_mat_window_clear(window->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0734     }
0735     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0736     {
0737         fq_nmod_mat_window_clear(window->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0738     }
0739     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0740     {
0741         nmod_mat_window_clear(window->nmod);
0742     }
0743     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0744     {
0745         fmpz_mod_mat_window_clear(window->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0746     }
0747     else
0748     {
0749         fq_mat_window_clear(window->fq, FQ_DEFAULT_CTX_FQ(ctx));
0750     }
0751 
0752 }
0753 
0754 FQ_DEFAULT_MAT_INLINE
0755 void fq_default_mat_concat_horizontal(fq_default_mat_t res,
0756           const fq_default_mat_t mat1,  const fq_default_mat_t mat2,
0757                                                     const fq_default_ctx_t ctx)
0758 {
0759     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0760     {
0761         fq_zech_mat_concat_horizontal(res->fq_zech,
0762                                mat1->fq_zech, mat2->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0763     }
0764     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0765     {
0766         fq_nmod_mat_concat_horizontal(res->fq_nmod,
0767                                mat1->fq_nmod, mat2->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0768     }
0769     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0770     {
0771         nmod_mat_concat_horizontal(res->nmod, mat1->nmod, mat2->nmod);
0772     }
0773     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0774     {
0775         fmpz_mod_mat_concat_horizontal(res->fmpz_mod,
0776                                        mat1->fmpz_mod, mat2->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0777     }
0778     else
0779     {
0780         fq_mat_concat_horizontal(res->fq, mat1->fq, mat2->fq, FQ_DEFAULT_CTX_FQ(ctx));
0781     }
0782 }
0783 
0784 FQ_DEFAULT_MAT_INLINE
0785 void fq_default_mat_concat_vertical(fq_default_mat_t res,
0786           const fq_default_mat_t mat1,  const fq_default_mat_t mat2,
0787                                                     const fq_default_ctx_t ctx)
0788 {
0789     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0790     {
0791         fq_zech_mat_concat_vertical(res->fq_zech,
0792                                mat1->fq_zech, mat2->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0793     }
0794     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0795     {
0796         fq_nmod_mat_concat_vertical(res->fq_nmod,
0797                                mat1->fq_nmod, mat2->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0798     }
0799     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0800     {
0801         nmod_mat_concat_vertical(res->nmod, mat1->nmod, mat2->nmod);
0802     }
0803     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0804     {
0805         fmpz_mod_mat_concat_vertical(res->fmpz_mod,
0806                                      mat1->fmpz_mod, mat2->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0807     }
0808     else
0809     {
0810         fq_mat_concat_vertical(res->fq, mat1->fq, mat2->fq, FQ_DEFAULT_CTX_FQ(ctx));
0811     }
0812 }
0813 
0814 /* Input and output  *********************************************************/
0815 
0816 #ifdef FLINT_HAVE_FILE
0817 int fq_default_mat_fprint(FILE * file, const fq_default_mat_t mat, const fq_default_ctx_t ctx);
0818 int fq_default_mat_fprint_pretty(FILE * file, const fq_default_mat_t mat, const fq_default_ctx_t ctx);
0819 #endif
0820 
0821 int fq_default_mat_print(const fq_default_mat_t mat, const fq_default_ctx_t ctx);
0822 int fq_default_mat_print_pretty(const fq_default_mat_t mat, const fq_default_ctx_t ctx);
0823 
0824 /* TODO: Read functions */
0825 
0826 /* Random matrix generation  *************************************************/
0827 
0828 FQ_DEFAULT_MAT_INLINE void fq_default_mat_randtest(fq_default_mat_t mat,
0829                                 flint_rand_t state, const fq_default_ctx_t ctx)
0830 {
0831     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0832     {
0833         fq_zech_mat_randtest(mat->fq_zech, state, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0834     }
0835     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0836     {
0837         fq_nmod_mat_randtest(mat->fq_nmod, state, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0838     }
0839     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0840     {
0841         nmod_mat_randtest(mat->nmod, state);
0842     }
0843     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0844     {
0845         fmpz_mod_mat_randtest(mat->fmpz_mod, state, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0846     }
0847     else
0848     {
0849         fq_mat_randtest(mat->fq, state, FQ_DEFAULT_CTX_FQ(ctx));
0850     }
0851 }
0852 
0853 FQ_DEFAULT_MAT_INLINE void fq_default_mat_randrank(fq_default_mat_t mat,
0854                     flint_rand_t state, slong rank, const fq_default_ctx_t ctx)
0855 {
0856     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0857     {
0858         fq_zech_mat_randrank(mat->fq_zech, state, rank, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0859     }
0860     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0861     {
0862         fq_nmod_mat_randrank(mat->fq_nmod, state, rank, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0863     }
0864     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0865     {
0866         nmod_mat_randrank(mat->nmod, state, rank);
0867     }
0868     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0869     {
0870         fmpz_mod_mat_randrank(mat->fmpz_mod, state, rank, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0871     }
0872     else
0873     {
0874         fq_mat_randrank(mat->fq, state, rank, FQ_DEFAULT_CTX_FQ(ctx));
0875     }
0876 }
0877 
0878 
0879 FQ_DEFAULT_MAT_INLINE
0880 void fq_default_mat_randops(fq_default_mat_t mat,
0881                    flint_rand_t state, slong count, const fq_default_ctx_t ctx)
0882 {
0883     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0884     {
0885         fq_zech_mat_randops(mat->fq_zech, state, count, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0886     }
0887     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0888     {
0889         fq_nmod_mat_randops(mat->fq_nmod, state, count, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0890     }
0891     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0892     {
0893         nmod_mat_randops(mat->nmod, state, count);
0894     }
0895     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0896     {
0897         fmpz_mod_mat_randops(mat->fmpz_mod, state, count, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0898     }
0899     else
0900     {
0901         fq_mat_randops(mat->fq, state, count, FQ_DEFAULT_CTX_FQ(ctx));
0902     }
0903 }
0904 
0905 FQ_DEFAULT_MAT_INLINE
0906 void fq_default_mat_randtril(fq_default_mat_t mat,
0907                       flint_rand_t state, int unit, const fq_default_ctx_t ctx)
0908 {
0909     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0910     {
0911         fq_zech_mat_randtril(mat->fq_zech, state, unit, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0912     }
0913     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0914     {
0915         fq_nmod_mat_randtril(mat->fq_nmod, state, unit, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0916     }
0917     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0918     {
0919         nmod_mat_randtril(mat->nmod, state, unit);
0920     }
0921     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0922     {
0923         fmpz_mod_mat_randtril(mat->fmpz_mod, state, unit, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0924     }
0925     else
0926     {
0927         fq_mat_randtril(mat->fq, state, unit, FQ_DEFAULT_CTX_FQ(ctx));
0928     }
0929 }
0930 
0931 FQ_DEFAULT_MAT_INLINE
0932 void fq_default_mat_randtriu(fq_default_mat_t mat,
0933                       flint_rand_t state, int unit, const fq_default_ctx_t ctx)
0934 {
0935     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0936     {
0937         fq_zech_mat_randtriu(mat->fq_zech, state, unit, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0938     }
0939     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0940     {
0941         fq_nmod_mat_randtriu(mat->fq_nmod, state, unit, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0942     }
0943     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0944     {
0945         nmod_mat_randtriu(mat->nmod, state, unit);
0946     }
0947     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0948     {
0949         fmpz_mod_mat_randtriu(mat->fmpz_mod, state, unit, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0950     }
0951     else
0952     {
0953         fq_mat_randtriu(mat->fq, state, unit, FQ_DEFAULT_CTX_FQ(ctx));
0954     }
0955 }
0956 
0957 /* Norms */
0958 
0959 /* Transpose */
0960 
0961 /* Addition and subtraction */
0962 
0963 FQ_DEFAULT_MAT_INLINE void fq_default_mat_add(fq_default_mat_t C,
0964                       const fq_default_mat_t A, const fq_default_mat_t B,
0965                                                     const fq_default_ctx_t ctx)
0966 {
0967     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0968     {
0969         fq_zech_mat_add(C->fq_zech, A->fq_zech, B->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0970     }
0971     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0972     {
0973         fq_nmod_mat_add(C->fq_nmod, A->fq_nmod, B->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
0974     }
0975     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
0976     {
0977         nmod_mat_add(C->nmod, A->nmod, B->nmod);
0978     }
0979     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
0980     {
0981         fmpz_mod_mat_add(C->fmpz_mod, A->fmpz_mod, B->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
0982     }
0983     else
0984     {
0985         fq_mat_add(C->fq, A->fq, B->fq, FQ_DEFAULT_CTX_FQ(ctx));
0986     }
0987 }
0988 
0989 FQ_DEFAULT_MAT_INLINE void fq_default_mat_sub(fq_default_mat_t C,
0990                       const fq_default_mat_t A, const fq_default_mat_t B,
0991                                                     const fq_default_ctx_t ctx)
0992 {
0993     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
0994     {
0995         fq_zech_mat_sub(C->fq_zech, A->fq_zech, B->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
0996     }
0997     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
0998     {
0999         fq_nmod_mat_sub(C->fq_nmod, A->fq_nmod, B->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1000     }
1001     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1002     {
1003         nmod_mat_sub(C->nmod, A->nmod, B->nmod);
1004     }
1005     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1006     {
1007         fmpz_mod_mat_sub(C->fmpz_mod, A->fmpz_mod, B->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1008     }
1009     else
1010     {
1011         fq_mat_sub(C->fq, A->fq, B->fq, FQ_DEFAULT_CTX_FQ(ctx));
1012     }
1013 }
1014 
1015 FQ_DEFAULT_MAT_INLINE void fq_default_mat_neg(fq_default_mat_t B,
1016                           const fq_default_mat_t A, const fq_default_ctx_t ctx)
1017 {
1018     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1019     {
1020         fq_zech_mat_neg(B->fq_zech, A->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1021     }
1022     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1023     {
1024         fq_nmod_mat_neg(B->fq_nmod, A->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1025     }
1026     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1027     {
1028         nmod_mat_neg(B->nmod, A->nmod);
1029     }
1030     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1031     {
1032         fmpz_mod_mat_neg(B->fmpz_mod, A->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1033     }
1034     else
1035     {
1036         fq_mat_neg(B->fq, A->fq, FQ_DEFAULT_CTX_FQ(ctx));
1037     }
1038 }
1039 
1040 FQ_DEFAULT_MAT_INLINE void fq_default_mat_submul(fq_default_mat_t D,
1041                         const fq_default_mat_t C, const fq_default_mat_t A,
1042                           const fq_default_mat_t B, const fq_default_ctx_t ctx)
1043 {
1044     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1045     {
1046         fq_zech_mat_submul(D->fq_zech,
1047                          C->fq_zech, A->fq_zech, B->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1048     }
1049     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1050     {
1051         fq_nmod_mat_submul(D->fq_nmod,
1052                          C->fq_nmod, A->fq_nmod, B->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1053     }
1054     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1055     {
1056         nmod_mat_submul(D->nmod, C->nmod, A->nmod, B->nmod);
1057     }
1058     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1059     {
1060         fmpz_mod_mat_submul(D->fmpz_mod, C->fmpz_mod, A->fmpz_mod, B->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1061     }
1062     else
1063     {
1064         fq_mat_submul(D->fq, C->fq, A->fq, B->fq, FQ_DEFAULT_CTX_FQ(ctx));
1065     }
1066 }
1067 
1068 /* Scalar operations */
1069 
1070 FQ_DEFAULT_MAT_INLINE void fq_default_mat_scalar_mul(fq_default_mat_t B,
1071                           const fq_default_mat_t A, const fq_default_t c, const fq_default_ctx_t ctx)
1072 {
1073     GR_IGNORE(gr_mat_mul_scalar((gr_mat_struct *) B, (const gr_mat_struct *) A, c, FQ_DEFAULT_GR_CTX(ctx)));
1074 }
1075 
1076 FQ_DEFAULT_MAT_INLINE void fq_default_mat_scalar_mul_fmpz(fq_default_mat_t B,
1077                           const fq_default_mat_t A, const fmpz_t c, const fq_default_ctx_t ctx)
1078 {
1079     GR_IGNORE(gr_mat_mul_fmpz((gr_mat_struct *) B, (const gr_mat_struct *) A, c, FQ_DEFAULT_GR_CTX(ctx)));
1080 }
1081 
1082 FQ_DEFAULT_MAT_INLINE void fq_default_mat_scalar_mul_si(fq_default_mat_t B,
1083                           const fq_default_mat_t A, const slong c, const fq_default_ctx_t ctx)
1084 {
1085     GR_IGNORE(gr_mat_mul_si((gr_mat_struct *) B, (const gr_mat_struct *) A, c, FQ_DEFAULT_GR_CTX(ctx)));
1086 }
1087 
1088 FQ_DEFAULT_MAT_INLINE void fq_default_mat_scalar_mul_ui(fq_default_mat_t B,
1089                           const fq_default_mat_t A, const ulong c, const fq_default_ctx_t ctx)
1090 {
1091     GR_IGNORE(gr_mat_mul_ui((gr_mat_struct *) B, (const gr_mat_struct *) A, c, FQ_DEFAULT_GR_CTX(ctx)));
1092 }
1093 
1094 
1095 /* Multiplication */
1096 
1097 FQ_DEFAULT_MAT_INLINE void fq_default_mat_mul(fq_default_mat_t C,
1098                       const fq_default_mat_t A, const fq_default_mat_t B,
1099                                                     const fq_default_ctx_t ctx)
1100 {
1101     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1102     {
1103         fq_zech_mat_mul(C->fq_zech, A->fq_zech, B->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1104     }
1105     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1106     {
1107         fq_nmod_mat_mul(C->fq_nmod, A->fq_nmod, B->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1108     }
1109     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1110     {
1111         nmod_mat_mul(C->nmod, A->nmod, B->nmod);
1112     }
1113     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1114     {
1115         fmpz_mod_mat_mul(C->fmpz_mod, A->fmpz_mod, B->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1116     }
1117     else
1118     {
1119         fq_mat_mul(C->fq, A->fq, B->fq, FQ_DEFAULT_CTX_FQ(ctx));
1120     }
1121 }
1122 
1123 FQ_DEFAULT_MAT_INLINE slong fq_default_mat_lu(slong * P,
1124                   fq_default_mat_t A, int rank_check, const fq_default_ctx_t ctx)
1125 {
1126     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1127     {
1128         return fq_zech_mat_lu(P, A->fq_zech, rank_check, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1129     }
1130     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1131     {
1132         return fq_nmod_mat_lu(P, A->fq_nmod, rank_check, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1133     }
1134     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1135     {
1136         return nmod_mat_lu(P, A->nmod, rank_check);
1137     }
1138     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1139     {
1140         return fmpz_mod_mat_lu(P, A->fmpz_mod, rank_check, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1141     }
1142     else
1143     {
1144         return fq_mat_lu(P, A->fq, rank_check, FQ_DEFAULT_CTX_FQ(ctx));
1145     }
1146 }
1147 
1148 /* Inverse *******************************************************************/
1149 
1150 FQ_DEFAULT_MAT_INLINE int fq_default_mat_inv(fq_default_mat_t B,
1151                                   fq_default_mat_t A, const fq_default_ctx_t ctx)
1152 {
1153     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1154     {
1155         return fq_zech_mat_inv(B->fq_zech, A->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1156     }
1157     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1158     {
1159         return fq_nmod_mat_inv(B->fq_nmod, A->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1160     }
1161     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1162     {
1163         return nmod_mat_inv(B->nmod, A->nmod);
1164     }
1165     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1166     {
1167         return fmpz_mod_mat_inv(B->fmpz_mod, A->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1168     }
1169     else
1170     {
1171         return fq_mat_inv(B->fq, A->fq, FQ_DEFAULT_CTX_FQ(ctx));
1172     }
1173 }
1174 
1175 /* Solving *******************************************************************/
1176 
1177 FQ_DEFAULT_MAT_INLINE slong fq_default_mat_rref(fq_default_mat_t B, const fq_default_mat_t A,
1178                                                     const fq_default_ctx_t ctx)
1179 {
1180     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1181     {
1182         return fq_zech_mat_rref(B->fq_zech, A->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1183     }
1184     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1185     {
1186         return fq_nmod_mat_rref(B->fq_nmod, A->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1187     }
1188     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1189     {
1190         nmod_mat_set(B->nmod, A->nmod);
1191         return nmod_mat_rref(B->nmod);
1192     }
1193     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1194     {
1195         return fmpz_mod_mat_rref(B->fmpz_mod, A->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1196     }
1197     else
1198     {
1199         return fq_mat_rref(B->fq, A->fq, FQ_DEFAULT_CTX_FQ(ctx));
1200     }
1201 }
1202 
1203 FQ_DEFAULT_MAT_INLINE slong fq_default_mat_nullspace(fq_default_mat_t X,
1204                           const fq_default_mat_t A, const fq_default_ctx_t ctx)
1205 {
1206     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1207     {
1208         return fq_zech_mat_nullspace(X->fq_zech, A->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1209     }
1210     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1211     {
1212         return fq_nmod_mat_nullspace(X->fq_nmod, A->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1213     }
1214     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1215     {
1216         return nmod_mat_nullspace(X->nmod, A->nmod);
1217     }
1218     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1219     {
1220         return fmpz_mod_mat_nullspace(X->fmpz_mod, A->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1221     }
1222     else
1223     {
1224         return fq_mat_nullspace(X->fq, A->fq, FQ_DEFAULT_CTX_FQ(ctx));
1225     }
1226 }
1227 
1228 FQ_DEFAULT_MAT_INLINE slong fq_default_mat_rank(const fq_default_mat_t A,
1229                                                     const fq_default_ctx_t ctx)
1230 {
1231     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1232     {
1233         return fq_zech_mat_rank(A->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1234     }
1235     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1236     {
1237         return fq_nmod_mat_rank(A->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1238     }
1239     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1240     {
1241         return nmod_mat_rank(A->nmod);
1242     }
1243     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1244     {
1245         return fmpz_mod_mat_rank(A->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1246     }
1247     else
1248     {
1249         return fq_mat_rank(A->fq, FQ_DEFAULT_CTX_FQ(ctx));
1250     }
1251 }
1252 
1253 FQ_DEFAULT_MAT_INLINE void fq_default_mat_solve_tril(fq_default_mat_t X,
1254                          const fq_default_mat_t L, const fq_default_mat_t B,
1255                                           int unit, const fq_default_ctx_t ctx)
1256 {
1257     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1258     {
1259         fq_zech_mat_solve_tril(X->fq_zech, L->fq_zech, B->fq_zech, unit, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1260     }
1261     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1262     {
1263         fq_nmod_mat_solve_tril(X->fq_nmod, L->fq_nmod, B->fq_nmod, unit, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1264     }
1265     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1266     {
1267         nmod_mat_solve_tril(X->nmod, L->nmod, B->nmod, unit);
1268     }
1269     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1270     {
1271         fmpz_mod_mat_solve_tril(X->fmpz_mod, L->fmpz_mod, B->fmpz_mod, unit, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1272     }
1273     else
1274     {
1275         fq_mat_solve_tril(X->fq, L->fq, B->fq, unit, FQ_DEFAULT_CTX_FQ(ctx));
1276     }
1277 }
1278 
1279 FQ_DEFAULT_MAT_INLINE void fq_default_mat_solve_triu(fq_default_mat_t X,
1280                         const fq_default_mat_t U, const fq_default_mat_t B,
1281                                           int unit, const fq_default_ctx_t ctx)
1282 {
1283     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1284     {
1285         fq_zech_mat_solve_triu(X->fq_zech, U->fq_zech, B->fq_zech, unit, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1286     }
1287     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1288     {
1289         fq_nmod_mat_solve_triu(X->fq_nmod, U->fq_nmod, B->fq_nmod, unit, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1290     }
1291     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1292     {
1293         nmod_mat_solve_triu(X->nmod, U->nmod, B->nmod, unit);
1294     }
1295     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1296     {
1297         fmpz_mod_mat_solve_triu(X->fmpz_mod, U->fmpz_mod, B->fmpz_mod, unit, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1298     }
1299     else
1300     {
1301         fq_mat_solve_triu(X->fq, U->fq, B->fq, unit, FQ_DEFAULT_CTX_FQ(ctx));
1302     }
1303 }
1304 
1305 /* Nonsingular solving *******************************************************/
1306 
1307 FQ_DEFAULT_MAT_INLINE int fq_default_mat_solve(fq_default_mat_t X,
1308                       const fq_default_mat_t A, const fq_default_mat_t C,
1309                                                     const fq_default_ctx_t ctx)
1310 {
1311     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1312     {
1313         return fq_zech_mat_solve(X->fq_zech,
1314                                      A->fq_zech, C->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1315     }
1316     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1317     {
1318         return fq_nmod_mat_solve(X->fq_nmod,
1319                                      A->fq_nmod, C->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1320     }
1321     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1322     {
1323         return nmod_mat_solve(X->nmod, A->nmod, C->nmod);
1324     }
1325     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1326     {
1327         return fmpz_mod_mat_solve(X->fmpz_mod, A->fmpz_mod, C->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1328     }
1329     else
1330     {
1331         return fq_mat_solve(X->fq, A->fq, C->fq, FQ_DEFAULT_CTX_FQ(ctx));
1332     }
1333 }
1334 
1335 /* Solving *******************************************************************/
1336 
1337 FQ_DEFAULT_MAT_INLINE int fq_default_mat_can_solve(fq_default_mat_t X,
1338                       const fq_default_mat_t A, const fq_default_mat_t B,
1339                                                     const fq_default_ctx_t ctx)
1340 {
1341     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1342     {
1343         return fq_zech_mat_can_solve(X->fq_zech,
1344                                      A->fq_zech, B->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1345     }
1346     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1347     {
1348         return fq_nmod_mat_can_solve(X->fq_nmod,
1349                                      A->fq_nmod, B->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1350     }
1351     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1352     {
1353         return nmod_mat_can_solve(X->nmod, A->nmod, B->nmod);
1354     }
1355     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1356     {
1357         return fmpz_mod_mat_can_solve(X->fmpz_mod, A->fmpz_mod, B->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1358     }
1359     else
1360     {
1361         return fq_mat_can_solve(X->fq, A->fq, B->fq, FQ_DEFAULT_CTX_FQ(ctx));
1362     }
1363 }
1364 
1365 /* Transforms ****************************************************************/
1366 
1367 FQ_DEFAULT_MAT_INLINE
1368 void fq_default_mat_similarity(fq_default_mat_t A, slong r,
1369                                       fq_default_t d, const fq_default_ctx_t ctx)
1370 {
1371     if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_ZECH)
1372     {
1373         fq_zech_mat_similarity(A->fq_zech, r, d->fq_zech, FQ_DEFAULT_CTX_FQ_ZECH(ctx));
1374     }
1375     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FQ_NMOD)
1376     {
1377         fq_nmod_mat_similarity(A->fq_nmod, r, d->fq_nmod, FQ_DEFAULT_CTX_FQ_NMOD(ctx));
1378     }
1379     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_NMOD)
1380     {
1381         nmod_mat_similarity(A->nmod, r, d->nmod);
1382     }
1383     else if (_FQ_DEFAULT_TYPE(ctx) == _FQ_DEFAULT_FMPZ_MOD)
1384     {
1385         fmpz_mod_mat_similarity(A->fmpz_mod, r, d->fmpz_mod, FQ_DEFAULT_CTX_FMPZ_MOD(ctx));
1386     }
1387     else
1388     {
1389         fq_mat_similarity(A->fq, r, d->fq, FQ_DEFAULT_CTX_FQ(ctx));
1390     }
1391 }
1392 
1393 /* Characteristic polynomial *************************************************/
1394 
1395 /* this prototype really lives in fq_poly_templates.h
1396  * FQ_DEFAULT_MAT_INLINE
1397  * void fq_default_mat_charpoly(fq_default_poly_t) p,
1398  *                            fq_default_mat_t A, const fq_default_ctx_t ctx)
1399  * {
1400  *   fq_default_mat_charpoly_danilevsky(p, A, ctx)
1401  * }
1402  */
1403 
1404 /* Minimal polynomial ********************************************************/
1405 
1406 /* this prototype really lives in fq_poly_templates.h
1407  * FQ_DEFAULT_MAT_INLINE
1408  * void fq_default_mat_minpoly(fq_default_poly_t) p,
1409  *                   const fq_default_mat_t X, const fq_default_ctx_t ctx)
1410  */
1411 
1412 #ifdef __cplusplus
1413 }
1414 #endif
1415 
1416 #endif