Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/qpa/lib/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 4.0.2024 mit Größe 135 kB image not shown  

Quellverzeichnis  modulehom.gi   Sprache: unbekannt

 
# GAP Implementation
# $Id: homomorphisms.gi,v 1.40 2012/09/28 12:57:10 sunnyquiver Exp $

#############################################################################
##
#M  ImageElm( <map>, <elm> )  . . . for PathAlgebraMatModuleMap and element
##
InstallMethod( ImageElm, 
    "for a map between representations and an element in a representation.",
    [ IsPathAlgebraMatModuleHomomorphism, IsAlgebraModuleElement ], 0, 
    function( map, elem )

    local elt, n, fam, image, temp, zero, new_image;

    if elem in Source(map) then
        if Dimension(Range(map)) = 0 then
            return Zero(Range(map));
        fi;
   elt := ExtRepOfObj(elem);
        n := Zero(Range(map));
        image := List([1..Length(elt![1])], x -> elt![1][x]*map!.maps[x]);

        image := PathModuleElem(FamilyObj(Zero(Range(map))![1]),image);        
        return Objectify( TypeObj( n ), [ image ] );
    else
        Error("the element entered is not an element in the source of the map,");
    fi; 
end);

#############################################################################
##
#M  ImagesSet( <map>, <elms> ) . . for a PathAlgebraMatModuleMap and finite collection
##
InstallMethod( ImagesSet, 
    "for a map between representations and a set of elements in a representation.",
    [ IsPathAlgebraMatModuleHomomorphism, IsCollection ], 0, 
    function( map, elms )

    local elt, B, images;

    images := [];
    if IsList(elms) then
        if IsFinite(elms) then
            B := elms;
        fi;
    else
        if IsPathAlgebraMatModule(elms) then 
            B := BasisVectors(CanonicalBasis(elms));
        else
            Error("input of wrong type,");
        fi;
    fi;
    for elt in B do
       if ImageElm(map,elt) <> Zero(Range(map)) then 
          Add(images,ImageElm(map,elt));
       fi;
    od;
    return images;
end
);
#############################################################################
##
#M  PreImagesRepresentative( <map>, <elms> ) . . for a 
##                              PathAlgebraMatModuleMap and finite collection
##
InstallMethod( PreImagesRepresentative, 
    "for a map between representations and an element in a representation.",
    [ IsPathAlgebraMatModuleHomomorphism, IsAlgebraModuleElement ], 0, 
    function( map, elem )

    local elt, m, fam, preimage;

    if elem in Range(map) then
        elt := ExtRepOfObj(elem)![1];
        m := Basis(Source(map))[1];
        preimage := List([1..Length(elt)], x -> SolutionMat(map!.maps[x],elt[x]));
        if ForAll(preimage,x -> x <> fail) then 
           preimage := PathModuleElem(FamilyObj(Zero(Source(map))![1]),preimage);        
           return Objectify( TypeObj( m ), [ preimage ] );
        else
    return fail;
        fi;
    else
        Error("the element entered is not an element in the range of the map,");
    fi; 
end);

#######################################################################
##
#O  RightModuleHomOverAlgebra( <M>, <N>, <linmaps> )
##
##  This function constructs a homomorphism  f  from the module  <M>  to
##  the module  <N>  from the linear maps given in  <linmaps>. The 
##  function checks if  <M>  and  <N>  are modules over the same algebra 
##  and checks if the linear maps  <linmaps>  defines a homomorphism from  
##  <M>  to  <N>. The source and the range of  f  can be recovered from 
##  f  via the function  Source(f)  and  Range(f). The linear maps can 
##  be recovered via  f!.maps  or  
##  MatricesOfPathAlgebraMatModuleHomomorphism(f).
##
InstallMethod( RightModuleHomOverAlgebra,
    "for two representations of a quiver",
    [ IsPathAlgebraMatModule, IsPathAlgebraMatModule, IsList ], 0,
    function( M, N, linmaps)

    local A, K, mat_M, mat_N, map, Fam, dim_M, dim_N, Q, arrows, 
        vertices, a, i, origin, target, j;

    A := RightActingAlgebra(M); 
    if A <> RightActingAlgebra(N) then
        Error("the two modules are not over the same algebra, ");
    fi;
    dim_M := DimensionVector(M);
    dim_N := DimensionVector(N);
#
# Checking the number of matrices entered. 
#
    if Length( linmaps ) <> Length(dim_M) then 
        Error("the number of matrices entered is wrong,");
    fi;     
#
# Check the matrices of linmaps
#
    K := LeftActingDomain(A);
    for i in [1..Length(dim_M)] do
        if ( dim_M[i] = 0 ) then 
            if dim_N[i] = 0 then 
         if linmaps[i] <> NullMat(1,1,K) then 
                     Error("the dimension of matrix number ",i," is wrong (A),");
                fi; 
            else
                if linmaps[i] <> NullMat(1,dim_N[i],K) then
                    Error("the dimension of matrix number ",i," is wrong (B),");
                fi;
            fi;
        else
            if dim_N[i] = 0 then
                if linmaps[i] <> NullMat(dim_M[i],1,K) then 
                    Error("the dimension of matrix number ",i," is wrong (C),");
                fi;
            else          
                if DimensionsMat(linmaps[i])[1] <> dim_M[i] or DimensionsMat(linmaps[i])[2] <> dim_N[i] then
                    Error("the dimension of matrix number ",i," is wrong (D),"); 
                fi;
            fi;
        fi;   
    od;

# Check commutativity relations with the matrices in M and N.
#
    mat_M := MatricesOfPathAlgebraModule(M);
    mat_N := MatricesOfPathAlgebraModule(N);
    Q := QuiverOfPathAlgebra(A);
    arrows   := ArrowsOfQuiver(Q);
    vertices := VerticesOfQuiver(Q);
    for a in arrows do
        i := Position(arrows,a); 
        origin := Position(vertices,SourceOfPath(a));
        target := Position(vertices,TargetOfPath(a)); 
        if mat_M[i]*linmaps[target] <> linmaps[origin]*mat_N[i] then 
            Error("entered map is not a module map between the representations entered, error for vertex number ",i," and arrow ",a,",");
        fi;
    od;
#
#
    map := Objectify( NewType( CollectionsFamily( GeneralMappingsFamily(
                   ElementsFamily( FamilyObj( M ) ),
                   ElementsFamily( FamilyObj( N ) ) ) ), 
                   IsPathAlgebraMatModuleHomomorphism and IsPathAlgebraMatModuleHomomorphismRep ), rec( maps := linmaps ));
    SetPathAlgebraOfMatModuleMap(map, A);
    SetSource(map, M);
    SetRange(map, N);  
    SetIsWholeFamily(map, true);
    
    return map;
end 
);

#######################################################################
##
#O  MatricesOfPathAlgebraMatModuleHomomorphism( <f> )
##
##  This function returns the matrices defining the homomorphism
##  <f>. 
##
InstallMethod( MatricesOfPathAlgebraMatModuleHomomorphism, 
    "for a PathAlgebraMatModuleHomomorphism",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f )
    return f!.maps;  
end
);

#######################################################################
##
#M  ViewObj( <f> )
##
##  This function defines how View prints a 
##  PathAlgebraMatModuleHomomorphism  <f>.
##
InstallMethod( ViewObj, 
    "for a PathAlgebraMatModuleHomomorphism",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ], NICE_FLAGS+1,
    function ( f );

    Print("<");
    View(Source(f));
    Print(" ---> ");
    View(Range(f));
    Print(">");
end
); 

#######################################################################
##
#M  PrintObj( <f> )
##
##  This function defines how Print prints a 
##  PathAlgebraMatModuleHomomorphism  <f>.
##
InstallMethod( PrintObj, 
    "for a PathAlgebraMatModuleHomomorphism",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ], NICE_FLAGS + 1,
    function ( f );

    Print("<",Source(f)," ---> ",Range(f),">");
end
); 

#######################################################################
##
#M  Display( <f> )
##
##  This function defines how Display prints a 
##  PathAlgebraMatModuleHomomorphism  <f>.
##
InstallMethod( Display, 
    "for a PathAlgebraMatModuleHomomorphism",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ], NICE_FLAGS + 1,
    function ( f )
    
    local i;

    Print(f);
    Print("\nwith ");
    for i in [1..Length(DimensionVector(Source(f)))] do
        Print("linear map for vertex number ",i,":\n");
        PrintArray(f!.maps[i]);
    od;
end
); 

#######################################################################
##
#M  Zero( <f> )
##
##  This function returns the zero mapping with the same source and 
##  range as  <f>. 
##
InstallMethod ( Zero, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f )
    
    local M, N, K, dim_M, dim_N, i, mats;

    M := Source(f);
    N := Range(f);
    K := LeftActingDomain(Source(f));
    dim_M := DimensionVector(M);
    dim_N := DimensionVector(N);
    mats := [];
    for i in [1..Length(dim_M)] do
        if dim_M[i] = 0 then
            if dim_N[i] = 0 then 
                Add(mats,NullMat(1,1,K));
            else
                Add(mats,NullMat(1,dim_N[i],K));
            fi;
        else
            if dim_N[i] = 0 then 
                Add(mats,NullMat(dim_M[i],1,K));
            else
                Add(mats,NullMat(dim_M[i],dim_N[i],K));
            fi;
        fi;
    od;
  
    return RightModuleHomOverAlgebra(Source(f),Range(f),mats);
end
);

#######################################################################
##
#M  ZeroMapping( <M>, <N> )
##
##  This function returns the zero mapping from the module  <M>  to the 
##  module  <N>. 
##
InstallMethod ( ZeroMapping, 
    " between two PathAlgebraMatModule's ",
    true,
    [ IsPathAlgebraMatModule, IsPathAlgebraMatModule ],
    0,
    function( M, N )
    
    local A, K, dim_M, dim_N, i, mats;

    A := RightActingAlgebra(M);
    if ( A = RightActingAlgebra(N) ) then 
        K := LeftActingDomain(M);
        dim_M := DimensionVector(M);
        dim_N := DimensionVector(N);
        mats  := [];
        for i in [1..Length(dim_M)] do
            if dim_M[i] = 0 then
                if dim_N[i] = 0 then 
                    Add(mats,NullMat(1,1,K));
                else
                    Add(mats,NullMat(1,dim_N[i],K));
                fi;
            else
                if dim_N[i] = 0 then 
                    Add(mats,NullMat(dim_M[i],1,K));
                else
                    Add(mats,NullMat(dim_M[i],dim_N[i],K));
                fi;
            fi;
        od;
  
        return RightModuleHomOverAlgebra(M,N,mats);
    else
        Error("the two modules entered are not modules of one and the same algebra, or they are not modules over the same (quotient of a) path algebra, ");
    fi;
end
);

#######################################################################
##
#M  IdentityMapping( <M> )
##
##  This function returns the identity homomorphism from  <M>  to  <M>.
##
InstallMethod ( IdentityMapping, 
    "for a PathAlgebraMatModule",
    true,
    [ IsPathAlgebraMatModule ],
    0,
    function( M )
    
    local K, dim_M, i, mats;
#
# Representing the identity map from M to M with identity matrices 
# of the right size, including if dim_M[i] = 0, then the identity 
# is represented by a one-by-one identity matrix.
#
    K := LeftActingDomain(M);
    dim_M := DimensionVector(M);
    mats := [];
    for i in [1..Length(dim_M)] do
        if dim_M[i] = 0 then
            Add(mats,NullMat(1,1,K));
        else
            Add(mats,IdentityMat(dim_M[i],K));
        fi;
    od;
    
    return RightModuleHomOverAlgebra(M,M,mats);
end
);

#######################################################################
##
#M  \=( <f>, <g> )
##
##  This function returns true if the homomorphisms  <f>  and  <g>  have
##  the same source, the same range and the matrices defining the 
##  homomorphisms are identitical.
##
InstallMethod ( \=, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism, IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f, g )
    
    local a;

    if ( Source(f) = Source(g) ) and ( Range(f) = Range(g) ) 
       and ( f!.maps = g!.maps ) then
        return true;
    else
        return false;
    fi;
end
);

#######################################################################
##
#O  SubRepresentationInclusion( <M>, <gen> )
##
##  This function returns the inclusion from the submodule of  <M>  
##  generated by the elements  <gen>  to the module  <M>. The function
##  checks if all the elements on the list  <gen>  are elements of  the
##  module  <M>. 
##
InstallMethod( SubRepresentationInclusion,
    "for a path algebra module and list of its elements",
    true,
    [IsPathAlgebraMatModule, IsList], 0,
    function( M, gen )

    local A, q, K, num_vert, basis_M, vertices, arrows_as_path, arrows_of_quiver, 
          newgen, g, v, submodspan, temp, new, V_list, m, V, basis_submod, submod_list, 
          dim_vect_sub, i, cnt, j, dim_size, s, t, big_mat, a, mat, dom_a, im_a, pd, 
          pi, arrow, submodule, dim_vect_M, dim_size_M, inclusion, map;

    if not ForAll(gen, g -> g in M) then
        Error("entered elements are not in the module <M>, ");
    fi;

    A := RightActingAlgebra(M);
    q := QuiverOfPathAlgebra(A);
    K := LeftActingDomain(M);
    num_vert := Length(VerticesOfQuiver(q));
    basis_M := Basis(M);
#
# vertices, vertices as elements of algebra
# arrows_as_path, arrows as elements of algebra
# arrows, as arrows in the quiver
#
    if Length(gen) = 0 then 
        return ZeroMapping(ZeroModule(A),M);
    else
        vertices := List(VerticesOfQuiver(q), x -> x*One(A));
        arrows_as_path := List(ArrowsOfQuiver(q), x -> x*One(A));
        arrows_of_quiver := GeneratorsOfQuiver(q){[1+num_vert..num_vert+Length(ArrowsOfQuiver(q))]};
#
# Ensuring uniform generators
#
        newgen := [];
        for g in gen do 
            for v in vertices do 
                if g^v <> Zero(M) then 
                    Add(newgen,g^v);
                fi;
            od;
        od;
#
# Finding the linear span of the submodule generated by gen in M
#  
        submodspan := [];
        temp := [];
        new := newgen;
        while new <> [] do
            for m in new do
                for a in arrows_as_path do
                    if m^a <> Zero(M) then
                        Add(temp,m^a);            
                    fi;
                od;
            od;
            Append(submodspan,new);
            new := temp;
            temp := [];
        od;
        V_list := List(submodspan, x -> Coefficients(basis_M,x));
        V := VectorSpace(K,V_list);
        basis_submod := CanonicalBasis(V);
#
# Converting elements in basis_submod to a list of elements in M 
#
        submod_list := List(basis_submod, x -> LinearCombination(basis_M,x));
#
# Finding the dimension vector of the submodule of M
#
        dim_vect_sub:=[];
        for i in [1.. num_vert] do
            cnt := 0;
            for j in [1..Length(submod_list)] do
                if submod_list[j]^vertices[i] <> Zero(M) then
                    cnt:=cnt+1;   
                fi;
            od;
            Add(dim_vect_sub,cnt);    
        od;
        if Dimension(V) <> Sum(dim_vect_sub) then
            Error("Bug alert: Something is wrong in this code! Report this.\n");
        fi;
#    
# CanonicalBasis(V) gives the basis in "upper triangular form", so that 
# first comes the basis vectors for the vector space in vertex 1, in 
# vertex 2, ...., in vertex n. Next we find the intervals of the basis
# vector [[?..?],[?..?],...,[?..?]]. Is no basis vectors for a vertex, [] is entered.
#
        dim_size := [];
        s := 1;
        t := 0;
        for i in [1..Length(vertices)] do
            t := dim_vect_sub[i] + t;
            if t < s then 
                Add(dim_size,[]);
            else
                Add(dim_size,[s..t]);
            fi;
            s := t + 1;
        od;  
#
# Finding the submodule as a representation of the quiver
#  
        big_mat := [];
        for a in arrows_as_path do
            mat := [];
            for v in vertices do
                if v*a <> Zero(A) then
                    dom_a := v;
                fi;
            od;
            for v in vertices do
                if a*v <> Zero(A) then
                    im_a := v;
                fi;
            od; 
            
            pd := Position(vertices,dom_a);
            pi := Position(vertices,im_a);
            
            arrow := arrows_of_quiver[Position(arrows_as_path,a)];
            if dim_vect_sub[pd] <> 0 and dim_vect_sub[pi] <> 0 then 
                for m in submod_list{dim_size[pd]} do
                    Add(mat,Coefficients(basis_submod,Coefficients(basis_M,m^a)){dim_size[pi]}); 
                od;
                Add(big_mat,[String(arrow),mat]);
            fi;
        od;
        
        if IsPathAlgebra(A) then 
            submodule := RightModuleOverPathAlgebra(A, dim_vect_sub, big_mat);
        else
            submodule := RightModuleOverPathAlgebra(A, dim_vect_sub, big_mat); 
        fi;      

#
# Finding inclusion map of submodule into M
#
        mat := [];
        for i in [1..Length(basis_submod)] do
            Add(mat,basis_submod[i]);
        od;
        
        dim_vect_M := DimensionVector(M);
        dim_size_M := [];
        s := 1;
        t := 0;
        for i in [1..Length(vertices)] do
            t := dim_vect_M[i] + t;
            if t < s then 
                Add(dim_size_M,[]);
            else
                Add(dim_size_M,[s..t]);
            fi;
            s := t + 1;
        od;
        
        inclusion := [];
        for i in [1..Length(vertices)] do
            if dim_vect_sub[i] = 0 then
                if dim_vect_M[i] = 0 then 
                    Add(inclusion,NullMat(1,1,K));
                else
                    Add(inclusion,NullMat(1,dim_vect_M[i],K)); 
                fi;
            else 
                Add(inclusion,mat{dim_size[i]}{dim_size_M[i]});
            fi;
        od;
        return RightModuleHomOverAlgebra(submodule,M,inclusion);
    fi;
end
);

