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);