| Peter Bruin on Tue, 18 Jun 2013 14:54:42 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
| FlxqM_gauss, FlxqM_inv and FqM_inv |
Hello, For personal use I needed the functions FlxqM_gauss and FlxqM_inv. Probably it would be nice to have these in PARI, so I am attaching a patch that adds these functions (as straightforward adaptations of the existing equivalent functions for other base fields). I also added FqM_inv since I noticed it was missing and it was trivial to implement. The patch is based on version 2.6.1 (development git-1e829d2). I thought about adapting FqM_gauss to use the new FlxqM_gauss in case the characteristic of the field is small, but I didn't know if it would be an improvement, and the function FlxM_to_FqM would have to be implemented first. Thanks, Peter
diff --git a/doc/usersch5.tex b/doc/usersch5.tex
index 4abf12c..34c9429 100644
--- a/doc/usersch5.tex
+++ b/doc/usersch5.tex
@@ -3651,6 +3651,9 @@ or \kbd{NULL} if none exist.
\fun{GEN}{FqM_image}{GEN x, GEN T, GEN p} as \kbd{image}
+\fun{GEN}{FqM_inv}{GEN x, GEN T, GEN p} returns the inverse of \kbd{x}, or
+\kbd{NULL} if \kbd{x} is not invertible.
+
\fun{long}{FqM_rank}{GEN x, GEN T, GEN p} as \kbd{rank}
\fun{GEN}{FqM_suppl}{GEN x, GEN T, GEN p} as \kbd{suppl}
@@ -3873,10 +3876,14 @@ and \kbd{y}
\fun{GEN}{FlxM_Flx_add_shallow}{GEN x, GEN y, ulong p} as
\kbd{RgM\_Rg\_add\_shallow}.
+\fun{GEN}{FlxqM_gauss}{GEN a, GEN b, GEN T, ulong p}
+
\fun{GEN}{FlxqM_ker}{GEN x, GEN T, ulong p}
\fun{GEN}{FlxqM_image}{GEN x, GEN T, ulong p}
+\fun{GEN}{FlxqM_inv}{GEN x, GEN T, ulong p}
+
\fun{long}{FlxqM_rank}{GEN x, GEN T, ulong p}
\subsec{\kbd{Zlm}}
diff --git a/src/basemath/alglin1.c b/src/basemath/alglin1.c
index c3fc338..4dec07d 100644
--- a/src/basemath/alglin1.c
+++ b/src/basemath/alglin1.c
@@ -1750,6 +1750,30 @@ FpM_gauss(GEN a, GEN b, GEN p)
u = gen_Gauss(a,b,E,ff);
return u ? gerepilecopy(av, iscol? gel(u,1): u): u;
}
+
+GEN
+FlxqM_gauss(GEN a, GEN b, GEN T, ulong p)
+{
+ pari_sp av = avma;
+ long li, aco = lg(a)-1;
+ int iscol;
+ GEN u;
+ const struct bb_field *ff;
+ void *E;
+
+ if (!init_gauss(a, &b, &aco, &li, &iscol))
+ return cgetg(1, iscol ? t_COL : t_MAT);
+ ff= get_Flxq_field(&E, T, p);
+ u = gen_Gauss(a, b, E, ff);
+ return u ? gerepilecopy(av, iscol ? gel(u,1) : u) : u;
+}
+
+GEN
+FlxqM_inv(GEN a, GEN T, ulong p)
+{
+ return FlxqM_gauss(a, NULL, T, p);
+}
+
GEN
FqM_gauss(GEN a, GEN b, GEN T, GEN p)
{
@@ -1767,6 +1791,12 @@ FqM_gauss(GEN a, GEN b, GEN T, GEN p)
return u ? gerepilecopy(av, iscol? gel(u,1): u): u;
}
+GEN
+FqM_inv(GEN a, GEN T, GEN p)
+{
+ return FqM_gauss(a, NULL, T, p);
+}
+
/* Dixon p-adic lifting algorithm.
* Numer. Math. 40, 137-141 (1982), DOI: 10.1007/BF01459082 */
GEN
diff --git a/src/headers/paridecl.h b/src/headers/paridecl.h
index 939b710..9947c46 100644
--- a/src/headers/paridecl.h
+++ b/src/headers/paridecl.h
@@ -888,8 +888,10 @@ GEN Flm_inv(GEN x, ulong p);
GEN Flm_ker(GEN x, ulong p);
GEN Flm_ker_sp(GEN x, ulong p, long deplin);
long Flm_rank(GEN x, ulong p);
+GEN FlxqM_gauss(GEN a, GEN b, GEN T, ulong p);
GEN FlxqM_ker(GEN x, GEN T, ulong p);
GEN FlxqM_image(GEN x, GEN T, ulong p);
+GEN FlxqM_inv(GEN x, GEN T, ulong p);
long FlxqM_rank(GEN x, GEN T, ulong p);
GEN FpM_deplin(GEN x, GEN p);
GEN FpM_det(GEN x, GEN p);
@@ -906,6 +908,7 @@ GEN FqM_deplin(GEN x, GEN T, GEN p);
GEN FqM_gauss(GEN a, GEN b, GEN T, GEN p);
GEN FqM_ker(GEN x, GEN T, GEN p);
GEN FqM_image(GEN x, GEN T, GEN p);
+GEN FqM_inv(GEN x, GEN T, GEN p);
long FqM_rank(GEN a, GEN T, GEN p);
GEN FqM_suppl(GEN x, GEN T, GEN p);
GEN QM_inv(GEN M, GEN dM);