#######################################################################
##
#O  SubRepresentation( <M>, <gen> )
##
##  This function returns a module isomorphic to the submodule of  <M>  
##  generated by the elements  <gen>  to the module  <M>. The function
##  checks if all the elements on the list  <gen>  are elements of  the
##  module  <M>. 
##
InstallMethod( SubRepresentation,
    "for a path algebra module and list of its elements",
    true,
    [ IsPathAlgebraMatModule, IsList], 0,
    function( M, gen );

    return Source(SubRepresentationInclusion(M,gen));
end
);

#######################################################################
##
#O  RadicalOfModuleInclusion( <M> )
##
##  This function returns the inclusion from the radical of  <M>  
##  to the module  <M>. 
##
InstallMethod( RadicalOfModuleInclusion,
    "for a path algebra module",
    true,
    [ IsPathAlgebraMatModule ], 0,
    function( M )

    local A, q, num_vert, arrows_as_path, basis_M, generators, a, b, run_time; 
    
    #
    # Checking if the algebra  <A>  is finite dimensional.  If it is and is 
    # a path algebra, then the radical is the ideal generated by the arrows.  
    # If it is not a path algebra but an admissible quotient of a path algebra,
    # the radical is the ideal generated by the arrows, and this function 
    # applies. 
    #
    A := RightActingAlgebra(M);
    q := QuiverOfPathAlgebra(A);
    if not IsFiniteDimensional(A) then
        TryNextMethod();
    fi; 
    if not IsPathAlgebra(A) and not IsAdmissibleQuotientOfPathAlgebra(A) then
        TryNextMethod();
    fi;

    num_vert := Length(VerticesOfQuiver(q));
#
# Note arrows_as_path will change if A is a quotient of a path algebra !!!!
#
    arrows_as_path := List(ArrowsOfQuiver(q), x -> x*One(A));
    basis_M := Basis(M);
    generators := [];
    for a in arrows_as_path do
        for b in basis_M do 
            if b^a <> Zero(M) then 
                Add(generators,b^a);
            fi;
        od;
    od;
    
    generators := Unique(generators);
    return SubRepresentationInclusion(M,generators);
end
);

#######################################################################
##
#O  RadicalOfModule( <M> )
##
##  This function returns a module isomorphic to the radical of  <M>. 
##
InstallMethod( RadicalOfModule,
    "for a path algebra module",
    true,
    [ IsPathAlgebraMatModule ], 0,
    function( M )

    return Source(RadicalOfModuleInclusion(M));
end
);

#######################################################################
##
#M  IsInjective( <f> )
##
##  This function returns a module isomorphic to the radical of  <M>. 
##
InstallOtherMethod ( IsInjective, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f )
    
    local M, K, V_list, dim_K, dim_M, i, VS_list;

    M := Source(f);
    K := LeftActingDomain(M);
    V_list := [];
    dim_K := 0;
    dim_M := DimensionVector(M);
#
# Computing the kernel of each f_i and making a vector space of Ker f_i with 
# basis given by the vectors supplied by NullspaceMat(f!.maps[i]).
#
    for i in [1..Length(dim_M)] do
        if dim_M[i] <> 0 then 
            dim_K := dim_K + Length(NullspaceMat(f!.maps[i]));
        fi;
    od;
    if dim_K = 0 then
        SetIsInjective(f,true);
        return true;
    else
        SetIsInjective(f,false);
        return false;
    fi;
end
);

#######################################################################
##
#O  KernelInclusion( <f> )
##
##  This function returns the inclusion from a module isomorphic to the 
##  kernel of  <f>  to the module  <M>. 
##
InstallMethod ( KernelInclusion, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f )
    
    local M, dim_M, V_list, V_dim, i, dim_K, VS_list, A, K, vertices, 
            arrows, mats, kermats, a, apos, j, matrix, k, Kerf, kermap;

    M := Source(f);
    K := LeftActingDomain(M);
    V_list := [];
    dim_K  := [];
    dim_M := DimensionVector(M);
    VS_list := [];
#
# Computing the kernel of each f_i and making a vector space of Ker f_i with 
# basis given by the vectors supplied by NullspaceMat(f!.maps[i]).
#
    for i in [1..Length(dim_M)] do
        if dim_M[i] <> 0 then
            Add(V_list,NullspaceMat(f!.maps[i]));
            Add(dim_K,Length(V_list[i]));
            if Length(V_list[i]) > 0 then 
                Add(VS_list,VectorSpace(K,V_list[i],"basis"));
            else
                Add(VS_list,TrivialSubmodule(VectorSpace(K,[[One(K)]])));
            fi;
        else
            Add(V_list,[]);
            Add(dim_K,0);
            Add(VS_list,TrivialSubmodule(VectorSpace(K,[[One(K)]])));
        fi;
    od;
    V_list := List(VS_list, V -> Basis(V));
    V_dim := Sum(dim_K);
    A := RightActingAlgebra(M);
    if V_dim = 0 then 
        SetIsInjective(f,true);
        kermap := ZeroMapping(ZeroModule(A),Source(f)); 
    else 
        vertices := VerticesOfQuiver(QuiverOfPathAlgebra(A));
        arrows := ArrowsOfQuiver(QuiverOfPathAlgebra(A));
        mats := MatricesOfPathAlgebraModule(M);
        kermats := [];
#
# The matrices f_alpha of the representation M is used to compute
# the induced action on the basis of Ker f_i.
#
        for a in arrows do
            i := Position(vertices,SourceOfPath(a));
            j := Position(vertices,TargetOfPath(a));
            if dim_K[i] <> 0 and dim_K[j] <> 0 then
                apos := Position(arrows,a);
                matrix := [];
                for k in [1..Length(V_list[i])] do
                    Add(matrix,Coefficients(V_list[j],V_list[i][k]*mats[apos]));
                od;
                Add(kermats,[String(a),matrix]);
            fi;
        od;
#
# Extracting the basis vectors of each Ker f_i, as a subspace of M_i,
# which give the matrices of the inclusion of Ker f  into M.
#
        for i in [1..Length(dim_M)] do
            if Dimension(VS_list[i]) = 0 then
                V_list[i] := []; 
                if dim_M[i] = 0 then 
                    Add(V_list[i],Zero(K));
                else 
                    for j in [1..dim_M[i]] do
                        Add(V_list[i],Zero(K));
                    od;
                fi;
                V_list[i] := [V_list[i]];
            else 
                V_list[i] := BasisVectors(V_list[i]);
            fi;
        od;
        if IsPathAlgebra(A) then 
            Kerf := RightModuleOverPathAlgebra(A, dim_K, kermats);
        else 
            Kerf := RightModuleOverPathAlgebra(A, dim_K, kermats);
        fi;
        kermap := RightModuleHomOverAlgebra(Kerf,M,V_list);
    fi;  
    SetKernelOfWhat(kermap,f);
    SetIsInjective(kermap,true);
    return kermap;
end
);

#######################################################################
##
#M  Kernel( <f> )
##
##  This function returns a module isomorphic to the kernel of  <f>.
##
InstallOtherMethod ( Kernel, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f )

    return Source(KernelInclusion(f));
end
);

#######################################################################
##
#O  ImageProjectionInclusion( <f> )
##
##  This function returns a projection from the source of  <f>  to a 
##  module isomorphic to the image of  <f>  and an inclusion from a 
##  module isomorphic to the image of  <f>  to the module  <M>. 
##
InstallMethod ( ImageProjectionInclusion, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f )
    
    local M, N, image, images, A, K, num_vert, vertices, arrows, gen_list, B, i,fam, n, s, v,
          pos, dim_M, dim_N, V, W, projection, dim_image, basis_image, basis_M, basis_N, a, b, image_mat, 
          mat, mats, source_a, target_a, pos_a, bb, image_f, C, map, partmap,
          inclusion, image_inclusion, image_projection, dimvecimage_f;

    M := Source( f );
    N := Range( f );
    A := RightActingAlgebra( M );
    K := LeftActingDomain( M ); 
    num_vert := Length( VerticesOfQuiver( QuiverOfPathAlgebra( A ) ) );
#
    vertices := List( VerticesOfQuiver( QuiverOfPathAlgebra( A ) ), x -> x * One( A ) );
#
# Finding a basis for the vector space in each vertex for the image
#
    image := ImagesSet( f, Source( f ) );
    gen_list := [ ];
    for i in [ 1..Length( vertices ) ] do
        Add( gen_list,[ ] );
    od;
    if Length( image ) > 0 then 
        for n in image do
            for v in vertices do
                if n^v <> Zero( N ) then
                    pos := Position( vertices, v );
                    Add( gen_list[ pos ], ExtRepOfObj( n )![ 1 ][ pos ] );
                fi;
            od;
        od;
        dim_N := DimensionVector( N );
        V := [];    
        W := [];
        basis_image := [];   
        basis_N := [];   
        for i in [ 1..Length( vertices ) ] do
            V[ i ] := K^dim_N[ i ];
            basis_N[ i ] := CanonicalBasis( V[ i ] );
            W[ i ] := Subspace( V[ i ], gen_list[ i ] );
            Add( basis_image, CanonicalBasis( W[ i ] ) );
        od;
#
# Finding the matrices of the representation image
#
        arrows := ArrowsOfQuiver( QuiverOfPathAlgebra( A ) );
        mats := MatricesOfPathAlgebraModule( N );
        image_mat := [ ];
        for a in arrows do 
            mat := [ ];
            pos_a := Position( arrows, a );
            source_a := Position( vertices, SourceOfPath( a ) * One( A ) );
            target_a := Position( vertices, TargetOfPath( a ) * One( A ) );
            if ( Length( basis_image[ source_a ]) <> 0 ) and ( Length( basis_image[ target_a ] ) <> 0 ) then 
         for b in basis_image[ source_a ] do
                    Add( mat, Coefficients( basis_image[ target_a ], b * mats[ pos_a ] ) );
                od;
                Add( image_mat, [ String( a ), mat ] );
            fi;
        od;

 dimvecimage_f := List( W, Dimension );
 image_f := RightModuleOverPathAlgebra( A, dimvecimage_f, image_mat );
#
# Finding inclusion map from the image to Range(f)
#     
        inclusion := [ ];
        for i in [ 1..num_vert ] do 
            mat := [ ];
            if Length( basis_image[ i ] ) = 0 then 
                if dim_N[ i ] = 0 then 
                    Add( inclusion, NullMat( 1, 1, K ) );
                else
                    Add( inclusion, NullMat( 1, dim_N[ i ], K ) );
                fi;
            else
                mat := [ ];
                for b in basis_image[ i ] do 
                    Add( mat, b );
                od;
                Add( inclusion, mat );
            fi;
        od; 
        image_inclusion := RightModuleHomOverAlgebra( image_f, Range( f ), inclusion );
        SetImageOfWhat( image_inclusion, f );
        SetIsInjective( image_inclusion, true );
#
# Finding the projection for Source(f) to the image
#
        dim_M := DimensionVector(M);
        basis_M := [];
        for i in [1..num_vert] do
            Add(basis_M,CanonicalBasis(K^dim_M[i]));
        od;
        projection := [];
        for i in [1..num_vert] do
            mat := [];
            if Length(basis_image[i]) = 0 then
                if dim_M[i] = 0 then  
                    mat := NullMat(1,1,K);
                else
                    mat := NullMat(dim_M[i],1,K);
                fi;
                Add(projection,mat);
            else 
                for b in basis_M[i] do
                    Add(mat,Coefficients(basis_image[i],b*f!.maps[i]));
                od;
                Add(projection,mat);
            fi;
        od;
        image_projection := RightModuleHomOverAlgebra(Source(f),image_f,projection);
        SetImageOfWhat(image_projection,f);
        SetIsSurjective(image_projection,true);
        
        return [image_projection,image_inclusion];
    else
        return [ZeroMapping(M,ZeroModule(A)),ZeroMapping(ZeroModule(A),N)];
    fi;
end
);

#######################################################################
##
#O  ImageProjection( <f> )
##
##  This function returns a projection from the source of  <f>  to a 
##  module isomorphic to the image of  <f>. 
##
InstallMethod ( ImageProjection, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f );

    return ImageProjectionInclusion(f)[1];
end
);

#######################################################################
##
#O  ImageInclusion( <f> )
##
##  This function returns an inclusion from a module isomorphic to the 
##  image of  <f>  to the module  <M>. 
##
InstallMethod ( ImageInclusion, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f );

    return ImageProjectionInclusion(f)[2];
end
);

#######################################################################
##
#M  ImagesSource( <f> )
##
##  This function returns a module isomorphic to the image of  <f>. 
##  TODO: Should this delegate to ImagesSet as for the general GAP
##  command?
##
InstallMethod ( ImagesSource, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f );

    return Range(ImageProjectionInclusion(f)[1]);
end
);

#######################################################################
##
#M  IsZero( <f> )
##
##  This function returns true if all the matrices of the homomorphism
##  <f>  are identically zero. 
##
InstallMethod ( IsZero, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f );

    return ForAll(f!.maps, IsZero);
end
);

#######################################################################
##
#M  IsSurjective( <f> )
##
##  This function returns true if the homomorphism  <f>  is surjective. 
##
InstallOtherMethod ( IsSurjective, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f )
    
    local image, dim_image, K, V;

    image := ImagesSet(f,Source(f));
    if Length(image) = 0 then 
        dim_image := 0;
    else
        image := List(image, x -> Flat(ExtRepOfObj(x)![1])); 
        K := LeftActingDomain(Source(f));
        V := K^Length(image[1]);
        dim_image :=  Dimension(Subspace(V,image));
    fi;
    if dim_image = Dimension(Range(f)) then 
        SetIsSurjective(f,true);
        return true;
    else
        SetIsSurjective(f,false);
        return false;
    fi;
end
);

#######################################################################
##
#M  IsIsomorphism( <f> )
##
##  This function returns true if the homomorphism  <f>  is an 
##  isomorphism. 
##
InstallMethod ( IsIsomorphism, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f );

    return IsInjective(f) and IsSurjective(f);
end
);

#######################################################################
##
#O  CoKernelProjection( <f> )
##
##  This function returns a projection from the range of  <f>  to a 
##  module isomorphic to the cokernel of  <f>. 
##
InstallMethod ( CoKernelProjection, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f )
    
    local M, N, image, A, K, num_vert, vertices, arrows, basis_list,i, n, v,
          pos, dim_N, V, W, projection, coker, basis_coker, basis_N, a, b,
          mat, mats, source_a, target_a, pos_a, bb, cokermat, C, map, partmap,
          morph, dimvec_coker;

    M := Source(f);
    N := Range(f);
    A := RightActingAlgebra(M);
    K := LeftActingDomain(M); 
    num_vert := Length(VerticesOfQuiver(QuiverOfPathAlgebra(A)));
#
    vertices := List(VerticesOfQuiver(QuiverOfPathAlgebra(A)), x -> x*One(A));
#
# Finding a basis for the vector space in each vertex for the cokernel
#
    image := ImagesSet(f,Source(f));
    basis_list := [];
    for i in [1..Length(vertices)] do
        Add(basis_list,[]);
    od;
    for n in image do
        for v in vertices do
            if n^v <> Zero(N) then
                pos := Position(vertices,v);
                Add(basis_list[pos],ExtRepOfObj(n)![1][pos]);
            fi;
        od;
    od;
    dim_N := DimensionVector(N);
    V := [];    
    W := [];
    projection := [];
    basis_coker := [];   
    basis_N := [];   
    coker := [];
    for i in [1..Length(vertices)] do
        V[i] := K^dim_N[i];
        basis_N[i] := CanonicalBasis(V[i]);
        W[i] := Subspace(V[i],basis_list[i]);
        projection[i] := NaturalHomomorphismBySubspace(V[i],W[i]);
        Add(basis_coker,Basis(Range(projection[i])));
        coker[i] := Range(projection[i]);
    od;
#
# Finding the matrices of the representation of the cokernel 
#
    mats := MatricesOfPathAlgebraModule(N);
    arrows := ArrowsOfQuiver(QuiverOfPathAlgebra(A));
    cokermat := [];
    for a in arrows do
        source_a := Position(vertices,SourceOfPath(a)*One(A));
        target_a := Position(vertices,TargetOfPath(a)*One(A));
        if Length(basis_coker[source_a]) <> 0 and Length(basis_coker[target_a]) <> 0 then
            mat := [];
            pos_a := Position(arrows,a);
            for b in basis_coker[source_a] do
                bb := PreImagesRepresentative(projection[source_a],b);
                bb := bb*mats[pos_a]; # computing bb^a
                Add(mat,Coefficients(basis_coker[target_a],Image(projection[target_a],bb)));
            od;
            Add(cokermat,[String(a),mat]);
        fi;
    od;
    
    dimvec_coker := List(basis_coker, basis -> Length(basis));
    
    if IsPathAlgebra(A) then
        C := RightModuleOverPathAlgebra(A, dimvec_coker, cokermat);
    else
        C := RightModuleOverPathAlgebra(A, dimvec_coker, cokermat);
    fi;
#
# Finding the map for Range(f) to the cokernel 
#
    map := [];
    for i in [1..Length(vertices)] do
        partmap := [];
        if dim_N[i] = 0 then
            partmap := NullMat(1,1,K);
        elif Length(basis_coker[i]) = 0 then 
            partmap := NullMat(dim_N[i],1,K);
        else 
            for b in basis_N[i] do 
                Add(partmap,Coefficients(basis_coker[i],Image(projection[i],b)));
            od;
        fi;
        Add(map,partmap);
    od;
    
    morph := RightModuleHomOverAlgebra(Range(f),C,map);
    SetCoKernelOfWhat(morph,f);
    SetIsSurjective(morph,true);
    
    return morph;
end
);

#######################################################################
##
#O  CoKernelOfAdditiveGeneralMapping( <f> )
##
##  This function returns a module isomorphic to the cokernel of  <f>. 
##
InstallMethod ( CoKernelOfAdditiveGeneralMapping, 
    "for a PathAlgebraMatModuleMap",
    true,
    [ IsPathAlgebraMatModuleHomomorphism ],
    SUM_FLAGS+1,
    function( f )

    return Range(CoKernelProjection(f));
end
);

#######################################################################
##
#A  TopOfModuleProjection( <M> )
##
##  This function computes the map from  M  to the top of  M, 
##  M ---> M/rad(M).
##
InstallMethod( TopOfModuleProjection, 
    "for a pathalgebramatmodule",
    true, 
    [ IsPathAlgebraMatModule ], 0,
    function( M ) 

    local K, A, Q, vertices, num_vert, incomingarrows, mats, arrows, subspaces,
          i, a, dim_M, Vspaces, Wspaces, naturalprojections, index,
          dim_top, matrices, topofmodule, topofmoduleprojection, W;

    A := RightActingAlgebra(M);
    if Dimension(M) = 0 then 
        return ZeroMapping(M,M);
    else
        K := LeftActingDomain(A);
        Q := QuiverOfPathAlgebra(A);
        vertices := VerticesOfQuiver(Q);
        num_vert := Length(vertices);
        incomingarrows := List([1..num_vert], x -> IncomingArrowsOfVertex(vertices[x]));
        mats := MatricesOfPathAlgebraModule(M);
        arrows := ArrowsOfQuiver(Q);
        subspaces := List([1..num_vert], x -> []);
        for i in [1..num_vert] do
            for a in incomingarrows[i] do
                Append(subspaces[i], StructuralCopy(mats[Position(arrows,a)]));
            od;
        od;
        dim_M := DimensionVector(M);
        Vspaces := List([1..num_vert], x -> FullRowSpace(K,dim_M[x]));
        Wspaces := List([1..num_vert], x -> []);
        for i in [1..num_vert] do
            if dim_M[i] <> 0 then 
                Wspaces[i] := Subspace(Vspaces[i],subspaces[i]);
            else
                Wspaces[i] := Subspace(Vspaces[i],[]);
            fi;
        od;
        naturalprojections := List([1..num_vert], x -> NaturalHomomorphismBySubspace(Vspaces[x],Wspaces[x]));
        dim_top := List([1..num_vert], x -> Dimension(Range(naturalprojections[x]))); 
        index := function( n )
            if n = 0 then 
                return 1;
            else
                return n;
            fi;
        end;
        matrices := [];
        for i in [1..num_vert] do
            if dim_top[i] <> 0 then
                Add(matrices, List(BasisVectors(Basis(Vspaces[i])), y -> ImageElm(naturalprojections[i],y)));
            else
                Add(matrices, NullMat(index(dim_M[i]),1,K));
            fi;
        od;
        topofmodule := RightModuleOverPathAlgebra(A,dim_top,[]);
        topofmoduleprojection := RightModuleHomOverAlgebra(M,topofmodule,matrices);

        SetTopOfModule(M,topofmodule);

        return topofmoduleprojection;
    fi;
end
);

#######################################################################
##
#A  TopOfModule( <M> )
##
##  This function computes the top  M/rad(M)  of the module M. 
##
InstallMethod( TopOfModule, 
    "for a pathalgebramatmodule",
    true, 
    [ IsPathAlgebraMatModule ], 0,
    function( M )

    return Range(TopOfModuleProjection(M));
end
);

InstallOtherMethod ( TopOfModule, 
"for a PathAlgebraMatModuleMap",
[ IsPathAlgebraMatModuleHomomorphism ],
function( f )
    
  local M, N, K, pi_M, pi_N, BTopM, dim_vector_TopM, dim_vector_TopN, 
        n, h, i, dim, matrix, j, b, btilde, bprime;
  
  M := Source( f );
  N := Range( f );
  K := LeftActingDomain( M );
  pi_M := TopOfModuleProjection( M );
  pi_N := TopOfModuleProjection( N );
  BTopM := BasisVectors( Basis( Range( pi_M ) ) );
  dim_vector_TopM := DimensionVector( Range( pi_M ) );
  dim_vector_TopN := DimensionVector( Range( pi_N ) );    
  n := Length( dim_vector_TopM ); 
  h := [ ];
  for i in [ 1..n ] do
    if dim_vector_TopM[ i ] > 0 then
      if dim_vector_TopN[ i ] = 0 then
        Add( h, NullMat( dim_vector_TopM[ i ], 1, K ) );
      else
#
# Assuming that the basisvectors of topM are listed as 
# first basisvectors for vertex 1, vertex 2, .....
#
        dim := Sum( dim_vector_TopM{ [ 1..i - 1 ] } );
        matrix := [ ];
        for j in [ 1..dim_vector_TopM[ i ] ] do
          b := BTopM[ dim + j ];
          btilde := PreImagesRepresentative( pi_M, b );
          bprime := ImageElm( pi_N, ImageElm( f, btilde ) );
          Add( matrix, ExtRepOfObj( ExtRepOfObj( bprime ) )[ i ] ); 
        od;
        Add( h, matrix );
      fi;
    else
      if dim_vector_TopN[ i ] = 0 then
        Add( h, NullMat( 1, 1, K ) );
      else
        Add( h, NullMat( 1, dim_vector_TopN[ i ], K ) );
      fi;
    fi;        
  od;
  
  return RightModuleHomOverAlgebra( Range( pi_M ), Range( pi_N ), h );
end
  );

#######################################################################
##
#M  \+( <f>, <g> )
##
##  This function returns the sum of two homomorphisms  <f>  and  <g>,
##  when the sum is defined, otherwise it returns an error message. 
##
InstallMethod( \+,
    "for two PathAlgebraMatModuleMap's",
    true,
#  IsIdenticalObj,
    [ IsPathAlgebraMatModuleHomomorphism, IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f, g )
    
    local i, num_vert, x, Fam;

    if ( Source(f) = Source(g) ) and ( Range(f) = Range(g) ) then 
      num_vert := Length(f!.maps);
        x := List([1..num_vert], y -> f!.maps[y] + g!.maps[y]);
        return RightModuleHomOverAlgebra(Source(f),Range(f),x);
    else
 Error("the two arguments entered do not live in the same homomorphism set, ");
    fi;
end
);
  
#######################################################################
##
#M  \*( <f>, <g> )
##
##  This function returns the composition  <f*g>  of two homomorphisms  
##  <f>  and  <g>, that is, first the map  <f> then followed by  <g>,  
##  when the composition is defined, otherwise it returns an error 
##  message. 
##
InstallMethod( \*,
    "for two PathAlgebraMatModuleMap's",
    true,
    [ IsPathAlgebraMatModuleHomomorphism, IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( f, g )
    
    local i, num_vert, x;

    if Range(f) = Source(g) then 
      num_vert := Length(f!.maps);
        x := List([1..num_vert], y -> f!.maps[y]*g!.maps[y]);
 return RightModuleHomOverAlgebra(Source(f),Range(g),x);
    else
        Error("codomain of the first argument is not equal to the domain of the second argument, ");
    fi;
end
);
  
#######################################################################
##
#M  \*( <a>, <g> )
##
##  This function returns the scalar multiple  <a*g>  of a scalar  <a> 
##  with a homomorphism <g>, when this scalar multiplication is defined, 
##  otherwise it returns an error message. 
##
InstallOtherMethod( \*,
    "for two PathAlgebraMatModuleMap's",
    true,
    [ IsScalar, IsPathAlgebraMatModuleHomomorphism ],
    0,
    function( a, g )
    
    local K, i, num_vert, x;

    K := LeftActingDomain(Source(g));
    if a in K then 
      num_vert := Length(g!.maps);
        x := List([1..num_vert], y -> a*g!.maps[y]);
        return RightModuleHomOverAlgebra(Source(g),Range(g),x);
     else
         Error("the scalar is not in the same field as the algbra is over,");
     fi;
end
);
  
#######################################################################
##
#M  AdditiveInverseOp( <f> )
##
##  This function returns the additive inverse of the homomorphism 
##  <f>. 
##
InstallMethod( AdditiveInverseOp,
    "for a morphism in IsPathAlgebraMatModuleHomomorphism",
    [ IsPathAlgebraMatModuleHomomorphism ],

    function ( f ) 

    local i, num_vert, x;

    num_vert := Length(f!.maps);
    x := List([1..num_vert], y -> (-1)*f!.maps[y]);

    return RightModuleHomOverAlgebra(Source(f),Range(f),x);
end
);

#######################################################################
##
#M  \*( <f>, <a> )
##
##  This function returns the scalar multiple  <f*a>  of a homomorphism
##  <f>  and a scalar  <a>. 
##
InstallOtherMethod( \*,
    "for two PathAlgebraMatModuleMap's",
    true,
    [ IsPathAlgebraMatModuleHomomorphism, IsScalar ],
    0,
    function( f, a )
    
    local K, i, num_vert, x;

    K := LeftActingDomain(Source(f));
    if a in K then 
      num_vert := Length(f!.maps);
        x := List([1..num_vert], y -> f!.maps[y]*a);
 return RightModuleHomOverAlgebra(Source(f),Range(f),x);
    else
  Error("the scalar is not in the same field as the algbra is over,");
    fi;
end
);
  
#######################################################################
##
#O  HomOverAlgebra( <M>, <N> )
##
##  This function computes a basis of the vector space of homomorphisms
##  from the module  <M>  to the module  <N>. The algorithm it uses is
##  based purely on linear algebra.
##
InstallMethod( HomOverAlgebra,
    "for two representations of a quiver",
    [ IsPathAlgebraMatModule, IsPathAlgebraMatModule ], 0,
    function( M, N )

    local A, F, dim_M, dim_N, num_vert, support_M, support_N, num_rows, num_cols, 
          block_rows, block_cols, block_intervals, 
          i, j, equations, arrows, vertices, v, a, source_arrow, target_arrow, 
          mats_M, mats_N, prev_col, prev_row, row_start_pos, col_start_pos, 
          row_end_pos, col_end_pos, l, m, n, hom_basis, map, mat, homs, x, y, k, b, 
          dim_hom, zero;

    A := RightActingAlgebra(M); 
    if A <> RightActingAlgebra(N) then
        Print("The two modules entered are not modules over the same algebra.");
        return fail;
    fi;
    F := LeftActingDomain(A);
    #
    # Finding the support of M and N
    # 
    vertices := VerticesOfQuiver(QuiverOfPathAlgebra(OriginalPathAlgebra(A)));
    dim_M := DimensionVector(M);
    dim_N := DimensionVector(N);
    num_vert := Length(dim_M);   
    support_M := [];
    support_N := [];
    for i in [1..num_vert] do
        if (dim_M[i] <> 0) then 
            AddSet(support_M,i);
        fi;
        if (dim_N[i] <> 0) then 
            AddSet(support_N,i);
        fi;
    od;
    #
    # Deciding the size of the equations, 
    # number of columns and rows
    #
    num_cols := 0;
    num_rows := 0;
    block_intervals := [];
    block_rows := [];
    block_cols := [];
    prev_col := 0;
    prev_row := 0;
    for i in support_M do
        num_rows := num_rows + dim_M[i]*dim_N[i];
        block_rows[i] := prev_row+1;
        prev_row := num_rows;
        for a in OutgoingArrowsOfVertex(vertices[i]) do
            source_arrow := Position(vertices,SourceOfPath(a));
            target_arrow := Position(vertices,TargetOfPath(a));
            if (target_arrow in support_N) and ( (source_arrow in support_N) or (target_arrow in support_M)) then 
                num_cols := num_cols + dim_M[source_arrow]*dim_N[target_arrow];
                Add(block_cols,[a,prev_col+1,num_cols]);
            fi;
            prev_col := num_cols; 
        od;
    od;
    #
    # Finding the linear equations for the maps between M and N
    #
    equations := NullMat(num_rows, num_cols, F);

    arrows := ArrowsOfQuiver(QuiverOfPathAlgebra(OriginalPathAlgebra(A)));
    mats_M := MatricesOfPathAlgebraModule(M);
    mats_N := MatricesOfPathAlgebraModule(N);
    prev_col := 0;
    prev_row := 0;
    for i in support_M do
        for a in OutgoingArrowsOfVertex(vertices[i]) do
            source_arrow := Position(vertices,SourceOfPath(a));
            target_arrow := Position(vertices,TargetOfPath(a));
            if (target_arrow in support_N) and ( (source_arrow in support_N) or (target_arrow in support_M)) then
                for j in [1..dim_M[source_arrow]] do
                    row_start_pos := block_rows[source_arrow] + (j-1)*dim_N[source_arrow]; 
                    row_end_pos := block_rows[source_arrow] - 1 + j*dim_N[source_arrow];
                    col_start_pos := prev_col + 1 + (j-1)*dim_N[target_arrow];
                    col_end_pos := prev_col + j*dim_N[target_arrow];
                    if (source_arrow in support_N) then 
                        equations{[row_start_pos..row_end_pos]}{[col_start_pos..col_end_pos]} := mats_N[Position(arrows,a)];
                    fi;
                    if (target_arrow in support_M) then 
                        for m in [1..DimensionsMat(mats_M[Position(arrows,a)])[2]] do
                            for n in [1..dim_N[target_arrow]] do
                                b := block_rows[target_arrow]+(m-1)*dim_N[target_arrow];
                                equations[b+n-1][col_start_pos+n-1] := equations[b+n-1][col_start_pos+n-1]+(-1)*mats_M[Position(arrows,a)][j][m];
                            od;
                        od;
                    fi;
                od;
                prev_col := prev_col + dim_M[source_arrow]*dim_N[target_arrow];
            fi;
        od;
    od;
    #
    # Creating the maps between the module M and N
    #
    homs := [];
    if (num_rows <> 0) and (num_cols <> 0) then 
        dim_hom := 0; 
        hom_basis := NullspaceMat(equations);
        for b in hom_basis do
            map := [];
            dim_hom := dim_hom + 1;
            k := 1;
            for i in [1..num_vert] do 
                if dim_M[i] = 0 then 
                    if dim_N[i] = 0 then 
                        Add(map,NullMat(1,1,F));
                    else
                        Add(map,NullMat(1,dim_N[i],F));
                    fi;
                else
                    if dim_N[i] = 0 then 
                        Add(map,NullMat(dim_M[i],1,F));
                    else
                        mat := NullMat(dim_M[i],dim_N[i], F);
                        for y in [1..dim_M[i]] do 
                            for x in [1..dim_N[i]] do 
                                mat[y][x] := b[k];
                                k := k + 1;
                            od;
                        od;
                        Add(map,mat);
                    fi;
                fi;
            od;
            homs[dim_hom] := Objectify( NewType( CollectionsFamily( GeneralMappingsFamily(
                                     ElementsFamily( FamilyObj( M ) ),
                                     ElementsFamily( FamilyObj( N ) ) ) ), 
                                     IsPathAlgebraMatModuleHomomorphism and IsPathAlgebraMatModuleHomomorphismRep and IsAttributeStoringRep ), rec( maps := map ));
            SetPathAlgebraOfMatModuleMap(homs[dim_hom], A);
            SetSource(homs[dim_hom], M);
            SetRange(homs[dim_hom], N);
            SetIsWholeFamily(homs[dim_hom],true);
        od;
        return homs;
    else
        homs := [];
        if Dimension(M) = 0 or Dimension(N) = 0 then 
            return homs;
        else 
            dim_hom := 0;
            zero := [];
            for i in [1..num_vert] do
                if dim_M[i] = 0 then 
                    if dim_N[i] = 0 then 
                        Add(zero,NullMat(1,1,F));
                    else
                        Add(zero,NullMat(1,dim_N[i],F));
                    fi;
                else
                    if dim_N[i] = 0 then 
                        Add(zero,NullMat(dim_M[i],1,F));
                    else
                        Add(zero,NullMat(dim_M[i],dim_N[i],F));
                    fi;
                fi;
            od;      
            for i in [1..num_vert] do
                if (dim_M[i] <> 0) and (dim_N[i] <> 0) then 
                    for m in BasisVectors(Basis(FullMatrixSpace(F,dim_M[i],dim_N[i]))) do
                        dim_hom := dim_hom + 1;
                        homs[dim_hom] := ShallowCopy(zero);
                        homs[dim_hom][i] := m;
                    od;
                fi;
            od;
            for i in [1..dim_hom] do 
                homs[i] := Objectify( NewType( CollectionsFamily( GeneralMappingsFamily(
                                   ElementsFamily( FamilyObj( M ) ),
                                   ElementsFamily( FamilyObj( N ) ) ) ), 
                                   IsPathAlgebraMatModuleHomomorphism and IsPathAlgebraMatModuleHomomorphismRep and IsAttributeStoringRep ), rec( maps := homs[i] ));
                SetPathAlgebraOfMatModuleMap(homs[i], A);
                SetSource(homs[i], M);
                SetRange(homs[i], N);
                SetIsWholeFamily(homs[i],true);
            od;

            return homs;
        fi;
    fi;
end
);

#######################################################################
##
#O  HomOverAlgebraWithBasisFunction( <M>, <N> )
##
##  This function returns a list with two entries. The first entry is 
##  a basis of the vector space of homomorphisms from the module  <M>
##  to the module  <N>.  The second entry is a function from the space 
##  of homomorphisms from  <M>  to  <N>  to the vector space with the 
##  given by the first entry.  The algorithm it uses is based purely 
##  on linear algebra.
##
InstallMethod( HomOverAlgebraWithBasisFunction,
    "for two representations of a quiver",
    [ IsPathAlgebraMatModule, IsPathAlgebraMatModule ], 0,
    function( M, N )

    local homs, F, basis, V, W, HomB, transfermat, coefficients;


    homs := HomOverAlgebra( M, N );
    F := LeftActingDomain( RightActingAlgebra( M ) );
    
    if Length( homs ) > 0 then
      basis := List( homs, h -> Flat( h!.maps ) );
      V := FullRowSpace( F, Length( basis[ 1 ] ) );
      W := Subspace( V, basis, "basis" );
      HomB := Basis( W );
      transfermat := List( basis, b -> Coefficients( HomB, b ) );
      coefficients := function( h )
        local hflat, coeff;
               
        hflat := Flat( h!.maps );
        coeff := Coefficients( HomB, hflat );
        
        return coeff * transfermat^(-1);
      end;
    else
      coefficients := function( h );
        return [ Zero( F ) ];
      end;
    fi;
    
    return [ homs, coefficients ];
end
);

#######################################################################
##
#A  EndOverAlgebra( <M>, <N> )
##
##  This function computes endomorphism ring of the module  <M>  and
##  representing it as an general GAP algebra. The algorithm it uses is
##  based purely on linear algebra.
##
InstallMethod( EndOverAlgebra,
    "for a representations of a quiver",
    [ IsPathAlgebraMatModule ], 0,
    function( M )

    local EndM, R, F, dim_M, alglist, i, j, r, maps, A; 

    EndM := HomOverAlgebra(M,M);
    R := RightActingAlgebra(M); 
    F := LeftActingDomain(R);
    dim_M := DimensionVector(M);
    alglist := [];
    for i in [1..Length(dim_M)] do 
        if dim_M[i] <> 0 then 
            Add(alglist, MatrixAlgebra(F,dim_M[i]));
        fi;
    od;
    maps := [];
    for i in [1..Length(EndM)] do
        maps[i] := NullMat(Dimension(M),Dimension(M),F);
        r := 1; 
        for j in [1..Length(dim_M)] do 
            if dim_M[j] <> 0 then 
                maps[i]{[r..r+dim_M[j]-1]}{[r..r+dim_M[j]-1]} := EndM[i]!.maps[j];
            fi;
            r := r + dim_M[j];
        od; 
    od;
    A := DirectSumOfAlgebras(alglist); 
    
    return SubalgebraWithOne(A,maps,"basis"); 
end
);

#######################################################################
##
#A  RightFacApproximation( <M>, <C> )
##
##  This function computes a right Fac<M>-approximation of the module 
##  <C>. 
##
InstallMethod( RightFacApproximation,
    "for a representations of a quiver",
    [ IsPathAlgebraMatModule, IsPathAlgebraMatModule ], 0,
    function( M, C )

    local homMC, i, generators; 

    homMC := HomOverAlgebra(M,C); 
    generators := [];
    for i in [1..Length(homMC)] do
        Append(generators,ImagesSet(homMC[i],Source(homMC[i])));
    od;
    
    return SubRepresentationInclusion(C,generators);
end
);

#######################################################################
##
#O  NumberOfNonIsoDirSummands( <M> )
##
##  This function computes the number of non-isomorphic indecomposable 
##  direct summands of the module  <M>, and in addition returns the 
##  dimensions of the simple blocks of the semisimple ring  
##  End(M)/rad End(M). 
##
InstallMethod( NumberOfNonIsoDirSummands,
    "for a representations of a quiver",
    [ IsPathAlgebraMatModule ], 0,
    function( M )
 
    local EndM, K, J, gens, I, A, top, AA, B, n,
          i, j, genA, V, W, d;

    EndM := EndOverAlgebra(M);
    K := LeftActingDomain(M);
    J := RadicalOfAlgebra(EndM);
    gens := GeneratorsOfAlgebra(J);
    I := Ideal(EndM,gens); 
    A := EndM/I;
    top := CentralIdempotentsOfAlgebra(A);
    
    return [Length(top),List(DirectSumDecomposition(EndM/I),Dimension)];
end
);

#######################################################################
##
#A  DualOfModuleHomomorphism( <f> )
##
##  This function computes the dual of a homomorphism from the module  
##  <M>  to the module  <N>.
##
InstallMethod ( DualOfModuleHomomorphism,
    "for a map between representations of a quiver",
    [ IsPathAlgebraMatModuleHomomorphism ], 0,
    function( f )

    local mats, M, N;
   
    mats := f!.maps;
    mats := List(mats, x -> TransposedMat(x));
    M := DualOfModule(Source(f));
    N := DualOfModule(Range(f));

    return RightModuleHomOverAlgebra(N,M,mats);
end
);

#######################################################################
##
#A  SocleOfModuleInclusion( <M> )
##
##  This function computes the map from the socle of  M  to the module M, 
##  soc(M) ---> M.
##
InstallMethod( SocleOfModuleInclusion, 
    "for a pathalgebramatmodule",
    true, 
    [ IsPathAlgebraMatModule ], 0,
    function( M )

    local A, K, Q, vertices, num_vert, outgoingarrows, mats, arrows, dim_M, 
          subspaces, i, a, j, socle, matrixfunction, dim_socle, socleofmodule, 
          socleinclusion, V, temp;

    A := RightActingAlgebra(M);
    if Dimension(M) = 0 then 
        return ZeroMapping(M,M);
    else
        K := LeftActingDomain(A);
        Q := QuiverOfPathAlgebra(A);
        vertices := VerticesOfQuiver(Q);
        num_vert := Length(vertices);
        outgoingarrows := List([1..num_vert], x -> OutgoingArrowsOfVertex(vertices[x]));
        dim_M := DimensionVector(M);
        mats := MatricesOfPathAlgebraModule(M);
        arrows := ArrowsOfQuiver(Q);
        dim_socle := List([1..num_vert], x -> 0);
        socle := List([1..num_vert], x -> []);
        for i in [1..num_vert] do
            if ( Length(outgoingarrows[i]) = 0 ) or ( dim_M[i] = 0 ) then
                dim_socle[i] := dim_M[i];
                if  dim_M[i] = 0 then
                    socle[i] := NullMat(1,1,K);
                else
                    socle[i] := IdentityMat(dim_M[i],K);
                fi;
            else
                subspaces := List([1..dim_M[i]], y -> []);   
                for a in outgoingarrows[i] do
                    for j in [1..dim_M[i]] do
                        Append(subspaces[j], StructuralCopy(mats[Position(arrows,a)][j]));
                    od;
                od;
                V := FullRowSpace(K,dim_M[i]);
                temp := NullspaceMat(subspaces);
                dim_socle[i] := Dimension(Subspace(V,temp));
                if dim_socle[i] = 0 then
                    socle[i] := NullMat(1,dim_M[i],K);
                else
                    socle[i] := temp;
                fi;
            fi;
        od;
        socleofmodule := RightModuleOverPathAlgebra(A,dim_socle,[]);
        socleinclusion := RightModuleHomOverAlgebra(socleofmodule,M,socle);
#        SetSocleOfModule(M,socleofmodule);
        return socleinclusion;
    fi;
end
  );

#######################################################################
##
#A  SocleOfModule( <M> )
##
##  This function computes the socle  soc(M)  of the module M. 
##
InstallMethod( SocleOfModule, 
    "for a pathalgebramatmodule",
    true, 
    [ IsPathAlgebraMatModule ], 0,
    function( M )

    return Source(SocleOfModuleInclusion(M));
end
);

#######################################################################
##
#O  CommonDirectSummand( <M>, <N> )
##
##  This function is using the algorithm for finding a common direct 
##  summand presented in the paper "Gauss-Elimination und der groesste
##  gemeinsame direkte Summand von zwei endlichdimensionalen Moduln"
##  by K. Bongartz, Arch Math., vol. 53, 256-258, with the modification
##  done by Andrzej Mroz found in "On the computational complexity of Bongartz's
##  algorithm" (improving the complexity of the algorithm).
##
InstallMethod( CommonDirectSummand, 
    "for two path algebra matmodules",
    [ IsPathAlgebraMatModule, IsPathAlgebraMatModule  ], 0,
    function( M, N ) 

    local   HomMN,  HomNM,  mn,  nm,  m,  n,  l,  zero,  j,  i,  temp,  
          r,  f,  fnm,  nmf;

    if RightActingAlgebra( M ) <> RightActingAlgebra( N ) then 
        Print( "The two modules are not modules over the same algebra.\n" );
        return fail;
    else
        HomMN := HomOverAlgebra( M, N );
        HomNM := HomOverAlgebra( N, M );
        mn := Length( HomMN );
        nm := Length( HomNM );
      
        if mn = 0 or nm = 0 then 
            return false;
        fi;
      
        m := Maximum( DimensionVector( M ) );
        n := Maximum( DimensionVector( N ) );
        if n = m then
            l := n;
        else
            l := Minimum( [ n, m ] ) + 1;
        fi;
        
        n := Int( Ceil( Log2( 1.0*( l ) ) ) );
          
        zero := ZeroMapping( M, M );
      
        for j in [ 1..nm ] do
            for i in [ 1..mn ] do
                if l > 1 then  # because hom^0 * hom => error! 
                    temp := HomMN[ i ] * HomNM[ j ];
                    for r in [ 1..n ] do
                        temp := temp * temp;
                    od;
                    f := temp * HomMN[ i ];
                else 
                    f := HomMN[ i ];
                fi;
                
                fnm := f * HomNM[ j ];
              
                if fnm <> zero then
                    nmf := HomNM[ j ] * f; 
                    return [ Image( fnm ), Kernel( fnm ), Image( nmf ), Kernel( nmf ) ];
                fi;
            od;
        od;

        return false;
    fi; 
end
);

#######################################################################
##
#O  MaximalCommonDirectSummand( <M>, <N> )
##
##  This function is using the algorithm for finding a maximal common 
##  direct summand based on the algorithm presented in the paper 
##  "Gauss-Elimination und der groesste gemeinsame direkte Summand von 
##  zwei endlichdimensionalen Moduln" by K. Bongartz, Arch Math., 
##  vol. 53, 256-258, with the modification done by Andrzej Mroz found 
##  in "On the computational complexity of Bongartz's algorithm" 
##  (improving the complexity of the algorithm).
##
InstallMethod( MaximalCommonDirectSummand, 
    "for two path algebra matmodules",
    [ IsPathAlgebraMatModule, IsPathAlgebraMatModule  ], 0,
    function( M, N ) 

    local U, V, maxcommon, L;

    U := M;
    V := N;
    maxcommon := [];
    repeat 
        L := CommonDirectSummand(U,V);
        if L <> false and L <> fail then 
            Add(maxcommon,L[1]);
            U := L[2];
            V := L[4];
            if Dimension(L[2]) = 0 or Dimension(L[4]) = 0 then
                break;
            fi;
        fi;
    until  L = false or L = fail;
    
    if Length(maxcommon) = 0 then 
        return false;
    else 
        return [maxcommon,U,V];
    fi;     
end
);

#######################################################################
##
#O  IsomorphicModules( <M>, <N> )
##
##  This function returns true if the modules  <M>  and  <N>  are 
##  isomorphic, an error message if  <M>  and  <N>  are not modules over 
##  the same algebra and false otherwise.
##  
InstallMethod( IsomorphicModules, 
    "for two path algebra matmodules",
    [ IsPathAlgebraMatModule, IsPathAlgebraMatModule  ], 0,
    function( M, N ) 

    local L;

    if DimensionVector(M) <> DimensionVector(N) then 
        return false;
    elif Dimension(M) = 0 and Dimension(N) = 0 then 
        return true; 
    else 
        L := MaximalCommonDirectSummand(M,N);
        if L = false then 
            return false;
        else
            if Dimension(L[2]) = 0 and Dimension(L[3]) = 0 then 
                return true;
            else
                return false;
            fi;
        fi;
    fi;
end
); 

#######################################################################
##
#O  IsDirectSummand( <M>, <N> )
##
##  This function returns true if the module  <M>  is isomorphic to a 
##  direct of the module  <N>, an error message if  <M>  and  <N>  are 
##  not modules over the same algebra and false otherwise.
##  
InstallMethod( IsDirectSummand, 
    "for two path algebra matmodules",
    [ IsPathAlgebraMatModule, IsPathAlgebraMatModule  ], 0,
    function( M, N ) 

    local L;

    if not DimensionVectorPartialOrder(M,N) then 
        return false;
    else 
        L := MaximalCommonDirectSummand(M,N);
        if L = false then 
            return false;
        else 
            if Dimension(L[2]) = 0 then 
                return true;
            else
--> --------------------

--> maximum size reached

--> --------------------

[ Original von:0.82Diese Quellcodebibliothek enthält Beispiele in vielen Programmiersprachen. Man kann per Verzeichnistruktur darin navigieren. Der Code wird farblich markiert angezeigt.  Datei übertragen  ]