Computing endomorphism ring of finite groups via computer I'm trying to figure out the structure of endomorphisms of some some rather precise class of finte solvable groups and I'm looking for "the less" expensive way to compute End$(G)$ with some computer system. I've been trying with the GAP function AllHomomorphismsClasses, which gets overwhelmed by the number of generators of the group really soon, so I'm wondering if there is a better way to compute End$(G)$.
One of my tries has been the MAGMA function Homomorphisms, but it seems that it is even slower. A small instance of comparison between the two is the following.
g:=SmallGroup(1458,556);;
h:=AllHomomorphismClasses(g,g);;

in GAP gives me an answer in less than a minute, while
g:=SmallGroup(1458,556);;
g1:=FPGroup(g);;
h:=Homomorphisms(g1,g);;

in MAGMA is running forever (viz. >>1 minute).
So, is there a better way, particularly with MAGMA, that I'm missing?
(I guess I can apply Homomorphisms in MAGMA to a faithful permutation representation of $g$, but I don't think it would improve things that much)
 A: In GAP, AllHomomorphismClasses is (and I'm writing this as the person who wrote the function) a "toy" function that is provided to try small examples in class. (Concretely, Gallian's textbook has exercises about homomorphisms between dihedral groups.) It tries out all possibilities in a backtrack search and thus is likely to be unperformative for groups of order more than a few hundred  that cannot be 2-generated.
What should work substantially better (for groups that are still reasonably small) is to test all subgroups and quotients for isomorphisms. This uses the fact that the isomorphism test performs typically much better than the brute-force image search.
The following function (which takes just a few seconds for the given group) does this:
EndoSeeds:=function(G)
local u,n,e,a,le,q,v,i,j,iso,fingerprint,asAuto,nat,qid;
  fingerprint:=function(sub)
    if Size(sub)<2000 and not Size(sub) in [512,1024] then
      return IdGroup(sub);
    else return Collected(List(ConjugacyClasses(sub),
      x->[Order(Representative(x)),Size(x)]));
    fi;
  end;
  a:=AutomorphismGroup(G);
  u:=List(ConjugacyClassesSubgroups(G),Representative);
  asAuto:=function(sub,hom) return Image(hom,sub);end;
  n:=NormalSubgroups(G);
  n:=List(Orbits(a,n,asAuto),x->x[1]);
  e:=[];
  # go through normal subgroups in deescending order
  SortBy(n,Size);
  n:=Reversed(n);
  for i in n do
    if Size(i)=1 then
      q:=G;
      le:=[IdentityMapping(G)];
    else
      nat:=NaturalHomomorphismByNormalSubgroup(G,i);
      q:=Image(nat);
      qid:=fingerprint(q);
      v:=Filtered(u,x->Size(x)=Size(q) and fingerprint(x)=qid);
      # fuse under automorphisms
      if Length(v)>1 then
        v:=List(Orbits(a,v,asAuto),x->x[1]);
      fi;
      le:=[];
      for j in v do
        iso:=IsomorphismGroups(q,j);
        if iso<>fail then
          Add(le,nat*iso);
        fi;
      od;
    fi;
    Print("Factor order ",Size(q),", ",Length(v)," subgroups, ",
      Length(le)," maps\n");
    Append(e,le);

  od;
  return e;
end;

It returns representatives of homomorphisms $\phi\colon G\to G$, up to the action of $\mbox{Aut}(G)\times\mbox{Aut}(G)$ on kernels and images, as well as the action of $\mbox{Aut}(\mbox{Image}(\phi))$ on the homomorphisms. It should not be hard to expand to the full set of endomorphisms.
