1# GAP Implementation
2# This file was generated from
3# $Id: functors.gi,v 1.9 2012/05/15 07:12:00 sunnyquiver Exp $
4
5
6#######################################################################
7##
8#O  DualOfModule(<M>)
9##
10##  This function computes the dual DM of the module <M>, that is,
11##  it computes Hom_k(M, k). If <M> is a module over A, then DM is a
12##  module over the opposite algebra of A.
13##
14InstallMethod ( DualOfModule,
15    "for a representation of a quiver",
16    [ IsPathAlgebraMatModule ], 0,
17    function( M )
18#
19#   M     = a representation of the quiver Q over K with rels
20#
21        local A_op, KQ, KQ_op, dim_vect_M, num_vert, vertices, i, j,
22  	      count, mat_M, mat_M_op, X, mats, arrows, a,
23	      vert_in_quiver, origin, target, N;
24
25A_op  := OppositeAlgebra(RightActingAlgebra(M));
26dim_vect_M := DimensionVector(M);
27if Sum(dim_vect_M) = 0 then
28   return ZeroModule(A_op);
29else
30    KQ_op := OriginalPathAlgebra(A_op);
31    num_vert := Length(DimensionVector(M));
32    mat_M    := MatricesOfPathAlgebraModule(M);
33    arrows   := ArrowsOfQuiver(QuiverOfPathAlgebra(KQ_op));
34    mat_M_op := List(mat_M, X -> TransposedMat(X));
35    vert_in_quiver := VerticesOfQuiver(QuiverOfPathAlgebra(KQ_op));
36    mats := [];
37    for a in arrows do
38    	i := Position(arrows,a);
39	origin := Position(vert_in_quiver,SourceOfPath(a));
40	target := Position(vert_in_quiver,TargetOfPath(a));
41 	if ( dim_vect_M[origin] <> 0 ) and ( dim_vect_M[target] <> 0 ) then
42	   Add(mats,[a,mat_M_op[i]]);
43	else
44	   Add(mats,[a,[dim_vect_M[origin],dim_vect_M[target]]]);
45        fi;
46    od;
47
48    if IsPathAlgebra(A_op) then
49       N:= RightModuleOverPathAlgebra(A_op,mats);
50    else
51       N:= RightModuleOverPathAlgebra(A_op,mats);
52    fi;
53    SetDualOfModule(N,M);
54    if HasIsIndecomposableModule(M) and IsIndecomposableModule(M) then
55        SetIsIndecomposableModule(N, true);
56    fi;
57    if HasIsProjectiveModule(M) and IsProjectiveModule(M) then
58        SetIsInjectiveModule(N, true);
59    fi;
60    if HasIsInjectiveModule(M) and IsInjectiveModule(M) then
61        SetIsProjectiveModule(N, true);
62    fi;
63    return N;
64fi;
65end
66);
67
68#######################################################################
69##
70#O  TransposeOfModule(<M>)
71##
72##  This function computes the transpose Tr(M) of the module <M>, that is,
73##  if  P1 ---> P0 ---> M ---> 0 is a projective presentation of <M>,
74##  and <M> is a module over an algebra A, then Tr(M) is the cokernel
75##  of the map
76##
77##    Hom_A(P0,A) ---> Hom_A(P1,A)
78##
79InstallMethod( TransposeOfModule,
80   "for a path algebra",
81   [ IsPathAlgebraMatModule ], 0,
82   function( M )
83
84   local A, B, Q, fam, KQ, gens, K,
85         num_vert, vertices,  verticesinalg,
86         arrows, BB, i, j, B_M, G, MM, projective_cover, r,
87         test, vertex_list, P, PI_list, zero_in_P, g, temp,
88         matrix, solutions, Solutions, projective_vector, s,
89         a, syzygyoverKQ, U, RG, rgb, new_rtgbofI, run_time, rad,
90         vector, part, newpart, zero, radicalspace, V, W, VW, f,
91         topofsyzygy, x, Topofsyzygy, PP, P_list, P1_list, P_0, P_1,
92         min_gen_list, inc_list, supp, Aop, dim, PPop, P_0op_list, P_0op,
93         matrix_op;
94
95   A := RightActingAlgebra(M);
96   B := CanonicalBasis(A);
97   Q := QuiverOfPathAlgebra(A);
98   fam := ElementsFamily(FamilyObj( UnderlyingLeftModule( B ) ));
99   KQ := OriginalPathAlgebra(A);
100   K := LeftActingDomain(A);
101
102   if IsProjectiveModule(M) then
103       return ZeroModule(OppositeAlgebra(A));
104   fi;
105   num_vert := NumberOfVertices(Q);
106   vertices := VerticesOfQuiver(Q);
107   if IsPathAlgebra(A) then
108      verticesinalg := GeneratorsOfAlgebra(A){[1..num_vert]};
109      arrows   := GeneratorsOfAlgebra(A){[1+num_vert..num_vert+NumberOfArrows(Q)]};
110   else
111      verticesinalg := GeneratorsOfAlgebra(A){[2..1+num_vert]};
112      arrows   := GeneratorsOfAlgebra(A){[2+num_vert..1+num_vert+NumberOfArrows(Q)]};
113   fi;
114#
115# Finding a basis for all the indecomposable projective A-modules as
116# right ideals.
117#
118   BB := [];
119   for i in [1..num_vert] do
120      BB[i] := [];
121   od;
122   for i in [1..num_vert] do
123      for j in [1..Length(B)] do
124         if verticesinalg[i]*B[j] <> Zero(A) then
125            Add(BB[i],B[j]);
126         fi;
127      od;
128   od;
129
130   B_M := CanonicalBasis(M);
131   G   := MinimalGeneratingSetOfModule(M);
132#
133# Computing the product of all the elements in the
134# minimal generating set G of M, with the basis of the
135# indecomposable projective covering that generator.
136#
137   MM := [];
138   projective_cover := [];
139   for i in [1..Length(G)] do
140      r := 0;
141      repeat
142         r := r + 1;
143         test := G[i]^verticesinalg[r] <> Zero(M);
144      until test;
145      projective_cover[i] := r;
146      for j in [1..Length(BB[r])] do
147         Add(MM,G[i]^BB[r][j]);
148      od;
149   od;
150
151   matrix := NullMat(Length(MM),Dimension(M),K);
152   for i in [1..Length(MM)] do
153      matrix[i] := Flat(ExtRepOfObj(MM[i])![1]);
154   od;
155#
156#  Finding the kernel of the projective cover as a vectorspace
157#
158   solutions := NullspaceMat(matrix);
159#
160# Finding the kernel of the projective cover as elements of the
161# direct sum of the indecomposable projective modules in the
162# projective cover.
163#
164   Solutions := [];
165   for i in [1..Length(solutions)] do
166      projective_vector := [];
167      s := 0;
168      for j in [1..Length(projective_cover)] do
169         a := Zero(A);
170         for r in [1..Length(BB[projective_cover[j]])] do
171            a := a + BB[projective_cover[j]][r]*solutions[i][r+s];
172         od;
173         Add(projective_vector,a);
174         s := s + Length(BB[projective_cover[j]]);
175      od;
176      Add(Solutions,projective_vector);
177   od;
178#
179# Finding the top of the syzygy, first finding generators of the
180# radical of the syzygy, rad.
181#
182   zero := ListWithIdenticalEntries(Length(projective_cover),Zero(A));
183   rad := [];
184   for s in Solutions do
185      for a in arrows do
186         if s*a <> zero then
187            Add(rad,s*a);
188         fi;
189      od;
190   od;
191#
192# Computing the radical as a vectorspace by flattening the vectors.
193#
194   radicalspace := [];
195   for s in rad do
196      vector := [];
197      for i in [1..Length(projective_cover)] do
198         part := Coefficients(B,s[i]);
199         newpart := [];
200         for j in [1..Length(BB[projective_cover[i]])] do
201            newpart[j] := part[Position(B,BB[projective_cover[i]][j])];
202         od;
203         Add(vector,newpart);
204      od;
205      vector := Flat(vector);
206      Add(radicalspace,vector);
207   od;
208#
209# Computing a basis for syzygy modulo radical of syzygy as a
210# vectorspace and pulling it back to the syzygy.
211#
212if Length(solutions) = 0 then
213   Print("The entered module is projective.\n");
214   return ZeroModule(OppositeAlgebra(A));
215else
216   V := VectorSpace(K,solutions);
217   W := Subspace(V,radicalspace);
218   f := NaturalHomomorphismBySubspace(V,W);
219   VW := CanonicalBasis(Range(f));
220   topofsyzygy := [];
221   for x in VW do
222      Add(topofsyzygy,PreImagesRepresentative(f,x));
223   od;
224#
225# Finding the minimal generators of the syzygy as elements of the
226# direct sum of the indecomposable projective modules in the
227# projective cover.
228#
229   Topofsyzygy := [];
230   for i in [1..Length(topofsyzygy)] do
231      projective_vector := [];
232      s := 0;
233      for j in [1..Length(projective_cover)] do
234         a := Zero(A);
235         for r in [1..Length(BB[projective_cover[j]])] do
236            a := a + BB[projective_cover[j]][r]*topofsyzygy[i][r+s];
237         od;
238         Add(projective_vector,a);
239         s := s + Length(BB[projective_cover[j]]);
240      od;
241      Add(Topofsyzygy,projective_vector);
242   od;
243#
244# Finding the indecomposable projective modules in the projective
245# cover of M.
246#
247   PP:= IndecProjectiveModules(A);
248   P_list := [];
249   for i in [1..Length(projective_cover)] do
250      Add(P_list,ShallowCopy(PP[projective_cover[i]]));
251   od;
252   P_0:= DirectSumOfQPAModules(P_list);
253#
254# Finding the indecomposable projective modules in the projective
255# cover of the syzygy of M.
256#
257   P1_list := [];
258   for i in [1..Length(Topofsyzygy)] do
259      supp := [];
260      for j in [1..Length(vertices)] do
261          if Topofsyzygy[i]*(vertices[j]*One(A)) <> Topofsyzygy[i]*Zero(A) then
262             Add(supp,j);
263         fi;
264      od;
265      if Length(supp) = 1 then
266         Add(P1_list,supp[1]);
267      else
268         Print("Error: Minimal generators of the syzygy are not uniform.\n");
269         return fail;
270      fi;
271   od;
272#
273# Transposing the presentation matrix of the module M,
274# and taking the corresponding opposite element in the
275# opposite algebra of all entries in the presentation matrix.
276#
277   Aop := OppositeAlgebra(A);
278   matrix := ShallowCopy(TransposedMat(Topofsyzygy));
279   dim := DimensionsMat(matrix);
280   for i in [1..dim[1]] do
281      matrix[i] := List(matrix[i],x->OppositePathAlgebraElement(x));
282   od;
283#
284# Finding all indecomposable projective modules over the opposite algebra.
285#
286   PPop := IndecProjectiveModules(Aop);
287#
288# Constructing the projective cover of the transpose of M.
289#
290   P_0op_list := List(P1_list,x -> ShallowCopy(PPop[x]));
291   P_0op := DirectSumOfQPAModules(P_0op_list);
292#
293# Constructing the transpose as the coker of the inclusion of the image
294# of the presentation matrix of the transpose of M.
295#
296   gens := [];
297   inc_list := DirectSumInclusions(P_0op);
298   min_gen_list := [];
299   for i in [1..Length(P_0op_list)] do
300      Add(min_gen_list,ImageElm(inc_list[i],MinimalGeneratingSetOfModule(P_0op_list[i])[1]));
301   od;
302   for i in [1..dim[1]] do
303      temp := Zero(P_0op);
304      for j in [1..Length(min_gen_list)] do
305         temp := temp +  min_gen_list[j]^matrix[i][j];
306      od;
307      Add(gens,temp);
308   od;
309   f := SubRepresentationInclusion(P_0op,gens);
310   U := CoKernel(f);
311   if Dimension(U) <> 0 and HasIsIndecomposableModule(M) and IsIndecomposableModule(M) then
312       SetIsIndecomposableModule(U, true);
313   fi;
314
315   return U;
316fi;
317end
318);
319
320#######################################################################
321##
322#O  DTr(<M>)
323##
324##  This function returns the dual of the transpose of a module <M>,
325##  sometimes denoted by "tau". It uses the previous methods DualOfModule
326##  and TransposeOfModule.
327##
328InstallMethod( DTr,
329    "for a path algebra module",
330    [ IsPathAlgebraMatModule ], 0,
331    function( M );
332
333    return DualOfModule(TransposeOfModule(M));
334end
335);
336
337#######################################################################
338##
339#O  TrD(<M>)
340##
341##  This function returns the transpose of the dual of a module <M>,
342##  sometimes denoted by "tau inverse". It uses the previous methods DualOfModule
343##  and TransposeOfModule.
344##
345InstallMethod( TrD,
346    "for a path algebra module",
347    [ IsPathAlgebraMatModule ], 0,
348    function( M );
349
350    return TransposeOfModule(DualOfModule(M));
351end
352);
353
354#######################################################################
355##
356#O  DTr(<M>, <n>)
357##
358##  This function returns returns DTr^n(<M>) of a module <M>.
359##  It will also print "Computing step i ..." when computing the ith
360##  DTr. <n> must be an integer.
361##
362InstallOtherMethod( DTr,
363   "for a path algebra module",
364   [ IsPathAlgebraMatModule, IS_INT ], 0,
365   function( M, n )
366
367   local U, i;
368
369   U := M;
370   if n < 0 then
371      for i in [1..-n] do
372         Print("Computing step ",i,"...\n");
373         U := TrD(U);
374      od;
375   else
376      if n >= 1 then
377         for i in [1..n] do
378            Print("Computing step ",i,"...\n");
379            U := DTr(U);
380         od;
381      fi;
382   fi;
383
384   return U;
385end
386);
387
388#######################################################################
389##
390#O  TrD(<M>, <n>)
391##
392##  This function returns returns TrD^n(<M>) of a module <M>.
393##  It will also print "Computing step i ..." when computing the ith
394##  TrD. <n> must be an integer.
395##
396##
397InstallOtherMethod( TrD,
398   "for a path algebra module",
399   [ IsPathAlgebraMatModule, IS_INT ], 0,
400   function( M, n )
401
402   local U, i;
403
404   U := M;
405   if n < 0 then
406      for i in [1..-n] do
407         Print("Computing step ",i,"...\n");
408         U := DTr(U);
409      od;
410   else
411      if n >= 1 then
412         for i in [1..n] do
413         Print("Computing step ",i,"...\n");
414            U := TrD(U);
415         od;
416      fi;
417   fi;
418
419   return U;
420end
421);
422
423#######################################################################
424##
425#A  StarOfModule( <M> )
426##
427##  This function takes as an argument a module over an algebra  A  and
428##  computes the module  Hom_A(M,A)  over the opposite of  A.
429##
430InstallMethod( StarOfModule,
431    "for a matrix",
432    [ IsPathAlgebraMatModule ],
433
434    function( M )
435    local A, Aop, K, P, V, BV, BasisVflat, b, dimvector, Bproj, arrows,
436          arrowsop, leftmultwitharrows, a, source, target, matrices, temp;
437    #
438    # Setting up necessary infrastructure.
439    #
440    A := RightActingAlgebra(M);
441    Aop := OppositeAlgebra(A);
442    K := LeftActingDomain(M);
443    P := IndecProjectiveModules(A);
444    #
445    # Finding the vector spaces in each vertex in the representation of
446    # Hom_A(M,A)  and making a vector space of the flatten matrices in
447    # each basis vector in  Hom_A(M,e_iA).
448    #
449    V := List(P, p -> HomOverAlgebra(M,p));
450    BV := List(V, v -> List(v, x ->
451                  Flat(MatricesOfPathAlgebraMatModuleHomomorphism(x))));
452    BasisVflat := [];
453    for b in BV do
454        if Length(b) <> 0 then
455            Add(BasisVflat,
456                Basis(Subspace(FullRowSpace(K, Length(b[1])), b, "basis"), b));
457        else
458            Add(BasisVflat, []);
459        fi;
460    od;
461    #
462    # Finding the dimension vector of  Hom_A(M,A)  and computing the maps
463    # induced by left multiplication by arrows  alpha : i ---> j  from
464    # e_jA ---> e_iA.
465    #
466    dimvector := List(V, Length);
467    Bproj := BasisOfProjectives(A);
468    Bproj := List([1..Length(dimvector)],
469                  i -> Subspace(A, Flat(Bproj[i]), "basis"));
470    arrows := ArrowsOfQuiver(QuiverOfPathAlgebra(A));
471    arrowsop := ArrowsOfQuiver(QuiverOfPathAlgebra(Aop));
472    leftmultwitharrows := [];
473    for a in arrows do
474        source := VertexIndex(SourceOfPath(a));
475        target := VertexIndex(TargetOfPath(a));
476        Add(leftmultwitharrows,
477            HomFromProjective(MinimalGeneratingSetOfModule(P[source])[1]^(a*One(A)), P[source]));
478    od;
479    #
480    # Finally, finding the linear maps in the representation given by  Hom_A(M,A)  and
481    # constructing the module/representation over  A^op.
482    #
483    matrices := [];
484    for a in arrows do
485        source := VertexIndex(SourceOfPath(a));
486        target := VertexIndex(TargetOfPath(a));
487        if dimvector[source] <> 0 and dimvector[target] <> 0 then
488            temp := V[target]*leftmultwitharrows[Position(arrows, a)];
489            temp := List(temp, t -> Coefficients(BasisVflat[source],
490                            Flat(MatricesOfPathAlgebraMatModuleHomomorphism(t))));
491            Add(matrices, [String(arrowsop[Position(arrows, a)]), temp]);
492        fi;
493    od;
494
495    return RightModuleOverPathAlgebra(Aop, dimvector, matrices);
496end
497);
498
499#######################################################################
500##
501#A  StarOfModuleHomomorphism( <f> )
502##
503##  This function takes as an argument a homomorphism  f  between two
504##  modules  M  and  N  over an algebra  A  and computes the induced
505##  homomorphism from the module  Hom_A(N, A)  to the module
506##  Hom_A(M, A)  over the opposite of  A.
507##
508InstallMethod( StarOfModuleHomomorphism,
509    "for a matrix",
510    [ IsPathAlgebraMatModuleHomomorphism ],
511
512    function( f )
513    local M, N, starM, starN, A, Aop, K, P, VN, dimvectorstarN, BfVN,
514          VM, dimvectorstarM, BVM, BasisVMflat, b, maps, i, map, dimrow,
515          dimcol;
516
517    M := Source(f);
518    N := Range(f);
519    #
520    # Finding the source and range of  StarOfModuleHomomorphism(f).
521    #
522    starM := StarOfModule(M);
523    starN := StarOfModule(N);
524    #
525    # Setting up necessary infrastructure.
526    #
527    A := RightActingAlgebra(M);
528    Aop := OppositeAlgebra(A);
529    K := LeftActingDomain(M);
530    P := IndecProjectiveModules(A);
531    VN := List(P, p -> HomOverAlgebra(N,p));
532    dimvectorstarN := List(VN, Length);
533    #
534    # Finding the image of the map  StarOfModuleHomomorphism(f).
535    #
536    VN := List(VN, v -> f*v);
537    BfVN := List(VN, v -> List(v, x ->
538                    Flat(MatricesOfPathAlgebraMatModuleHomomorphism(x))));
539    #
540    # Computing the basis of StarOfModule(Source(f))  used when the module
541    # was constructed.
542    #
543    VM := List(P, p -> HomOverAlgebra(M,p));
544    dimvectorstarM := List(VM, Length);
545    BVM := List(VM, v -> List(v, x ->
546                   Flat(MatricesOfPathAlgebraMatModuleHomomorphism(x))));
547    BasisVMflat := [];
548    for b in BVM do
549        if Length(b) <> 0 then
550            Add(BasisVMflat,
551                Basis(Subspace(FullRowSpace(K, Length(b[1])), b, "basis")));
552        else
553            Add(BasisVMflat, []);
554        fi;
555    od;
556    #
557    # Constructing the map induced by  f  from StarOfModule(Range(f))  to
558    # StarOfModule(Source(f)).
559    #
560    maps := [];
561    for i in [1..Length(BfVN)] do
562        if Length(BfVN[i]) <> 0 then
563            map := List(BfVN[i], t -> Coefficients(BasisVMflat[i], t));
564        else
565            if dimvectorstarN[i] = 0 then
566                dimrow := 1;
567            else
568                dimrow := dimvectorstarN[i];
569            fi;
570            if dimvectorstarM[i] = 0 then
571                dimcol := 1;
572            else
573                dimcol := dimvectorstarM[i];
574            fi;
575            map := NullMat(dimrow,dimcol,K);
576        fi;
577        Add(maps, map);
578    od;
579
580    return RightModuleHomOverAlgebra(starN, starM, maps);
581end
582);
583
584#######################################################################
585##
586#A  NakayamaFunctorOfModule( <M> )
587##
588##  This function takes as an argument a module over an algebra  A  and
589##  computes the image of the Nakayama functor, that is, the module
590##  Hom_K(Hom_A(M, A), K)  over  A.
591##
592InstallMethod( NakayamaFunctorOfModule,
593    "for a matrix",
594    [ IsPathAlgebraMatModule ],
595
596    function( M );
597
598    return DualOfModule(StarOfModule(M));
599end
600  );
601
602#######################################################################
603##
604#A  NakayamaFunctorOfModuleHomomorphism( <f> )
605##
606##  This function takes as an argument a homomorphism  f  between two
607##  modules  M  and  N  over an algebra  A  and computes the induced
608##  homomorphism from the module  Hom_K(Hom_A(N, A), K)  to the module
609##  Hom_K(Hom_A(M, A), K)  over  A.
610##
611InstallMethod( NakayamaFunctorOfModuleHomomorphism,
612    "for a matrix",
613    [ IsPathAlgebraMatModuleHomomorphism ],
614
615    function( f );
616
617    return DualOfModuleHomomorphism(StarOfModuleHomomorphism(f));
618end
619);
620
621#######################################################################
622##
623#O  TensorProductOfModules( <M>, <N> )
624##
625##  Given two representations  <Arg>M</Arg> and <Arg>N</Arg>, where
626##  <Arg>M</Arg> is a right module over  <M>A</M> and  <Arg>N</Arg> is
627##  a right module over the opposite of <M>A</M>, then this function
628##  computes the tensor product <M>M\otimes_A N</M> as a vector space
629##  and a function <M>M\times N \to M\otimes_A N</M>.
630##
631InstallMethod ( TensorProductOfModules,
632    "for two representations of a fin. dim. quotient of a path algebra",
633    true,
634    [ IsPathAlgebraMatModule, IsPathAlgebraMatModule ],
635    0,
636    function( M, N )
637
638  local   A,  F,  topofM,  dimvectorN,  V,  elementarytensor,
639          projres,  pi,  d1,  inclusionsP1,  projectionsP0,
640          imagesofgensP1,  t,  projectivesinP0,  verticesofquiver,
641          projectivesinP1,  matrix,  topofP1,  topofP0,  dimvectorM,
642          size_matrix,  bigmatrix,  i,  tempmat,  j,  m,  s,  startN,
643          temp,  d1tensoronemap,  rowsinblock,  r,  dim,  W,  h;
644
645   A := RightActingAlgebra( M );
646   if A <> OppositeAlgebra( RightActingAlgebra( N ) ) then
647       Error("The entered modules are not over the appropriate algebras,\n");
648   fi;
649   F := LeftActingDomain( M );
650#
651# An easy check if the tensor product is zero, if so, return zero.
652#
653   topofM := DimensionVector( TopOfModule( M ) );
654   dimvectorN := DimensionVector( N );
655   if topofM*dimvectorN = 0 then
656     V := F^1;
657     elementarytensor := function( m, n );
658        return Zero(V);
659     end;
660
661     return [ TrivialSubspace( V ), elementarytensor ];
662   fi;
663#
664# Computing M \otimes N via taking a projective resolution of M and then tensoring
665# with N.
666#
667   projres := ProjectiveResolution( M );
668   ObjectOfComplex( projres, 1 );
669   pi := DifferentialOfComplex( projres, 0 );
670   d1 := DifferentialOfComplex( projres, 1 );
671
672   projectionsP0 := DirectSumProjections( Range( d1 ) );
673   t := Length( projectionsP0 );
674   projectivesinP0 := List( projectionsP0, p -> SupportModuleElement( MinimalGeneratingSetOfModule( Range( p ) )[ 1 ] ) );
675   if IsQuotientOfPathAlgebra( A ) then
676       projectivesinP0 := List( projectivesinP0, t -> CoefficientsAndMagmaElements( t![ 1 ]![ 1 ] )[ 1 ] );
677   elif IsPathAlgebra( A ) then
678       projectivesinP0 := List( projectivesinP0, t -> CoefficientsAndMagmaElements( t![ 1 ] )[ 1 ] );
679   else
680       Error("Something went wrong, inform the maintainers of the QPA-package,\n");
681   fi;
682   verticesofquiver := VerticesOfQuiver( QuiverOfPathAlgebra( A ) );
683   projectivesinP0 := List( projectivesinP0, v -> Position( verticesofquiver, v ) );
684#
685# If P_1 - d1 -> P_0 --> M --> 0 is a minimal projective presentation of M and
686# P_1\otimes N = (0), then  M\otimes N \simeq P_0\otimes N.
687#
688   if DimensionVector( Source( d1 ) ) * dimvectorN = 0 then
689       dim := topofM * dimvectorN;
690       V := F^dim;
691       h := NaturalHomomorphismBySubspace( V, TrivialSubspace( V ) );
692       elementarytensor := function( m, n )
693           local  p0, psum, nsum, v;
694
695           p0 := PreImagesRepresentative( pi, m );
696           psum := List( [ 1..t ], n -> ElementInIndecProjective( A, ImageElm( projectionsP0[ n ], p0 ), projectivesinP0[ n ] ) );
697           if IsQuotientOfPathAlgebra( A ) then
698               psum := List( psum, x -> ElementOfQuotientOfPathAlgebra( ElementsFamily( FamilyObj( OppositeAlgebra( A ) ) ), OppositePathAlgebraElement( x ), true ) );
699           elif IsPathAlgebra( A ) then
700               psum := List( psum, x -> OppositePathAlgebraElement( x ) );
701           else
702               Error("Something went wrong, inform the maintainers of the QPA-package,\n");
703           fi;
704           nsum := List( psum, x -> n^x );
705           v := Flat( List( [ 1..size_matrix[ 2 ] ], l -> nsum[ l ]![ 1 ]![ 1 ][ projectivesinP0[ l ] ] ) );
706
707           return ImageElm( h, v );
708       end;
709
710       return [ Range( h ), elementarytensor ];
711   fi;
712
713   inclusionsP1 := DirectSumInclusions( Source( d1 ) );
714   imagesofgensP1 := List( inclusionsP1, f -> ImageElm( f, MinimalGeneratingSetOfModule( Source( f ) )[ 1 ] ) );
715   imagesofgensP1 := List( imagesofgensP1, m -> ImageElm( d1, m ) );
716   projectivesinP1 := List( inclusionsP1, i -> SupportModuleElement( MinimalGeneratingSetOfModule( Source( i ) )[ 1 ] ) );
717   projectivesinP1 := List( projectivesinP1, t -> CoefficientsAndMagmaElements( t![ 1 ]![ 1 ] )[ 1 ] );
718   projectivesinP1 := List( projectivesinP1, v -> Position( verticesofquiver, v ) );
719
720   matrix := List( imagesofgensP1, m -> List( [ 1..t ], n ->
721                                                          ElementInIndecProjective( A, ImageElm( projectionsP0[ n ], m ), projectivesinP0[ n ] ) ) );
722   if IsQuotientOfPathAlgebra( A ) then
723       matrix := List( matrix, m -> List( m, x -> ElementOfQuotientOfPathAlgebra( ElementsFamily( FamilyObj( OppositeAlgebra( A ) ) ), OppositePathAlgebraElement( x ), true ) ) );
724   elif IsPathAlgebra( A ) then
725       matrix := List( matrix, m -> List( m, x -> OppositePathAlgebraElement( x ) ) );
726   else
727       Error("Something went wrong, inform the maintainers of the QPA-package,\n");
728   fi;
729
730   topofP1 := DimensionVector( TopOfModule( Source( d1 ) ) );
731   topofP0 := DimensionVector( TopOfModule( Range( d1 ) ) );
732   dimvectorM := DimensionVector( M );
733   size_matrix := DimensionsMat( matrix );
734
735   bigmatrix := NullMat( size_matrix[ 1 ], size_matrix[ 2 ], F );
736   for i in [ 1..size_matrix[ 1 ] ] do
737       for j in [ 1..size_matrix[ 2 ] ] do
738           m := matrix[ i ][ j ];
739           s := projectivesinP0[ j ];
740           t := projectivesinP1[ i ];
741           startN := Sum( dimvectorN{ [ 1..t - 1 ] } );
742           if Length( Basis( N ){ [ startN + 1..startN + dimvectorN[ t ] ] } ) > 0 then
743               temp := List( Basis( N ){ [ startN + 1..startN + dimvectorN[ t ] ] }, b -> b^m );
744               tempmat := List( temp, t -> t![ 1 ]![ 1 ][ s ] );
745           else
746               tempmat := NullMat( 1, Length( Basis( N )[ 1 ]![ 1 ]![ 1 ][ s ] ), F );
747           fi;
748           bigmatrix[ i ][ j ] := tempmat;
749       od;
750   od;
751
752   d1tensoronemap := [];
753   for i in [ 1..size_matrix[ 1 ] ] do
754       rowsinblock := DimensionsMat( bigmatrix[ i ][ 1 ] )[ 1 ];
755       for r in [ 1..rowsinblock ] do
756           temp := [];
757           for j in [ 1..size_matrix[ 2 ] ] do
758               Add( temp, bigmatrix[ i ][ j ][ r ] );
759           od;
760           temp := Flat(temp);
761           Add( d1tensoronemap, temp );
762       od;
763   od;
764
765   dim := Length( d1tensoronemap[ 1 ] );
766   V := F^dim;
767   W := Subspace( V, d1tensoronemap );
768   h := NaturalHomomorphismBySubspace( V, W );
769
770   elementarytensor := function( m, n )
771       local  p0, psum, nsum, v;
772
773       p0 := PreImagesRepresentative( pi, m );
774       psum := List( [ 1..t ], n -> ElementInIndecProjective( A, ImageElm( projectionsP0[ n ], p0 ), projectivesinP0[ n ] ) );
775       if IsQuotientOfPathAlgebra( A ) then
776           psum := List( psum, x -> ElementOfQuotientOfPathAlgebra( ElementsFamily( FamilyObj( OppositeAlgebra( A ) ) ), OppositePathAlgebraElement( x ), true ) );
777       elif IsPathAlgebra( A ) then
778           psum := List( psum, x -> OppositePathAlgebraElement( x ) );
779       else
780           Error("Something went wrong, inform the maintainers of the QPA-package,\n");
781       fi;
782       nsum := List( psum, x -> n^x );
783       v := Flat( List( [ 1..size_matrix[ 2 ] ], l -> nsum[ l ]![ 1 ]![ 1 ][ projectivesinP0[ l ] ] ) );
784
785       return ImageElm( h, v );
786   end;
787
788   return [ Range( h ), elementarytensor ];
789end);
790