Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  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

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

[ Dauer der Verarbeitung: 0.54 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge