Skip to content

Remove POW_MAT_INT to speed up matrix powering#6293

Open
fingolfin wants to merge 1 commit intomasterfrom
mh/POW_MAT_INT
Open

Remove POW_MAT_INT to speed up matrix powering#6293
fingolfin wants to merge 1 commit intomasterfrom
mh/POW_MAT_INT

Conversation

@fingolfin
Copy link
Copy Markdown
Member

I understand that in theory, this provides a speedup. But in practice, I could not find a single case where it was faster than POW_OBJ_INT, but many were it was dramatically slower.

Here are some timings to back this up:

gap> x:=PseudoRandom(GL(2,5));;e:=30000000;;
gap> for i in [1..10000] do x:=POW_MAT_INT(x,e); od; time;
507
gap> for i in [1..10000] do x:=POW_OBJ_INT(x,e); od; time;
36

gap> x:=PseudoRandom(GL(3,127));;e:=30000000;;
gap> for i in [1..10000] do x:=POW_MAT_INT(x,e); od; time;
634
gap> for i in [1..10000] do x:=POW_OBJ_INT(x,e); od; time;
67

gap> x:=PseudoRandom(GL(20,256));;e:=30000000;;
gap> for i in [1..10000] do x:=POW_MAT_INT(x,e); od; time;
10378
gap> for i in [1..10000] do x:=POW_OBJ_INT(x,e); od; time;
3566

CC @frankluebeck who wrote that code -- maybe he can point me to cases were POW_MAT_INT is faster, then we can look into tuning the heuristics for when to switch.

I understand that in theory, this provides a speedup. But in
practice, I could not find a single case where it was faster than
POW_OBJ_INT, but many were it was dramatically slower.

Here are some timings to back this up:

    gap> x:=PseudoRandom(GL(2,5));;e:=30000000;;
    gap> for i in [1..10000] do x:=POW_MAT_INT(x,e); od; time;
    507
    gap> for i in [1..10000] do x:=POW_OBJ_INT(x,e); od; time;
    36

    gap> x:=PseudoRandom(GL(3,127));;e:=30000000;;
    gap> for i in [1..10000] do x:=POW_MAT_INT(x,e); od; time;
    634
    gap> for i in [1..10000] do x:=POW_OBJ_INT(x,e); od; time;
    67

    gap> x:=PseudoRandom(GL(20,256));;e:=30000000;;
    gap> for i in [1..10000] do x:=POW_MAT_INT(x,e); od; time;
    10378
    gap> for i in [1..10000] do x:=POW_OBJ_INT(x,e); od; time;
    3566
@frankluebeck
Copy link
Copy Markdown
Member

I do not approve this pull request. This code should not be removed. But the heuristics for choosing the best method in each case can certainly be improved. Certainly in the tiny cases you mention above.

POW_MAT_INT was written to speed up typical applications in group recognition (recog package).

In that context typical calls are for matrices in GL(n,q) and exponents in the order of q^n, e.g.,

gap> x := PseudoRandom(GL(200,251));;
gap> e := 251^200;;
gap> for i in [1..10] do x:=POW_OBJ_INT(x,e); od; time;
84571
gap> for i in [1..10] do x:=POW_MAT_INT(x,e); od; time;
1142

For compressed matrices over small finite fields the matrix multiplication is quite fast, and the overhead in POW_MAT_INT will only beat POW_OBJ_INT in somehow large cases.

For non-compressed matrices the break even point is much lower, e.g.,

gap> x := PseudoRandom(GL(20,3^10));;
gap> e := 10000000;;
gap> for i in [1..100] do x:=POW_OBJ_INT(x,e); od; time;
298
gap> for i in [1..100] do x:=POW_MAT_INT(x,e); od; time;
288
gap> for i in [1..100] do x:=POW_BY_MINPOL(x,e); od; time;   # see below
279

In an attempt to improve the heuristics it may also be useful to reenable the method which is currently commented out (many matrices have efficient methods for characteristic/minimal polynomial and for large exponents one can reduce to n multiplications):

POW_BY_MINPOL := function(mat, n)
  local pol, indet;
  # generic method for small n, break even point probably a bit lower,
  # needs rethinking and some experiments.
  if n < 2^Length(mat) then
    return POW_OBJ_INT(mat, n);
  fi;
  pol := MinimalPolynomial(mat); 
  # could be further improved using PowerModCoeffs:
  indet := IndeterminateOfUnivariateRationalFunction(pol);
  # cost of this needs to be investigated
  pol := PowerMod(indet, n, pol);
  # now we are sure that we need at most Length(mat) matrix multiplications
  return Value(pol, mat);
end;

As far as I remember, after introducing POW_MAT_INT there was the idea to implement a kernel version of this for compressed matrices. Therefore we did not work hard to find a good heuristic. But so far nobody implemented this ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic: library topic: performance bugs or enhancements related to performance (improvements or regressions)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants