source: git/Singular/LIB/modules.lib

spielwiese
Last change on this file was 4772b1, checked in by Hans Schoenemann <hannes@…>, 4 years ago
if != for cring is not /yet) implemented...
  • Property mode set to 100644
File size: 62.5 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="version modules.lib 4.1.2.0 Feb_2019 "; // $Id$
3category="Commutative Algebra";
4info="
5LIBRARY:  modules.lib    Modules
6
7AUTHORS:  J. Boehm, boehm@mathematik.uni-kl.de
8    D. Wienholz wienholz@mathematik.uni-kl.de
9    C. Koenen koenen@rhrk.uni-kl.de
10    M. Mayer mayer@mathematik.uni-kl.de
11
12OVERVIEW:
13This library is used for the computation of graded free resolutions with an own graduation of
14the monomials. For these Resolution is a new class of modules needed. These modules, can be
15computed via the image, kernel, cokernel of a matrix or the subquotient of two matrices.
16The used matrices also have a free module as source and target, with graded generators if the
17matrix is homogeneous. A matrix of this new form is created by a normal matrix, source, target and
18the graduatin, if the matrix is homogeneous, are done automatically. With this matrices it is then
19possible to compute the new class of modules.
20This library also offers the opppurtunity to create R-module-homomorphisms betweens two modules.
21For these homorphisms the kernel can be computed an will be returned as a module of the new class.
22
23This is experimental work in progress!!!
24
25
26KEYWORDS: graded-module, graded-resolution, homogenoues-matrix, R-module-homomorphism
27
28TYPES:
29Matrix      the class of matrices with source and target in form of free modules
30FreeModule    free modules representet with the ring and degree
31Resolution    class of graded resolutions
32Module      modules represented by either the image, coker, kernelof a matrix or the subquotient of two matrices
33Vector      element of a Module
34Ideal      same as ideal, but with it's own basering saved, used to compute resolutions
35Homomorphism    class of R-module-homomormphisms
36
37PROCEDURES:
38id(int n)      return a nxn identity Matrix
39zero(int n,int m)    return a nxm zero Matrix
40freeModule(ring,int,list)  creating a graded free module
41makeMatrix(matrix,#int)    creating a Matrix with graded target and source if the matrix is homogeneous. If # is set to 1, makeMatrix ignores the grading of source & target.
42makeIdeal(ideal)    creates an Ideal from an given ideal, is used to compute a resolution of the ideal
43Target(Matrix)      return target of the Matrix
44Source(Matrix)      return source of the Matrix
45printMatrix(Matrix)    print a Matrix
46printFreeModule(FreeModule)  print a FreeModule
47printResolution(Resolution)  print a Resolution
48printModule(Module)    print a Module
49printHom(Homomorphism)    print a Homomorphism
50mRes(Module/Ideal,#int)    return a minimized graded Resolution
51sRes(Module/Ideal,#int)    return a  graded Resolution computet with Schreyer's method
52Res(Module/Ideal,#int)    return a graded Resolution
53Betti(Resolution)    return the Betti-Matrix of the Resolution
54printBetti(Resolution)    prints the Betti-matrix of the Resolution
55SetDeg(list/intvec)    sets an own graduatuation for the monomials
56Deg(poly)      same as deg, but can be used with an own graduation
57Degree(FreeModule)    return list with degrees of the module
58Degrees(Module)      return list with degrees of the module
59subquotient(Matrix,Matrix)  return a Module, the subquotient of the two Matrices
60coker(Matrix)      return a Module, the cokernel of the Matrix
61image(Matrix)      return a Module, the image of the Matrix
62Ker(Matrix)      return a Module, the kernel of the Matrix
63compareModules(Module,Module)  return 0 or 1, compares the two Modules up to isomorphism
64addModules(Module,Module)  return a Module, sum of the two Modules
65homomorphism(matrix,Module,Module)  creates a R-Modul-Homomorphism
66target(Homomorphism)    return a Module, target of the Homomorphism
67source(Homomorphism)    return a Module, source of the Homomorphism
68compareMatrix(Matrix,Matrix)  return 0 or 1, compares two Matrices
69
70
71freeModule2Module(FreeModule)    converts a FreeModule into a Module
72makeVector(vector,Module)    creates Vector in the given Module
73netVector(Vector)      prints Vector
74netMatrix(Matrix)      prints Matrix
75presentation(Module)      converts M as a Subquotient to the Coker of a matrix C
76tensorMatrix(Matrix,Matrix)    computes tensorproduct of two Matrices
77tensorModule(Module,Module)    computes tensorproduct of two Modules
78tensorModFreemod(Module,FreeModule)  computes tensorproduct of Module and FreeModule
79tensorFreemodMod(FreeModule,Module)  computes tensorproduct of FreeModule and Module
80tensorFreeModule(FreeModule,FreeModule)  computes tensorproduct ot two FreeModules
81tensorProduct(def,def)      computes tensorproduct
82pruneModule(Module)      simplifies the presentation of a Module
83hom(Module,Module)      computes Hom(M,N)
84kerHom(Homomorphism)      computes the kernel of a Homomorphism
85interpret(Vector)      interprets the Vector in some Module or abstract space
86interpretInv(def,Module)    interprets a Vector or Homomorphism into the given Module
87reduceIntChain(Module,#int)    reduces a chain of interpretations to minimal size or # steps
88interpretElem(Vector,#int)    interpret a Vector with # steps or until can't interpret further
89interpretList(list,#int)    interpret a list of Vectors as far as possible
90compareVectors(Vector,Vector)    compares two Vectors with regard to the relations of their Module
91simplePrune(Module)                     simplify module
92
93";
94
95LIB "matrix.lib";
96LIB "homolog.lib";
97
98
99static proc mod_init()
100{
101LIB "nets.lib";
102
103newstruct("FreeModule","int Rank,ring over,int isgraded,list grading");
104newstruct("Matrix","matrix hom, FreeModule source, FreeModule target, ring over,int ishomogeneous");
105newstruct("Module","Matrix generators,Matrix relations,ring over,int isgraded, list grading, list interpretation");
106//interpretation is a list of two sublists: the first one gives the interpretation into another module M (entries are of type Vector), while the second denotes the inverse of this map (entries are of type vector, since the targetspace is clear).
107newstruct("Vector","Module space, vector entries");
108newstruct("Homomorphism","Module target,Module source,matrix rule,ring over");
109newstruct("Resolution","resolution reso,ring over,int isgraded,list dd");
110newstruct("Ideal","ring over, ideal gens");
111
112system("install","FreeModule","==",compareFreeModules,2);
113system("install","Resolution","print",printResolution,1);
114system("install","Matrix","print",printMatrix,1);
115system("install","FreeModule","print",printFreeModule,1);
116system("install","Module","print",printModule,1);
117system("install","Homomorphism","print",printHom,1);
118system("install","Module","+",addModules,2);
119system("install","Module","==",compareModules,2);
120system("install","Matrix","==",compareMatrix,2);
121system("install","Vector","+",addVector,2);
122system("install","Vector","*",multVecPoly,2);
123system("install","Vector","print",printVector,1);
124system("install","Vector","=",makeVector,1);
125system("install","Ideal","=",makeIdeal,1);
126system("install","Matrix","=",makeMatrix,1);
127system("install","Homomorphism","=",homomorphism,1);
128system("install","Homomorphism","*",scaleHomomorphism,2);
129system("install","Homomorphism","+",addHomomorphism,2);
130system("install","Vector","==",compareVectors,2);
131HashTable netH = hashTable(list(list("Module")),list("netModule"));
132HashTable netMat = hashTable(list(list("Matrix"),list("Vector"),list("Homomorphism")),list("netMatrix","netVector","netHom"));
133Method netM = method(netH);
134Method netNat = method(netMat);
135Method netN = Nets::net_;
136Method netS = netN + netM + netNat;
137installMethod(netS,"net");
138Nets::net_=netS;
139HashTable kerH = hashTable(list(list("matrix"),list("Matrix"),list("Homomorphism")),list("kermat","kerMat","kerHom"));
140Method ker_ = method(kerH);
141export(ker_);
142installMethod(ker_,"ker");
143
144
145list tensortypes = list("Module","Module"),list("FreeModule","FreeModule"),list("Matrix","Matrix"),list("FreeModule","Module"),list("Module","FreeModule");
146list tensorfuncs = "tensorModule","tensorFreeModule","tensorMatrix","tensorFreemodMod","tensorModFreemod";
147HashTable tensors = hashTable(tensortypes,tensorfuncs);
148Method Tens_ = method(tensors);
149installMethod(Tens_,"tensorProduct");
150system("install","Module","*",tensorProduct,2);
151}
152
153
154static proc kermat(matrix A){
155return(syz(A));}
156
157static proc kerMat(Matrix A){
158Matrix M = syz(A.hom);
159return(M);}
160
161
162proc id(int n)
163"USAGE: id(n); n integer
164RETURN: returns the n x n identity matrix, with nongraded free modules for source and target
165EXAMPLE: example id, shows an example"
166{
167  matrix E[n][n];
168  E=E+1;
169  Matrix M=makeMatrix(E);
170  return(M);
171}
172
173example
174{
175 "EXAMPLE:"; echo=2;
176 ring r;
177 int n=4;
178 id(n);
179}
180
181/////////////////////////////////////////////////////////////////////////////////////////
182
183proc zero(int n,int m)
184"USAGE: zero(n); n and m integer
185RETURN: returns the n x m zero matrix, with nongraded free modules for source and target
186EXAMPLE: example zero, shows an example"
187{
188  matrix E[n][m];
189  Matrix M=makeMatrix(E);
190  return(M);
191}
192
193example
194{
195 "EXAMPLE:"; echo=2;
196 ring r;
197 int n=4;
198 int m=3;
199 zero(n,m);
200}
201
202/////////////////////////////////////////////////////////////////////////////////////////
203
204proc SetDeg(def mydeg)
205"USAGE: SetDeg(l), l list or intvec
206RETURN: nothing, saves own degrees for the different variables of the basering
207NOTE: should be used after decleration of the ring and shouldn't be changed afterwards
208EXAMPLE: example SetDeg, shows an example"
209{
210list R=ringlist(basering);
211if(size(R[2])!=size(mydeg)){
212  ERROR("Number of arguments doesn't match number of variables");
213}
214intvec I;
215if(typeof(mydeg)=="intvec"){
216  I=mydeg;
217}else{
218  if(typeof(mydeg)=="list"){
219    for(int i=1;i<=size(mydeg);i++){
220      I[i]=mydeg[i];
221    }
222  }
223  else{
224  ERROR("Input isn't a list or intvec");
225  }
226}
227attrib(basering,"Grading",I);
228}
229
230example
231{
232 "EXAMPLE:"; echo=2;
233 ring r;
234 Deg(x);
235 list l=2,2,2;
236 SetDeg(l);
237 Deg(x);
238}
239
240////////////////////////////////////////////////////////////////////////////////
241
242proc Deg(def p)
243"USAGE: same as deg
244NOTE: only needed if custom degrees are set with SetDeg
245EXAMPLE: example Deg, shows an example"
246{
247if(size(attrib(basering,"Grading"))==0){return(deg(p));}
248else{return(deg(p,attrib(basering,"Grading")));}
249}
250example
251{
252 "EXAMPLE:"; echo=2;
253 ring r;
254 Deg(x);
255 list l=2,2,2;
256 SetDeg(l);
257 Deg(x);
258}
259
260////////////////////////////////////////////////////////////////////////////////
261
262proc printResolution(Resolution R)
263"USAGE: printResolution(R); or R; R Resolution
264RETURN: nothing, prints the resolution
265EXAMPLE: example Res, shows and example"
266{
267R.reso;
268}
269example
270{
271 "EXAMPLE:"; echo=2;
272 ring r;
273 matrix m[1][3]=x,y,z;
274 Matrix M=m;
275 Module N=coker(M);
276 N;
277 Resolution R = Res(N);
278 R;
279}
280
281///////////////////////////////////////////////////////////////////////////////////
282
283proc freeModule(def basis,int myrank,list degrees)
284"USAGE: freeModule(r,n,l); r ring, n integer, l list
285RETURN: a free Module over the ring r, with rank n, and degrees l for the generators
286NOTE: -1 for nor graduation and 0 to set every degree to 0
287EXAMPLE: example freeModule, shows an example"
288{
289def R=basering;
290setring(basis);
291int mydeg=0;
292FreeModule M;
293M.over= basis;
294M.Rank = myrank;
295list l=-1;
296M.isgraded=0;
297if(!(comparedeg(degrees,l))){
298  M.isgraded=1;
299  l=0;
300  if(comparedeg(degrees,l)){
301    for(int j=1;j<=myrank;j++){
302      M.grading[j]=mydeg;
303    }
304  }
305
306  else{
307  if(myrank!=size(degrees)){ERROR("Graduation incorrect")}
308  M.grading=degrees;
309  }
310}
311setring(R);
312return(M);
313}
314example
315{
316 "EXAMPLE:"; echo=2;
317 ring r;
318 int n=3;
319 list l=1,2,3;
320 freeModule(r,n,l);
321}
322
323///////////////////////////////////////////////////////////////////////////////
324
325static proc gradedMatrix(matrix m,list mydeg){
326Matrix M;
327M.ishomogeneous=1;
328M.over=basering;
329M.target = freeModule(basering,nrows(m),0);
330M.source = freeModule(basering,ncols(m),mydeg);
331M.hom = m;
332return(M);
333}
334
335//////////////////////////////////////////////////////////////////////////////////
336
337static proc resMatrix(matrix m,list t,FreeModule N){
338def R=basering;
339setring(N.over);
340list mydeg;
341Matrix M;
342M.ishomogeneous=1;
343M.over=basering;
344int a;
345int j;
346for(int i=1;i<=ncols(m);i++){
347  a=0;
348  for(j=1;j<=nrows(m);j++){
349    if(m[i][j]!=0){
350      a=Deg(m[i][j]);
351      break;
352    }
353  }
354  mydeg[i]=t[j]+a;
355}
356M.target = N;
357M.source = freeModule(basering,ncols(m),mydeg);
358M.hom = m;
359setring(R);
360return(M);
361}
362
363////////////////////////////////////////////////////////////////////////////////////////////
364
365static proc comparedeg(list l,list j){
366if(size(l)!=size(j)){return(0);}
367for(int i=1;i<=size(l);i++){
368  if(l[i]!=j[i]){return(0);}
369}
370return(1);
371}
372
373/////////////////////////////////////////////////////////////////////////////////////////////
374
375static proc isHomogenous(matrix m)
376{
377int j;
378int f;
379list mydeg;
380list controldeg;
381for(int i=1;i<=ncols(m);i++){
382  mydeg[i]=0;
383  controldeg[i]=0;
384  for(j=1;j<=nrows(m);j++){
385    if(m[j,i]!=0){
386      if(controldeg[i]==1){
387        if(mydeg[i]!=Deg(m[j,i])){return(-1)}
388      }
389      mydeg[i]=Deg(m[j,i]);
390      controldeg[i]=1;
391    }
392  }
393}
394return(mydeg)
395}
396
397////////////////////////////////////////////////////////////////////////////////////////////////
398
399proc printFreeModule(FreeModule M)
400"USAGE: printFreeModule(M); or M; M FreeModule
401RETURN: nothing, prints a free Module
402EXAMPLE: example freeModule, shows an example"
403{
404string l1;
405string l2;
406l2=nameof(basering);
407for(int i=1;i<=size(l2);i++){
408  l1=l1+" ";
409}
410l1=l1+string(M.Rank);
411print(l1);
412print(l2);
413print("free Module");
414if(M.isgraded){
415  string l3 = "Degrees of the generators: ";
416  for(i=1;i<=size(M.grading);i++){
417    l3=l3+"{"+string(M.grading[i])+"} ";
418  }
419  print(l3);
420}
421}
422example
423{
424 "EXAMPLE:"; echo=2;
425 ring r;
426 int n=3;
427 list l=1,2,3;
428 freeModule(r,n,l);
429}
430
431
432//////////////////////////////////////////////////////////////////////////////////////////////////
433
434proc makeIdeal(ideal i)
435"USAGE: makeIdeal(i) or Ideal I=i; i ideal
436RETURN: Ideal with saved basering
437EXAMPLE: example makeIdeal, shows an example"
438{
439Ideal I;
440I.over =basering;
441I.gens=i;
442return(I);
443}
444
445example
446{
447 "EXAMPLE:"; echo=2;
448 ring r;
449 ideal i=x,y,z+x;
450 i;
451 Ideal I=i;
452}
453
454static proc printIdeal(Ideal I)
455{
456stackNets(net(I.gens),net("ideal over ")+net(I.over));
457}
458
459//////////////////////////////////////////////////////////////////////////////////////////////////
460
461proc mRes(def M,int #)
462"USAGE: mRes(M,n); M Module or Ideal, n integer
463RETURN: Resolution, minimized resolution with graded modules
464NOTE: n is optional, if n ist positiv only that many steps will be computed
465      use R.dd[i]; to return the different modules as image of matrices, R Resolution i integer
466EXAMPLE. example mRes, shows an example"
467{
468module m;
469def S =basering;
470if(typeof(M)=="Ideal"){
471  setring(M.over);
472  m=M.gens;
473}
474if(typeof(M)=="Module"){
475  setring(M.over);
476  module gens=M.generators.hom;
477  module rels=M.relations.hom;
478  m=modulo(gens,rels);
479}
480int j=0;
481if(size(#)!=0){j=#;}
482list mydeg;
483Resolution R;
484R.reso=mres(m,j);
485matrix a=R.reso[1];
486R.dd[1]=makeMatrix(a);
487if(!(R.dd[1].ishomogeneous)){
488  R.isgraded=0;
489  for(int i=2;i<=(size(R.reso)+1);i++){
490    a=R.reso[i];
491    R.dd[i]=nongradedMatrix(a);
492  }
493
494}
495else{
496  R.isgraded=1;
497  for(int i=2;i<=(size(R.reso));i++){
498    a=R.reso[i];
499    mydeg=R.dd[i-1].source.grading;
500    R.dd[i]=resMatrix(a,mydeg,R.dd[i-1].source);
501  }
502}
503R.over=M.over;
504setring(S);
505return(R);
506}
507
508example
509{
510 "EXAMPLE:"; echo=2;
511 ring r;
512 matrix m[1][3]=x,y,z;
513 Matrix M=m;
514 Module N=coker(M);
515 N;
516 Resolution R = mRes(N);
517 R;
518 R.dd[2];
519}
520
521/////////////////////////////////////////////////////////////////////////////////////////////////
522
523proc sRes(def M,int #)
524"USAGE: sRes(M,n); M Module or Ideal, n integer
525RETURN: Resolution, with graded modules, computed with Schreyer's method using the function sres
526NOTE: n is optional, if n ist positiv only that many steps will be computed
527      use R.dd[i]; to return the different modules as image of matrices, R Resolution i integer
528EXAMPLE. example sRes, shows an example"
529{
530module m;
531def S =basering;
532if(typeof(M)=="Ideal"){
533  setring(M.over);
534  m=M.gens;
535}
536if(typeof(M)=="Module"){
537  setring(M.over);
538    module gens=M.generators.hom;
539    module rels=M.relations.hom;
540    m=modulo(gens,rels);
541}
542int j=0;
543if(size(#)!=0){j=#;}
544list mydeg;
545Resolution R;
546R.reso=sres(m,j);
547matrix a=R.reso[1];
548R.dd[1]=makeMatrix(a);
549if(!(R.dd[1].ishomogeneous)){
550  R.isgraded=0;
551  for(int i=2;i<(size(R.reso)+1);i++){
552    a=R.reso[i];
553    R.dd[i]=nongradedMatrix(a);
554  }
555
556}
557else{
558  R.isgraded=1;
559  for(int i=2;i<(size(R.reso));i++){
560    a=R.reso[i];
561    mydeg=R.dd[i-1].source.grading;
562    R.dd[i]=resMatrix(a,mydeg,R.dd[i-1].source);
563  }
564}
565R.over=basering;
566setring(S);
567return(R);
568}
569
570example
571{
572 "EXAMPLE:"; echo=2;
573 ring r;
574 matrix m[1][3]=x,y,z;
575 Matrix M=m;
576 Module N=coker(M);
577 N;
578 Resolution R = sRes(N);
579 R;
580 R.dd[2];
581}
582
583////////////////////////////////////////////////////////////////////////////////////////////////////////////////
584
585proc Res(def M,int #)
586"USAGE: Res(M,n); M Module or Ideal, n integer
587RETURN: Resolution, resolution with graded modules
588NOTE: n is optional, if n ist positiv only that many steps will be computed
589      use R.dd[i]; to return the different modules as image of matrices, R Resolution i integer
590EXAMPLE. example Res, shows an example"
591{
592module m;
593def S =basering;
594if(typeof(M)=="Ideal"){
595  setring(M.over);
596  m=M.gens;
597}
598if(typeof(M)=="Module"){
599  setring(M.over);
600    module gens=M.generators.hom;
601    module rels=M.relations.hom;
602    m=modulo(gens,rels);
603}
604int j=0;
605if(size(#)!=0){j=#;}
606list mydeg;
607Resolution R;
608R.reso=res(m,j);
609matrix a=R.reso[1];
610R.dd[1]=makeMatrix(a);
611if(!(R.dd[1].ishomogeneous)){
612  R.isgraded=0;
613  for(int i=2;i<(size(R.reso)+1);i++){
614    a=R.reso[i];
615    R.dd[i]=nongradedMatrix(a);
616  }
617
618}
619else{
620  R.isgraded=1;
621  for(int i=2;i<(size(R.reso));i++){
622    a=R.reso[i];
623    mydeg=R.dd[i-1].source.grading;
624    R.dd[i]=resMatrix(a,mydeg,R.dd[i-1].source);
625  }
626}
627R.over=basering;
628setring(S);
629return(R);
630}
631example
632{
633 "EXAMPLE:"; echo=2;
634 ring r;
635 matrix m[1][3]=x,y,z;
636 Matrix M=m;
637 Module N=coker(M);
638 N;
639 Resolution R = Res(N);
640 R;
641 R.dd[2];
642}
643
644////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
645
646proc Betti(Resolution resi)
647"USAGE: Betti(reso); reso Resolution
648RETURN: intmat, Bettimatrix of the resolution
649NOTE: for a clear overview use printBetti
650EXAMPLE: example Betti, shows an example"
651{
652Matrix M;
653int j;
654list l;
655int i=size(resi.dd);
656M=resi.dd[i];
657for(j=1;j<=size(M.source.grading);j++){
658    l[M.source.grading[j]-i+1]=0;
659  }
660intmat Bet[size(l)][size(resi.dd)+1];
661for(j=1;j<=size(M.source.grading);j++){
662    Bet[M.source.grading[j]-i+1,i+1]=Bet[M.source.grading[j]-i+1,i+1]+1;
663  }
664for(i=1;i<=size(resi.dd);i++){
665  M=resi.dd[i];
666  for(j=1;j<=size(M.target.grading);j++){
667    Bet[M.target.grading[j]-i+2,i]=Bet[M.target.grading[j]-i+2,i]+1;
668  }
669}
670return(Bet);
671}
672example
673{
674"EXAMPLE:"; echo=2;
675 ring r;
676 matrix m[1][3]=x,y,z;
677 Matrix M=m;
678 Module N=coker(M);
679 Resolution R=mRes(N);
680 R;
681 Betti(R);
682}
683
684////////////////////////////////////////////////////////////////////////////////////
685
686proc printBetti(Resolution resi)
687"USAGE: printBetti(resi), resi Resolution
688RETURN: nothing, prints the Bettimatrix of the Resolution
689EXAMPLE: example printBetti, shows an example"
690{
691print(Betti(resi),"betti");
692}
693example
694{
695"EXAMPLE:"; echo=2;
696 ring r;
697 matrix m[1][3]=x,y,z;
698 Matrix M=m;
699 Module N=coker(M);
700 Resolution R=mRes(N);
701 R;
702 printBetti(R);
703}
704example
705{
706"EXAMPLE:"; echo=2;
707 ring r;
708 matrix m[1][3]=x,y,z;
709 Matrix M=m;
710 Module N=coker(M);
711 Resolution R=mRes(N);
712 R;
713 Betti(R);
714}
715
716
717///////////////////////////////////////////////////////////////////////////////////////
718
719proc makeMatrix(matrix m, int #)
720"USAGE:makeMatrix(m), m matrix
721RETURN Matrix, with graded source and target if the matrix is homogeneous
722EXAMPLE: example makeMatrix, shows an example"
723{
724Matrix M;
725list mydeg=isHomogenous(m);
726if(mydeg[1]==-1 || # == 1){
727  return(nongradedMatrix(m));
728}
729return(gradedMatrix(m,mydeg));
730}
731
732example
733{
734"EXAMPLE:"; echo=2;
735 ring r;
736 matrix m[2][2]=x,y3,z,xz;
737 m;
738 Matrix M=m;
739}
740
741
742//////////////////////////////////////////////////////////////////////////////////////////
743
744static proc nongradedMatrix(matrix m){
745Matrix M;
746M.ishomogeneous=0;
747M.over=basering;
748M.target = freeModule(basering,nrows(m),-1);
749M.source = freeModule(basering,ncols(m),-1);
750M.hom = m;
751return(M);
752}
753
754///////////////////////////////////////////////////////////////////////////////////////////
755
756proc Target(Matrix M)
757"USAGE: Target(M); M Matrix
758RETURN: FreeModule, target of the Matrix
759EXAMPLE: example Target, shows an example"
760{
761return(M.target);
762}
763
764example
765{
766"EXAMPLE:"; echo=2;
767 ring r;
768 matrix m[2][2]=x,y3,z,xz;
769 Matrix M=m;
770 M;
771 Target(M);
772}
773
774///////////////////////////////////////////////////////////////////////////////////////////
775
776proc Source(Matrix M)
777"USAGE: Source(M); M Matrix
778RETURN: FreeModule, source of the Matrix
779EXAMPLE: example Source, shows an example"
780{
781return(M.source);
782}
783
784example
785{
786"EXAMPLE:"; echo=2;
787 ring r;
788 matrix m[2][2]=x,y3,z,xz;
789 Matrix M=m;
790 M;
791 Source(M);
792}
793
794///////////////////////////////////////////////////////////////////////////////////////////
795
796proc Degree(FreeModule M)
797"USAGE: Degree(M); M FreeModule
798RETURN: list, degrees of the generators from the module, if they are graded
799EXAMPLE: example Degree, shows an example"
800{
801if(M.isgraded){
802 return(M.grading);
803}
804print("The module isn't graded");
805}
806
807example
808{
809"EXAMPLE:"; echo=2;
810 ring r;
811 matrix m[2][2]=x,y3,z,xz;
812 Matrix Ma=m;
813 FreeModule M=Source(Ma);
814 M;
815 Degree(M);
816}
817
818///////////////////////////////////////////////////////////////////////////////////////////
819
820
821proc printMatrix(Matrix M)
822"USAGE: printMatrix(M); or M; M Matrix
823RETURN: nothing, prints the matrix with degrees of the generators from target and source
824EXAMPLE: example printMatrix, shows an example"
825{
826def R=basering;
827setring(M.over);
828matrix m=M.hom;
829if(M.ishomogeneous){
830  string s1;
831  string s2;
832  list l1;
833  int j;
834  for(int i=1;i<=ncols(m);i++){
835    l1[i]=0;
836    for(j=1;j<=nrows(m);j++){
837      if(size(string(m[i][j]))>l1[i]){
838        l1[i]=size(string(m[i][j]));
839      }
840    }
841  }
842  s1="   ";
843  for(i=1;i<=ncols(m);i++){
844    for(j=1;j<=(l1[i]);j++){
845      s1=s1+" ";
846    }
847    s1=s1+"{"+string(M.source.grading[i])+"}";
848  }
849  print(s1);
850  for(int k=1;k<=nrows(m);k++){
851    s2="{"+string(M.target.grading[k])+"}";
852      for(i=1;i<=ncols(m);i++){
853        for(j=1;j<=(l1[i]+3-size(string(m[i][k])));j++){
854          s2=s2+" ";
855        }
856        s2=s2+string(m[i][k]);
857      }
858  print(s2);
859  }
860
861}
862else{print(m);}
863setring(R);
864}
865
866example
867{
868"EXAMPLE:"; echo=2;
869 ring r;
870 matrix m[2][2]=x,y3,z,xz;
871 Matrix M=m;
872 M;
873}
874
875///////////////////////////////////////////////////////////////////////////////////////////////////
876
877static proc compareRing(def r, def t){
878list a=ring_list(r);
879list b=ring_list(t);
880if(!(a[1]==b[1])){return(0);}
881for(int i=1;i<=size(a[2]);i++){
882  if(a[2][i]!=b[2][i]){return(0);}
883}
884if(a[3][1][1]!=b[3][1][1]){return(0);}
885if(a[3][1][2]!=b[3][1][2]){return(0);}
886if(a[3][2][1]!=b[3][2][1]){return(0);}
887if(a[3][2][2]!=b[3][2][2]){return(0);}
888ideal I = std(a[4]);
889ideal J = std(b[4]);
890if(size(I)!=size(J)){
891  return(0);
892}
893for(int j  = 1;i<=size(I); i++){
894  if(I[i]!=J[i]){
895    return(0);
896  }
897}
898return(1);
899}
900
901////////////////////////////////////////////////////////////////////////////////////////////////////////
902
903static proc compareFreeModules(FreeModule M, FreeModule N){
904if(!(compareRing(M.over,N.over)))
905{
906return(0);}
907if(M.Rank!=N.Rank){
908return(0);}
909return(1);
910}
911
912////////////////////////////////////////////////////////////////////////////////////////////////////////
913
914proc subquotient(Matrix gens, Matrix rels)
915"USAGE: subquotient(gens,rels); gens and rels Matrices
916RETURN: Module, the subquotient of two entered Matrices
917EXAMPLE: example suquotient; shows an example"
918{
919ring R=basering;
920setring(gens.over);
921Module S;
922S.isgraded=0;
923if(gens.ishomogeneous){
924S.grading=gens.source.grading;
925S.isgraded=1;
926}
927if(!(gens.target==rels.target)){
928setring(R);
929ERROR("the two matrices don't have the same target");
930}
931S.generators = gens;
932S.relations = rels;
933S.over = gens.over;
934setring(R);
935return(S);
936}
937
938example
939{
940 "EXAMPLE:"; echo=2;
941 ring r;
942 matrix m[2][2]=x,y2,z,xz;
943 Matrix M=m;
944 matrix n[2][3]=z2,xyz,x2y2,xy,x3,y4;
945 Matrix N=n;
946 M;
947 N;
948 subquotient(M,N);
949}
950
951/////////////////////////////////////////////////////////////////////////////////////////////////////////////
952
953proc homomorphism(matrix rules,Module sources, Module targets)
954"USAGE: homomorphism(rules,sources,targets); rules a matrix, sources and targets are Modules
955Return: Homomorphism
956EXAMPLE: example homomorphism; shows an example"
957{
958ring S=basering;
959setring(sources.over);
960module d=targets.relations.hom;
961module b=rules*sources.relations.hom;
962d=std(d);
963for(int i=1;i<=size(b);i++){
964  if(reduce(b[i],d)!=0){
965    ERROR("The given homomorphism between the two modules isn't possible");}
966}
967Homomorphism H;
968H.source=sources;
969H.target=targets;
970H.rule=rules;
971H.over=sources.over;
972setring(S);
973return(H);
974}
975
976example
977{
978 "EXAMPLE:"; echo=2;
979 ring R=0,(x,y),(lp,c);
980 Matrix M=id(2);
981 Module src=image(M);
982 matrix rules[2][2]=x,y,x2,y2;
983 Module tar=coker(M);
984 src;
985 tar;
986 rules;
987 homomorphism(rules,src,tar);
988}
989
990///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
991
992proc coker(Matrix rels)
993"USAGE:coker(M), M a Matrix
994RETURN:Module, the coker of M
995EXAMPLE: example coker; shows an example"
996{
997int i;
998int n = nrows(rels.hom);
999matrix new = rels.hom;
1000//Delete Zerocolumns in relations:
1001for (i=2;i<ncols(new);i++) {
1002  if ([new[1..n,i]]==0) {
1003    new = deleteCol(new,i);
1004  }
1005}
1006Module M;
1007if(rels.ishomogeneous){M.isgraded=1;}
1008else{M.isgraded=0;}
1009Matrix New = new;
1010M=subquotient(id(nrows(new)),New);
1011return(M);
1012}
1013
1014example
1015{
1016 "EXAMPLE:"; echo=2;
1017 ring r;
1018 matrix m[2][2]=x,y2,z,xz;
1019 Matrix M=m;
1020 M;
1021 coker(M);
1022}
1023
1024/////////////////////////////////////////////////////////////////////////////////////////////////
1025
1026
1027proc image(Matrix gens)
1028"USAGE:image(M); M a Matrix
1029RETURN: Module, the image of M
1030EXAMPLE: example image; shows an example"
1031{
1032Module M;
1033M=subquotient(gens,zero(nrows(gens.hom),1));
1034return(M);
1035}
1036
1037example
1038{
1039 "EXAMPLE:"; echo=2;
1040 ring r;
1041 matrix m[2][2]=x,y2,z,xz;
1042 Matrix M=m;
1043 M;
1044 image(M);
1045}
1046
1047/////////////////////////////////////////////////////////////////////////////////////
1048
1049proc Ker(Matrix mat)
1050"USAGE: Ker(M); M a Matrix
1051RETURN: Module, image of a Matrix N with image(N)=Ker(M)
1052EXAMPLE: example Ker; shows an example"
1053{
1054matrix m=syz(mat.hom);
1055if (mat.source.isgraded){
1056  Matrix M=resMatrix(m,mat.source.grading,mat.source);
1057}else{
1058  Matrix M = makeMatrix(m,1);
1059}
1060return(image(M));
1061}
1062
1063example
1064{
1065 "EXAMPLE:"; echo=2;
1066 ring r;
1067 matrix m[1][3]=x,y2,z3;
1068 Matrix M=m;
1069 M;
1070 Ker(M);
1071}
1072
1073///////////////////////////////////////////////////////////////////////////////////////////////////////
1074
1075static proc isZero(matrix M)
1076{
1077int n=nrows(M);
1078int m=ncols(M);
1079Matrix Z=zero(n,m);
1080return(M==Z.hom);
1081}
1082
1083/////////////////////////////////////////////////////////////////////////////////////////////////////
1084
1085static proc isIdentity(matrix M)
1086{
1087int n=ncols(M);
1088Matrix Z=id(n);
1089return(M==Z.hom);
1090}
1091
1092///////////////////////////////////////////////////////////////////////////////////////////////////////
1093
1094static proc nameOver(Module M){
1095def R= basering;
1096setring(M.over);
1097string n = nameof(basering);
1098setring R;
1099return(n);}
1100
1101///////////////////////////////////////////////////////////////////////////////////////////////////
1102
1103proc netModule(Module M)
1104{
1105def R=basering;
1106setring(M.over);
1107matrix rels = M.relations.hom;
1108matrix gens = M.generators.hom;
1109int zerorel=isZero(rels);
1110int idgens=isIdentity(gens);
1111Net ret,ret2,ret3,ret4;
1112if (zerorel) {
1113   if (idgens){
1114     ret=net(nameOver(M))+net("^")+net(nrows(gens));
1115     ret2=net(", free");
1116   } else {
1117     typeof(gens);
1118     ret=net("image ")+net(gens);
1119     ret2=net(", submodule of ")+net(nameof(basering))+net("^")+net((nrows(rels)));
1120   }
1121}
1122if ((!zerorel)&&idgens) {
1123   ret=net("cokernel ")+net(rels);
1124   ret2=net(", quotient of ")+net(nameof(basering))+net("^")+net((nrows(rels)));
1125}
1126if ((!idgens)&&(!zerorel)) {
1127   ret=net("subquotient (")+net(gens)+net(", ")+net(rels)+net(")");
1128   ret2=net(", subquotient of ")+net(nameof(basering))+net("^")+net((nrows(rels)));
1129}
1130
1131if (M.isgraded == 1){
1132  ret3 = net("Graded with:") + net(M.grading);
1133}
1134
1135//interpretationlist:
1136
1137if (size(M.interpretation)==0){ret4 = net("The Interpretationmap is the Identity.");}
1138else {
1139  ret4 = netList(M.interpretation[1]);
1140  ret4.rows = (net("Interpretation:")).rows + ret4.rows;
1141  if (size(M.interpretation[2])!=0) {
1142    ret4.rows = ret4.rows + (net("inverse Interpretation:")).rows + (net(M.interpretation[2])).rows;
1143  }
1144}
1145
1146
1147Net output = ret+ret2;
1148output.rows = output.rows + ret3.rows + ret4.rows;
1149
1150setring(R);
1151return(output);
1152}
1153
1154
1155///////////////////////////////////////////////////////////////////////////////////////////////////////////
1156
1157static proc present(Module M)
1158{
1159  def R=basering;
1160  setring(M.over);
1161  int n=ncols(M.generators.hom);
1162  matrix MM;
1163  if (isZero(M.relations.hom)){
1164     MM=M.generators.hom;
1165  } else {
1166     MM=concat(M.generators.hom,M.relations.hom);
1167  }
1168  matrix K = syz(MM);
1169  K=submat(K,1..n, 1..ncols(K));
1170  Matrix L=K;
1171  Module cc = coker(L);
1172  setring R;
1173  return(cc);
1174}
1175
1176//////////////////////////////////////////////////////////////////////////////////////////
1177
1178static proc minimize(Module M)
1179{
1180  def R=basering;
1181  setring(M.over);
1182  Module MM = present(M);
1183  module Mold = MM.relations.hom;
1184  matrix gM = pruneModule(Mold);
1185  Module cc=coker(gM);
1186  setring R;
1187  return(cc);
1188}
1189
1190/////////////////////////////////////////////////////////////////////////////////////////////
1191
1192
1193proc printHom(Homomorphism f)
1194"USAGE:printHom(M); f a Homomorphism
1195RETURN: nothing, prints f
1196EXAMPLE: example printHom; shows an example"
1197{
1198ring R=basering;
1199setring(f.over);
1200print(net(f.rule));
1201print("");
1202print(netModuleShort(f.target)+net(" <--- ")+netModuleShort(f.source));
1203setring R;
1204}
1205
1206example
1207{
1208 "EXAMPLE:"; echo=2;
1209 ring R=0,(x,y),(lp,c);
1210 Matrix M=id(2);
1211 Module src=image(M);
1212 matrix rules[2][2]=x,y,x2,y2;
1213 Module tar=coker(M);
1214 src;
1215 tar;
1216 rules;
1217 Homomorphism f=homomorphism(rules,src,tar);
1218 f;
1219}
1220
1221
1222//////////////////////////////////////////////////////////////////////////////////////////////////
1223
1224proc target(Homomorphism f)
1225"USAGE:target(f); f Homomorphism
1226RETURN: Module, the target of f
1227EXAMPLE: example target; shows an example"
1228{
1229 return(f.target);
1230}
1231
1232example
1233{
1234 "EXAMPLE:"; echo=2;
1235 ring R=0,(x,y),(lp,c);
1236 Matrix M=id(2);
1237 Module src=image(M);
1238 matrix rules[2][2]=x,y,x2,y2;
1239 Module tar=coker(M);
1240 src;
1241 tar;
1242 rules;
1243 Homomorphism f=homomorphism(rules,src,tar);
1244 f;
1245 target(f);
1246}
1247
1248////////////////////////////////////////////////////////////////////////////////////////////////
1249
1250proc source(Homomorphism f)
1251"USAGE:source(f); f Homomorphism
1252RETURN: Module, the source of f
1253EXAMPLE: example source; shows an example"
1254{
1255 return(f.source);
1256}
1257
1258example
1259{
1260 "EXAMPLE:"; echo=2;
1261 ring R=0,(x,y),(lp,c);
1262 Matrix M=id(2);
1263 Module src=image(M);
1264 matrix rules[2][2]=x,y,x2,y2;
1265 Module tar=coker(M);
1266 src;
1267 tar;
1268 rules;
1269 Homomorphism f=homomorphism(rules,src,tar);
1270 f;
1271 source(f);
1272}
1273
1274///////////////////////////////////////////////////////////////////////////////////////////////////
1275
1276static proc kerHom_old(Homomorphism f)
1277"USAGE:kerHom_old(f); f Homomorphism
1278RETURN: Module, the kernel of f
1279EXAMPLE: example kerHom_old; shows an example"
1280{
1281Module T=f.target;
1282ring R=basering;
1283setring(T.over);
1284Module NN=present(f.target);
1285Module MM=present(f.source);
1286module N=NN.relations.hom;
1287module M=MM.relations.hom;
1288matrix A=f.rule;
1289matrix K=hom_kernel(A,M,N);
1290Matrix KER=K;
1291Module KE=coker(KER);
1292setring R;
1293return(KE);
1294}
1295
1296example
1297{
1298 "EXAMPLE:"; echo=2;
1299 ring R=0,(x,y),(lp,c);
1300 Matrix M=id(2);
1301 Module src=image(M);
1302 matrix rules[2][2]=x,y,xy,y2;
1303 Module tar=coker(M);
1304 Homomorphism f=homomorphism(rules,src,tar);
1305 f;
1306 kerHom_old(f);
1307}
1308
1309/////////////////////////////////////////////////////////////////////////////////////////////////////////////
1310
1311proc addModules(Module M, Module N)
1312"USAGE: addModules(M,N); or M+N; M and N Modules
1313RETURN: Module, sum of the two Modules
1314EXAMPLE: example addModules; shows an example"
1315{
1316  def R=basering;
1317  setring(M.over);
1318  if (!((image(M.relations))==(image(N.relations)))){ERROR("expected submodules of the same module")};
1319  Module MN;
1320  MN.over = basering;
1321  matrix gens = concat(M.generators.hom,N.generators.hom);
1322  MN.generators = makeMatrix(gens);
1323  MN.relations = N.relations;
1324  //MN=minimize(MN);
1325  setring R;
1326  return(MN);
1327}
1328
1329example
1330{
1331 "EXAMPLE:"; echo=2;
1332 ring r;
1333 matrix ma[2][2]=x,y,x2,y2;
1334 Matrix m=ma;
1335 Module M=image(m);
1336 matrix na[2][2]=xy,x2,y2,x;
1337 Matrix n=na;
1338 Module N=image(na);
1339 M;
1340 N;
1341 N+M;
1342}
1343
1344////////////////////////////////////////////////////////////////////////////////////////////////////////////
1345
1346proc compareModules(Module M, Module N)
1347"USAGE:compareModules(M,N); or M==N; compares two Modules up to isomorphism
1348RETURN: 1 or 0, if the are ismomophic or aren't
1349EXAMPLE: example compareModules; shows an example"
1350{
1351  def R=basering;
1352  setring(M.over);
1353 int re =1;
1354if(M.isgraded!=N.isgraded){re=0;}
1355if(M.isgraded){
1356  if(size(M.grading)!=size(N.grading)){re=0;}
1357  for(int i=1;i<=size(M.grading);i++){
1358    if(M.grading[i]!=N.grading[i]){re=0;}
1359  }
1360}
1361module gensm=M.generators.hom;
1362module relsm=M.relations.hom;
1363matrix m=modulo(gensm,relsm);
1364module gensn=N.generators.hom;
1365module relsn=N.relations.hom;
1366matrix n=modulo(gensn,relsn);
1367  if (m!=n){re=0;};
1368  setring R;
1369  return(re);
1370}
1371
1372example
1373{
1374 "EXAMPLE:"; echo=2;
1375 ring r;
1376 matrix ma[2][2]=x,y,x,y;
1377 Matrix m=ma;
1378 Module M=image(m);
1379 matrix na[2][1]=-y,x;
1380 Matrix n=na;
1381 M;
1382 Module N=image(n);
1383 N;
1384 N==M;
1385 N=coker(n);
1386 N;
1387 N==M;
1388}
1389
1390/////////////////////////////////////////////////////////////////////////////////////////////////////////
1391
1392proc Degrees(Module M)
1393"USAGE:Degrees(M); M a Module
1394RETURN: list, grading of the Module
1395EXAMPLE: example Degrees; shows an example"
1396{
1397def R=basering;
1398setring(M.over);
1399if(M.isgraded){
1400return(M.grading);
1401}else{
1402Error("The Module isn't graded.");
1403}
1404setring R;
1405}
1406
1407example
1408{
1409 "EXAMPLE:"; echo=2;
1410 ring r;
1411 matrix ma[2][2]=x,y,x,y;
1412 Matrix m=ma;
1413 Module M=image(m);
1414 M;
1415 Degrees(M);
1416}
1417
1418////////////////////////////////////////////////////////////////////////////////////////////////////////
1419
1420proc compareMatrix(Matrix M, Matrix N)
1421"USAGE:compareMatrix(M,N); or M==N; compares two Matrices
1422RETURN: 1 or 0, if the are the same or aren't
1423EXAMPLE: example compareMatrix; shows an example"
1424{
1425return(M.hom==N.hom);
1426}
1427
1428example
1429{
1430 "EXAMPLE:"; echo=2;
1431 ring r;
1432 matrix ma[2][2]=x,y,x,y;
1433 Matrix M=ma;
1434 matrix na[2][1]=-y,x;
1435 Matrix N=na;
1436 M;
1437 N;
1438 N==M;
1439 M==M;
1440}
1441
1442
1443////////////////////////////////////////////////////////////////////////////////////////////////////////
1444
1445//Eigene Funktionen
1446
1447////////////////////////////////////////////////////////////////////////////////////////////////////////
1448
1449
1450proc printModule(Module M)
1451"USAGE: printModule(M); or M; M a Module
1452RETURN: nothing, prints the Module
1453EXAMPLE: example printModule; shows an example
1454{
1455  netModuleShort(M);
1456}
1457example
1458{
1459 "EXAMPLE:"; echo=2;
1460 ring r;
1461 matrix m[2][2]=x,y2,z,xz;
1462 Matrix M=m;
1463 M;
1464 Module N=image(M);
1465 N;
1466}
1467
1468
1469static proc netModuleShort(Module M)
1470{
1471  def R=basering;
1472  setring(M.over);
1473  matrix rels = M.relations.hom;
1474  matrix gens = M.generators.hom;
1475  int zerorel=isZero(rels);
1476  int idgens=isIdentity(gens);
1477  Net ret;
1478  if (zerorel) {
1479     if (idgens){
1480       ret=net(nameOver(M))+net("^")+net(nrows(gens));
1481     } else {
1482       ret=net("image ")+net(gens);
1483     }
1484  }
1485  if ((!zerorel)&&idgens) {
1486     ret=net("cokernel ")+net(rels);
1487  }
1488  if ((!idgens)&&(!zerorel)) {
1489     ret=net("subquotient (")+net(gens)+net(", ")+net(rels)+net(")");
1490  }
1491  setring(R);
1492  return(ret);
1493}
1494
1495
1496static proc netHom(Homomorphism f) {
1497  return(net(f.rule));
1498}
1499
1500
1501////////////////////////////////////////////////////////////////////////////////////////////////////////
1502
1503
1504proc freeModule2Module(FreeModule F)
1505"USAGE: freeModule2Module(F); F FreeModule
1506RETURN: returns F as a Module
1507EXAMPLE: example freeModule2Module, shows an example"
1508{
1509Module M = image (id(F.Rank));
1510M.isgraded = F.isgraded;
1511M.grading = F.grading;
1512return(M);
1513}
1514example
1515{
1516 "EXAMPLE:"; echo=2;
1517 ring r;
1518 list L = 1,1,1;
1519 FreeModule F = freeModule(r,3,L);
1520 freeModule2Module(F);
1521}
1522
1523
1524////////////////////////////////////////////////////////////////////////////////////////////////////////
1525
1526
1527proc netMatrix(Matrix M)
1528"USAGE = netMatrix(M); M Matrix
1529RETURN: nothing, prints M
1530KEYWORDS: Output
1531EXAMPLE: example netMatrix; shows an example"
1532{
1533Net N = netmatrix(M.hom); /*
1534N;
1535print("");
1536print("From source");
1537printFreeModule(M.source);
1538print("");
1539print("to target");
1540printFreeModule(M.target);
1541print("");
1542print("Ring:");
1543M.over;*/
1544return(N);
1545}
1546example
1547{
1548 "EXAMPLE:"; echo=2;
1549 ring r;
1550 matrix m[2][2]=x,y2,z,xz;
1551 Matrix M=m;
1552 netMatrix(M);
1553}
1554
1555////////////////////////////////////////////////////////////////////////////////////////////////////////
1556//////////////////////////////////    Vector related functions   ///////////////////////////////////////
1557////////////////////////////////////////////////////////////////////////////////////////////////////////
1558
1559
1560proc makeVector(vector v, Module M)
1561"USAGE = makeVector(v,M); vector v, Module M
1562RETURN: a Vector V, element of M with entries v
1563EXAMPLE: example makeVector; shows an example"
1564{
1565  //assure that v has the right size:
1566  if (nrows(v)>nrows(M.generators.hom)){ERROR("The Element has too many entries");}
1567  //assure that V is in M:
1568  list DivVec = division(v,M.generators.hom);
1569  if ((DivVec[2])[1] != 0) {ERROR("The vector isn't in the Module");}
1570
1571  Vector V;
1572  V.space = M;
1573  V.entries = v;
1574  return(V);
1575}
1576example
1577{
1578 "EXAMPLE:"; echo=2;
1579 ring r;
1580 Module M = image(id(3));
1581 makeVector([x,y,z],M);
1582}
1583
1584
1585proc netVector(Vector V)
1586"USAGE: netVector(V); V Vector
1587RETURN: pretty print for Vector
1588EXAMPLE: example netVector; shows an example"
1589{
1590  int i = nrows(V.space.generators.hom);
1591  matrix ents[i][1] = V.entries;
1592  Net ret = net(ents);
1593  return(ret);
1594}
1595example
1596{
1597 "EXAMPLE:"; echo=2;
1598 ring r;
1599 Module M = image(id(3));
1600 Vector V = makeVector([x,y,z],M);
1601 netVector(V);
1602}
1603
1604static proc printVector(Vector V) {
1605  net(V);
1606}
1607
1608proc compareVectors(Vector V1, Vector V2)
1609"USAGE: compareVector(V1,V2); Vector V1,V2
1610RETURN: compares the given Vectors up tu equivalence
1611EXAMPLE: example compareVector; shows an example"
1612{
1613  if (V1.space == V2.space){
1614    int n = nrows(((V1.space).generators).hom);
1615    matrix vecDiff[n][1] = V1.entries-V2.entries;
1616    list divList = division(vecDiff,V1.space.relations.hom);
1617    if (divList[2][1] == 0){return(1);} else {return(0);}
1618  }else{return(0);}
1619}
1620example
1621{
1622 "EXAMPLE:"; echo=2;
1623 ring r;
1624 matrix m[2][1] = x,-y;
1625 Module M = subquotient(id(2),m);
1626 Vector V = [x,y],M;
1627 Vector W = [0,2y],M;
1628 Vector U = [x,y2],M;
1629 compareVectors(V,W);
1630 compareVectors(U,V);
1631}
1632
1633
1634////////////////////////////////////////////////////////////////////////////////////////////////////////
1635////////////////////////////////////   Presentation of Module    ///////////////////////////////////////
1636////////////////////////////////////////////////////////////////////////////////////////////////////////
1637
1638
1639proc presentation(Module M)
1640"USAGE = presentation(M); M Module
1641RETURN: Subquotient M converted to coker(C)
1642EXAMPLE: example presentation; shows an example"
1643{
1644  //TODO Grading
1645matrix A = M.generators.hom;
1646// If M is already given as a cokernel, don't change anything:
1647if (M.generators == id(M.generators.source.Rank)){
1648  return(M);
1649}
1650matrix B = M.relations.hom;
1651int n = nrows(A);
1652int m = ncols(A) + ncols(B);
1653matrix ab[n][m] = A,B;
1654Matrix AB = ab;
1655Module Kern = Ker(AB);
1656matrix c = Kern.generators.hom;
1657n = ncols(A);
1658m = ncols(c);
1659matrix helpmat[n][m] = c[1..n,1..m];
1660Matrix C = helpmat;
1661Module N = coker(C);
1662int i;
1663list L = list(),list();
1664for (i=1;i<=ncols(A);i++) {
1665  (L)[1][i] = makeVector([A[1..nrows(A),i]],M);
1666}
1667matrix gens = N.generators.hom;
1668for (i=1;i<=ncols(gens);i++){
1669  (L)[2][i] = [gens[1..nrows(gens),i]];
1670}
1671N.interpretation = L;
1672return(N);
1673}
1674
1675example
1676{
1677 "EXAMPLE:"; echo=2;
1678 ring R = 0,(x,y),dp;
1679 matrix a[1][2] = x,y;
1680 Matrix A = a;
1681 matrix b[1][2] = x2,y2;
1682 Matrix B = b;
1683 Module M = subquotient(A,B);
1684 presentation(M);
1685}
1686
1687
1688////////////////////////////////////////////////////////////////////////////////////////////////////////
1689////////////////////////////////////       Tensor products       ///////////////////////////////////////
1690////////////////////////////////////////////////////////////////////////////////////////////////////////
1691
1692
1693proc tensorMatrix(Matrix A, Matrix B)
1694"USAGE = tensorMatrix(A,B); A,B Matrix over the same ring
1695RETURN: Tensorprodukt of A,B
1696EXAMPLE: example tensorMatrix; shows an example"
1697{
1698if (A.over != B.over) {
1699  ERROR("A and B don't work over the same ring")
1700}
1701int i;
1702int j;
1703Matrix T = tensor(A.hom,B.hom);
1704list source_grading;  //TODO Grading
1705list target_grading;
1706list betweenSafe = B.source.grading; //english for Runaways
1707if (A.source.isgraded==0 || B.source.isgraded==0) {
1708  source_grading = -1;
1709}else{
1710  /*If both Matrices have dimension 1x1, we only need to add the degrees. Especially if both gradings are zero.*/
1711  if (size(A.source.grading)==1 && size(B.source.grading)==1) {
1712    source_grading = A.source.grading[1]+B.source.grading[1];
1713  }else{
1714    for (i=1;i<=A.source.Rank;i++) {
1715      for (j=1;j<=B.source.Rank;j++) {
1716        source_grading = source_grading + list(betweenSafe[j] + A.source.grading[i]);
1717      }
1718    }
1719  }
1720}
1721T.source = freeModule(A.over,A.source.Rank*B.source.Rank,source_grading);
1722if (A.target.isgraded==0 || B.target.isgraded==0) {
1723  target_grading = -1;
1724}else{
1725  target_grading = 0; //vorlaeufig
1726}
1727T.target = freeModule(A.over,A.target.Rank*B.target.Rank,target_grading);
1728return(T);
1729}
1730
1731example
1732{
1733"EXAMPLE:"; echo=2;
1734ring r;
1735matrix m[2][2]=x,y2,z,xz;
1736matrix n[2][2]=1,2,3,4;
1737Matrix M = m;
1738Matrix N = n;
1739tensorMatrix(M,N);
1740}
1741
1742
1743////////////////////////////////////////////////////////////////////////////////////////////////////////
1744
1745
1746proc tensorModule(Module M, Module N)
1747"USAGE = tensorModule(M,N); M,N Modules over the same ring
1748RETURN: Tensorprodukt of M,N
1749EXAMPLE: example tensorModule; shows an example"
1750{
1751//TODO Grading
1752if (M.over != N.over) {
1753  ERROR("The modules don't live over the same ring");
1754}
1755Module M2 = presentation(M);
1756Module N2 = presentation(N);
1757Matrix Tensormatrix1 = tensorMatrix(N2.generators, M2.relations);
1758Matrix Tensormatrix2 = tensorMatrix(N2.relations, M2.generators);
1759Matrix Tensormatrix = concMatrix(Tensormatrix1,Tensormatrix2);
1760Module T = coker(Tensormatrix);
1761return(T);
1762}
1763
1764example
1765{
1766"EXAMPLE:"; echo=2;
1767ring R = 0,(x,y,z),dp;
1768matrix a[1][2] = x,y;
1769Matrix A = a;
1770matrix b[1][2] = x2,y2;
1771Matrix B = b;
1772Module M = subquotient(A,B);
1773M;
1774matrix c[2][2]=x,y2,z,xz;
1775Matrix C=c;
1776matrix d[2][3]=z2,xyz,x2y2,xy,x3,y4;
1777Matrix D=d;
1778Module N = subquotient(C,D);
1779N;
1780tensorModule(M,N);
1781}
1782
1783
1784////////////////////////////////////////////////////////////////////////////////////////////////////////
1785
1786
1787proc tensorModFreemod(Module M, FreeModule F)
1788"USAGE = tensorModFreemod(M,F); M Module,F FreeModule over the same ring
1789RETURN: Tensorprodukt of M,F
1790EXAMPLE: example tensorModFreemod; shows an example"
1791{
1792//TODO Grading
1793if (M.over != F.over) {
1794  ERROR("The modules don't live over the same ring");
1795}
1796Module M2 = presentation(M);
1797Matrix Tensormatrix = tensorMatrix(M2.relations, id(F.Rank));
1798Module T = coker(Tensormatrix);
1799return(T);
1800}
1801
1802example
1803{
1804"EXAMPLE:"; echo=2;
1805ring R = 0,(x,y,z),dp;
1806matrix a[1][2] = x,y;
1807Matrix A = a;
1808matrix b[1][2] = x2,y2;
1809Matrix B = b;
1810Module M = subquotient(A,B);
1811M;
1812FreeModule F = freeModule(R,3,0);
1813F;
1814tensorModFreemod(M,F);
1815}
1816
1817
1818////////////////////////////////////////////////////////////////////////////////////////////////////////
1819
1820
1821proc tensorFreemodMod(FreeModule F, Module M) //Dreht input um
1822{
1823if (M.over != F.over) {
1824  ERROR("The modules don't live over the same ring");
1825}
1826Module T = tensorModFreemod(M,F);
1827return(T);
1828}
1829
1830
1831////////////////////////////////////////////////////////////////////////////////////////////////////////
1832
1833
1834proc tensorFreeModule(FreeModule M, FreeModule N)
1835"USAGE = tensorFreeModule(M,N); M,N FreeModule over the same ring
1836RETURN: Tensorprodukt of M,N
1837EXAMPLE: example tensorFreeModule; shows an example"
1838{
1839if (M.over != N.over) {
1840  ERROR("The modules don't live over the same ring");
1841}
1842FreeModule T = freeModule(M.over,M.Rank*N.Rank,-1); //vorlaeufig ohne grading   //TODO Grading
1843return(T);
1844}
1845
1846example
1847{
1848"EXAMPLE:"; echo=2;
1849ring R = 0,(x,y,z),dp;
1850FreeModule F = freeModule(R,3,0);
1851F;
1852tensorFreeModule(F,F);
1853}
1854
1855
1856
1857
1858////////////////////////////////////////////////////////////////////////////////////////////////////////
1859///////////////////////////////////        Pruning maps       //////////////////////////////////////////
1860////////////////////////////////////////////////////////////////////////////////////////////////////////
1861
1862
1863proc pruneModule(Module M)
1864"USAGE = pruneModule(M); M Module
1865RETURN: M in a simplyfied presentation
1866EXAMPLE: example pruneModule; shows an example"
1867{
1868        ring s = basering;
1869        Module P = presentation(M);
1870        Matrix Rels = P.relations;
1871        //R HIR: calculate Hermite-NF
1872        ring r = Rels.over;
1873        if (charstr(r)=="ZZ"){
1874                matrix new = hermiteNormalForm(Rels.hom);
1875                P.relations = new;
1876                return(P);
1877        }
1878        //run prunefunctions
1879        Rels = pruneModule1(Rels);
1880        Rels = pruneModule2(Rels);
1881        P.relations = Rels;
1882        //adjust pruningmap:
1883        //while dimension changes, use adjust pruning-map
1884        int dimension = nrows(P.generators.hom);
1885        P = simplePrune(P);
1886        while (dimension != nrows(P.generators.hom)){
1887          dimension--;
1888          P = simplePrune(P);
1889                P = reduceIntChain(P);
1890        }
1891        //compute GB of relations:
1892        Rels = P.relations;
1893        Rels = pruneModule1(Rels);
1894        P.relations = Rels;
1895        setring(s);
1896        return(P);
1897}
1898
1899example
1900{
1901"EXAMPLE:"; echo=2;
1902ring R = 0,(x,y,z),dp;
1903matrix a[2][3] = -x,-y^2,x^3,y,x,0;
1904matrix b[1][2] = x^2-y^3,xy;
1905Matrix A = a;
1906Matrix B = b;
1907Module M = coker(A);
1908Module N = coker(B);
1909Module H = hom(M,N);
1910H;
1911pruneModule(H);
1912}
1913
1914
1915
1916////////////////////////////////////////////////////////////////////////////////////////////////////////
1917
1918
1919static proc pruneModule1(Matrix M) {
1920  matrix gens = std(M.hom);
1921/*  if (homog(gens)==1) {
1922    matrix gens = minbase(M.hom);
1923  }*/
1924  Matrix Gens = gens;
1925  return(Gens);
1926}
1927
1928
1929////////////////////////////////////////////////////////////////////////////////////////////////////////
1930
1931
1932static proc pruneModule2(Matrix M) {
1933  matrix m = M.hom;
1934  poly factor;
1935  poly pivot;
1936  int i,j,k,l;
1937  int rows = nrows(m);
1938  int cols = ncols(m);
1939  for (i=1;i<=rows;i++) {
1940    for (j=1;j<=cols;j++) {
1941      if (isUnit(m[i,j])) {
1942      //if the entry is a unit, it's Pivot element
1943        pivot = m[i,j];
1944        if (pivot!=1) {for(k=1;k<=rows;k++) { m[k,j] = m[k,j]/pivot; }}
1945        //dividing Pivot col with Pivot element
1946        //Now add multiples of Pivot column to the other columns to make the row to zero:
1947        for(k=1;k<=cols;k++) {
1948          if (k!=j) {
1949          factor = -m[i,k];
1950          m[1..rows,k] = m[1..rows,k] + factor*m[1..rows,j];
1951          }//change all columns except pivot column
1952        }
1953      }
1954    }
1955  }
1956  Matrix Mat = m;
1957  return (Mat);
1958}
1959
1960
1961////////////////////////////////////////////////////////////////////////////////////////////////////////
1962
1963
1964proc simplePrune(Module M)
1965"USAGE = simplePrune(M); M Module
1966RETURN: Simplyfied Module with reduced dimension
1967EXAMPLE: example simplePrune; shows an example"
1968/*
1969Whenever the relations of a presented Module include a 1-entry, we can reduce the dimension of the Module by representing the relevant variable. This allows us, to 'forget' this row after killing all the other row entries to 0. Therefore, we can reduce the dimension of the Module by 1 without losing any information.
1970*/
1971{
1972  //TODO Grading
1973//M must be presented as a cokernel
1974  matrix rels = M.relations.hom;
1975  int abbruch = 0;
1976  int i,j;
1977  while (i<nrows(rels) && abbruch==0) {
1978    i++;
1979    for (j=1;j<=ncols(rels);j++) {
1980      if (rels[i,j] == 1) {abbruch=1;break;}
1981    }
1982  }
1983  if (abbruch==0){return(M);} //no 1 found
1984  //Have now indices (i,j) of a 1-entry
1985  Module N;
1986  N.over = M.over;
1987  if (ncols(rels)>1){
1988    matrix newrels[ncols(rels)][nrows(rels)-1] = deleteCol(transpose(rels),i);
1989    matrix needthislater = transpose(newrels);
1990    newrels = deleteCol(needthislater,j);
1991    Matrix Newrels = newrels;
1992  }else{
1993    Matrix Newrels = zero(nrows(rels)-1,1);
1994    matrix needthislater = Newrels.hom;
1995  }
1996  N.relations = Newrels;
1997  int rows = nrows(M.generators.hom)-1;
1998  N.generators = id(rows);
1999  N.interpretation = list(list(),list());
2000  //Need to insert 0 in the i-th row which is for the identitymatrix equivalent to deleting the i-th column:
2001  matrix m[rows+1][rows] = deleteCol(id(rows+1).hom,i);
2002  int k;
2003  list interpr;
2004  Vector V;
2005  for (k=1;k<=rows;k++) {
2006    V = makeVector([m[1..(rows+1),k]],M);
2007    interpr[k] = V;
2008  }
2009  N.interpretation[1] = interpr;
2010  //Now construct the inverse map: 'forget' the i-th row and send the i-th unitvector to the according negative relations.
2011  list preinterpr;
2012  vector v;
2013  matrix n[rows][rows];
2014  n = n+1;
2015  for (k=1;k<=rows+1;k++) {
2016    if (k!=i) {
2017      if (k<i) {
2018        v = [n[1..rows,k]];
2019        preinterpr[k] = v;
2020      }else{
2021        v = [n[1..rows,k-1]];
2022        preinterpr[k] = v;
2023      }
2024    }else{
2025      v = [(-1)*needthislater[1..rows,j]];
2026      preinterpr[k] = v;
2027    }
2028  }
2029  N.interpretation[2] = preinterpr;
2030  return(N);
2031}
2032example
2033{
2034"EXAMPLE:"; echo=2;
2035ring R;
2036matrix a[5][4];
2037Module M = coker(a+1);
2038Module N = simplePrune(M);
2039}
2040
2041
2042////////////////////////////////////////////////////////////////////////////////////////////////////////
2043
2044
2045static proc isUnit(poly p) {
2046  if (deg(p)!=0){ return (0); }
2047  int i = int(p);
2048  if (char(basering) != 0) {
2049    if (gcd(char(basering),i) == 1){ return(1); }
2050    else{ return(0); }
2051  }else{
2052    if (charstr(basering) == "ZZ" && absValue(i) != 1){ return(0); }
2053    else{ return(1); }
2054  }
2055}
2056
2057
2058////////////////////////////////////////////////////////////////////////////////////////////////////////
2059///////////////////////////////////  Interpretation functions //////////////////////////////////////////
2060////////////////////////////////////////////////////////////////////////////////////////////////////////
2061
2062
2063proc interpretElem(Vector Elmt, int #)
2064"USAGE = interpretElem(V,n); Vector Elmt, n integer
2065RETURN: interpretation of a Vector with # steps or until can't interpret further
2066EXAMPLE: example interpretElem; shows an example"
2067{
2068  if (# == 0){#=-1;}  //if we want to interpret as far as possible
2069  while (# != 0 && size(Elmt.space.interpretation) != 0){
2070    Elmt = interpret(Elmt);
2071    # = # - 1;
2072  }
2073  return(Elmt);
2074}
2075example
2076{
2077"EXAMPLE:"; echo=2;
2078ring R;
2079matrix a[5][4];
2080Module M = coker(a+1);
2081Module N = simplePrune(simplePrune(simplePrune(simplePrune(M))));
2082Vector V = [x+y],N;
2083interpretElem(V,3);
2084}
2085
2086
2087////////////////////////////////////////////////////////////////////////////////////////////////////////
2088
2089
2090proc interpretList(list Elements, int #)
2091"USAGE = interpretList(L,n); list L of Vectors all of the same Module, n integer
2092RETURN: interpretation of Elements in some abstract structure defined by the user or into a Module
2093EXAMPLE: example interpretList; shows an example"
2094{
2095  Vector Cache;
2096  Module C = (Elements[1]).space;
2097  C = reduceIntChain(C,#);
2098  int i;
2099  list newEls;
2100  for (i=1;i<=size(Elements);i++) {
2101    Cache = makeVector((Elements[i]).entries,C);
2102    newEls = newEls + list(interpret(Cache));
2103  }
2104  return(newEls);
2105}
2106example
2107{
2108"EXAMPLE:"; echo=2;
2109ring R;
2110matrix a[5][4];
2111Module M = coker(a+1);
2112Module N = simplePrune(simplePrune(simplePrune(simplePrune(M))));
2113Vector V = [x+y],N;
2114Vector W = [x2+y2+3*z2],N;
2115Vector U = [x+2y+27z],N;
2116list L = U,V,W;
2117//interpretList(L,3);
2118}
2119
2120
2121////////////////////////////////////////////////////////////////////////////////////////////////////////
2122
2123
2124proc reduceIntChain(Module C, int #)
2125"USAGE = reduceIntChain(C,n); C Module, n int
2126RETURN: Module C with minimized (or # steps) interpretation list
2127EXAMPLE: example reduceIntChain; shows an example"
2128{
2129Module M;
2130list preList;
2131Vector V;
2132Vector cacheVec;
2133list intList;
2134  if (size(C.interpretation) != 0) {  // either there is no interpretation list or at least the "interpret direction" exists
2135    int i;
2136    if (#==0){#=-1;}
2137    while ((typeof((C.interpretation)[1][1])=="Vector") && (#<>0))
2138    {
2139      if (size(((C.interpretation)[1][1]).space.interpretation)==0){break;}
2140      // M is in each iteration step precisely the module, which will be cut out of the chain
2141      M = ((C.interpretation)[1][1]).space;
2142      // First construct the concatenation of the inverse maps
2143      preList = list();
2144      if (size(C.interpretation[2]) != 0 && size(M.interpretation[2]) != 0){
2145        for (i=1; i<=size((M.interpretation)[2]);i++){
2146          V = makeVector(((M.interpretation)[2])[i],M);
2147          cacheVec = interpretInv(V,C);
2148          preList[i] = cacheVec.entries;
2149        }
2150      }
2151      (C.interpretation)[2] = preList;
2152      // Second concatenate the interpretation maps
2153      for(i=1;i<=size((C.interpretation)[1]);i++) {
2154        intList[i] = interpret((C.interpretation)[1][i]);
2155      }
2156      C.interpretation[1] = intList;
2157      intList = list();
2158      # = #-1;
2159    }
2160  }
2161  return(C);
2162}
2163
2164example
2165{
2166"EXAMPLE:"; echo=2;
2167ring R;
2168matrix a[5][4];
2169Module M = coker(a+1);
2170Module N = simplePrune(simplePrune(simplePrune(simplePrune(M))));
2171//reduceIntChain(N);
2172}
2173
2174
2175////////////////////////////////////////////////////////////////////////////////////////////////////////
2176
2177
2178proc interpret(Vector V)
2179"USAGE = interpret(V); V Vector
2180RETURN: interpretation of V into some space that is stored in the interpretationlist of V.space
2181EXAMPLE: example interpret; shows an example"
2182{
2183int i;
2184  if (size(V.space.interpretation) == 0) {return(V);}
2185  //nothing to interpret
2186
2187  if (V.space.generators == id(ncols(V.space.generators.hom))) {
2188    def W = V.space.interpretation[1][1];
2189    W = V.space.interpretation[1][1]*V.entries[1];
2190    for (i=2;i<=nrows(V.entries);i++) {
2191      W = W + V.space.interpretation[1][i]*V.entries[i];
2192    }
2193    return(W);
2194  }//Have cokernel-presentation in this case
2195
2196  //general case:
2197  list DivVec = division(V.entries,V.space.generators.hom);
2198  matrix myCoeffs = DivVec[1];
2199  def W = V.space.interpretation[1][1]*myCoeffs[1,1]; //user needs to define '*' in advance
2200  for (i=2;i<=nrows(myCoeffs);i++) {
2201    W = W + V.space.interpretation[1][i]*myCoeffs[i,1]; //user needs to define '+' as well
2202  }
2203  return(W);
2204}
2205
2206
2207example
2208{
2209"EXAMPLE:"; echo=2;
2210"example 1:";
2211ring R = 0,(x,y),dp;
2212matrix a[1][2] = x,y;
2213Matrix A = a;
2214matrix b[1][2] = x2,y2;
2215Matrix B = b;
2216Module M = subquotient(A,B);
2217Module C = presentation(M);
2218Vector V = [x2,y4],C;
2219interpret(V);
2220
2221"example 2:";
2222ring S;
2223matrix gens[2][3] = x2+y-3z4,y+xy,xyz+4,3+z2x,z3-3x+3,2+x+y+z7;
2224vector v = 2x*[gens[1..2,1]] + (y-z2)*[gens[1..2,2]] + 5*[gens[1..2,3]];
2225Matrix Gens = gens;
2226M = subquotient(Gens,zero(2,3));
2227M.interpretation = list(list(1,1,1),list());
2228V = v,M;
2229interpret(V);
2230}
2231
2232
2233////////////////////////////////////////////////////////////////////////////////////////////////////////
2234
2235
2236proc interpretInv(def V, Module N)
2237"USAGE = interpretInv(V,N); V Vector or Homomorphism, N Module
2238RETURN: interpretation of V into some Module N (inverse to interpret)
2239EXAMPLE: example interpretInv; shows an example"
2240{
2241  if (typeof(V)=="Vector"){
2242    Module M = V.space;
2243    //Check whether there is a inverse interpretationlist:
2244    if ((size(N.interpretation)!=0) && (size((N.interpretation)[2])!=0) && (((N.interpretation)[1][1]).space == M)) {
2245    // third condition checks whether the given modules are related
2246      //in this case we decompose v into the generators of its Module and project those onto the generators of N
2247      list DivVec = division(V.entries,M.generators.hom);
2248      matrix myCoeffs = DivVec[1];
2249      vector w = N.interpretation[2][1]*myCoeffs[1,1];
2250      //inverse maps only contain elements of type vector
2251      int i;
2252      for (i=2;i<=nrows(myCoeffs);i++) {
2253        w = w + N.interpretation[2][i]*myCoeffs[i,1];
2254      }
2255      Vector W = w,N;
2256      return(W);
2257    }
2258    //If not, check whether there exists an interpretationlist to N in the Module of V:
2259    if ((size(M.interpretation)!=0) && (((M.interpretation)[1][1]).space == N)){return(interpret(V));}
2260    //If neither exist, can't interpretInv:
2261    ERROR("There exists no inverse map into the given module");
2262  }
2263  if (typeof(V)=="Homomorphism"){
2264    //generators of Hom are the tensors of the canonical basevectors
2265    matrix cache = V.rule;
2266    int n = nrows(cache);
2267    int m = ncols(cache);
2268    int i,j;
2269    vector ret_bar;
2270    if (size(N.interpretation)==0){ERROR("There exists no inverse map into the given module");}
2271    if (size(N.interpretation[2])!=n*m){ERROR("Homomorphism has wrong dimension");}
2272    list int_inv = N.interpretation[2];
2273    for (i=1;i<=n;i++){
2274      for(j=1;j<=m;j++){
2275        ret_bar = ret_bar + cache[i,j]*int_inv[(j-1)*n+i];
2276      }
2277    }
2278    Vector ret = ret_bar,N;
2279    return(ret);
2280  }
2281  else {ERROR("Can't interpret object of the given type into the Module");}
2282}
2283
2284example
2285{
2286"EXAMPLE:"; echo=2;
2287ring R;
2288matrix gens[2][3] = x2,xy,4,z2x,3x+3,z;
2289vector v = 2x*[gens[1..2,1]] + (y-z2)*[gens[1..2,2]] + 5*[gens[1..2,3]];
2290Matrix Gens = gens;
2291Module S = subquotient(Gens,zero(2,3));
2292Module N = coker(id(3));
2293matrix E = N.generators.hom;
2294Vector E1 = [1,0,0],N;
2295Vector E2 = [0,1,0],N;
2296Vector E3 = [0,0,1],N;
2297S.interpretation = list(list(E1,E2,E3),list([gens[1..2,1]],[gens[1..2,2]],[gens[1..2,3]]));
2298Vector V = v,S;
2299Vector W = interpret(V),N;
2300net(V);
2301Vector Vnew = interpretInv(W,S);
2302net(Vnew);
2303V==Vnew;
2304}
2305
2306
2307
2308////////////////////////////////////////////////////////////////////////////////////////////////////////
2309///////////////////////////////////      compute Hom(M,N)     //////////////////////////////////////////
2310////////////////////////////////////////////////////////////////////////////////////////////////////////
2311
2312
2313proc hom(Module M, Module N)
2314"USAGE = hom(M,N); M,N Module
2315RETURN: calculates Hom(M,N) as a subquotient and yields an interpretation for the elements
2316EXAMPLE: example hom; shows an example"
2317{
2318  //TODO Grading
2319  N = presentation(N);
2320  M = presentation(M);
2321  Matrix T = tensorMatrix(transMat(M.relations.hom),N.generators);
2322  Module Targ = coker(tensorMatrix(id(ncols(M.relations.hom)),N.relations));
2323  Module Sour = coker(tensorMatrix(id(nrows(M.relations.hom)),N.relations));
2324  Homomorphism h = homomorphism(T.hom,Sour,Targ);
2325  Module H = kerHom(h);
2326  //interpretationlist:
2327  list interpretation = list(),list();
2328  //Need to write the generators of H as matrices:
2329  int m = nrows(M.relations.hom);
2330  int n = nrows(N.relations.hom);
2331  int i,j;
2332  matrix mat[n][m];
2333  mat = transpose(mat);
2334  matrix H_gens = H.generators.hom;
2335  Homomorphism interpr_hom;
2336  for (i=1;i<=ncols(H_gens);i++) {
2337    mat = H_gens[1..nrows(H_gens),i];
2338    interpr_hom = homomorphism(transpose(mat),M,N);
2339    interpretation[1] = interpretation[1] + list(interpr_hom);
2340    mat = 0;
2341  }
2342  H.interpretation = interpretation;
2343  return(H);
2344}
2345example
2346{
2347"Example:"; echo=2;
2348ring R = 0,(x,y,z),dp;
2349matrix a[2][3] = -x,-y^2,x^3,y,x,0;
2350matrix b[1][2] = x^2-y^3,xy;
2351Matrix A = a;
2352Matrix B = b;
2353Module M = coker(A);
2354Module N = coker(B);
2355hom(M,N);
2356}
2357
2358
2359////////////////////////////////////////////////////////////////////////////////////////////////////////
2360
2361
2362proc kerHom(Homomorphism H)
2363"USAGE = kerHom(H); H Homomorphism
2364RETURN: returns the kernel of the given homomorphism
2365EXAMPLE: example kerHom; shows an example"
2366{
2367  Matrix B = H.rule;
2368  Matrix A = H.target.relations;
2369  Matrix C = concMatrix(A,B);
2370  matrix s = syz(C.hom);
2371  int s_rows = nrows(s);
2372  int s_cols = ncols(s);
2373  int A_cols = ncols(A.hom);
2374  matrix k = submat(s,A_cols+1..s_rows,1..s_cols);
2375  Module Kernel = subquotient(k,H.source.relations);
2376  return(Kernel);
2377}
2378example
2379{
2380ring R=0,(x,y),(lp,c);
2381 Matrix M=id(2);
2382 Module src=image(M);
2383 matrix rules[2][2]=x,y,xy,y2;
2384 Module tar=coker(M);
2385 Homomorphism f=homomorphism(rules,src,tar);
2386 f;
2387 kerHom(f);
2388}
2389
2390
2391////////////////////////////////////////////////////////////////////////////////////////////////////////
2392///////////////////////////////////    Auxiliary functions    //////////////////////////////////////////
2393////////////////////////////////////////////////////////////////////////////////////////////////////////
2394
2395
2396static proc concMatrix(Matrix A,Matrix B)
2397"USAGE = concMatrix(A,B); A,B Matrix over the same ring
2398RETURN: concatenated Matrix with concatenated grading
2399EXAMPLE: example concMatrix; shows an example"
2400{
2401  //TODO Grading
2402if (A.over != B.over) {
2403  ERROR("The matrices don't live over the same ring");
2404}
2405Matrix M;
2406int i = ncols(A.hom);
2407int j = ncols(B.hom);
2408int k = nrows(A.hom);
2409if (nrows(A.hom) != nrows(B.hom)){ERROR("Wrong Dimension")};
2410matrix m[k][i+j] = concat(A.hom,B.hom);
2411M.hom = m;
2412list grading = concatGrading(A.source,B.source);
2413M.source = freeModule(A.over,ncols(A.hom)+ncols(B.hom),grading);
2414M.target = A.target; //vorlaeufig
2415M.over = A.over;
2416return(M);
2417}
2418
2419example
2420{
2421"EXAMPLE:"; echo=2;
2422ring R;
2423matrix a[2][2] = x,x2,2x,3x2;
2424Matrix A = a;
2425Matrix B = a;
2426B.source.grading = list(2,3);
2427concMatrix(A,B);
2428}
2429
2430
2431static proc concatGrading(FreeModule F1, FreeModule F2){
2432  list L1 = F1.grading;
2433  list L2 = F2.grading;
2434
2435  if (F1.isgraded == 0 || F2.isgraded == 0){
2436    return(-1);
2437  }
2438  return(L1+L2);
2439}
2440
2441
2442////////////////////////////////////////////////////////////////////////////////////////////////////////
2443
2444
2445static proc transMat(Matrix M){
2446  matrix m = transpose(M.hom);
2447  M = m;
2448  return(M);
2449}
2450
2451
2452////////////////////////////////////////////////////////////////////////////////////////////////////////
2453
2454
2455static proc addHomomorphism(Homomorphism h1, Homomorphism h2){
2456  if (target(h1) == target(h2) && source(h1) == source(h2)){
2457  Homomorphism H = homomorphism(h1.rule + h2.rule, h1.source, h2.target);
2458  return (H);
2459  }else{
2460  ERROR("Cannot add those homomorphisms!");generators of hom(M,N)
2461  }
2462}
2463
2464
2465static proc scaleHomomorphism(def P, def H){
2466  if (typeof(H) == "Homomorphism"){
2467    if (typeof(P) == "poly"){
2468      H.rule = H.rule*P;
2469    }
2470    return(H)
2471  }
2472  if (typeof(P) == "Homomorphism"){
2473    if (typeof(H) == "poly"){
2474      P.rule = P.rule*H;
2475    }
2476    return(P)
2477  }
2478  return(H*P);
2479}
2480
2481
2482////////////////////////////////////////////////////////////////////////////////////////////////////////
2483
2484
2485static proc multVecPoly(def V, def P) {
2486if (typeof(V) == "Vector"){
2487  if (typeof(P) == "poly"){
2488    V.entries = V.entries*P;
2489  }
2490  return(V)
2491}
2492if (typeof(P) == "Vector"){
2493  if (typeof(V) == "poly"){
2494    P.entries = P.entries*V;
2495  }
2496  return(P)
2497}
2498return(V*P);
2499}
2500
2501
2502static proc addVector(Vector V, Vector W) {
2503  int i;
2504  if ((V.space==W.space)==0) {ERROR("The Vectors aren't in the same Module");}
2505  vector sum = V.entries + W.entries;
2506  Vector Sum = makeVector(sum,V.space);
2507  return(Sum);
2508}
2509
2510
2511
2512////////////////////////////////////////////////////////////////////////////////////////////////////////
2513
2514
2515static proc deleteCol(matrix mat, int i) {
2516  int n = nrows(mat);
2517  int m = ncols(mat);
2518  if (i<1 || i>m) {return(mat);}
2519  if (n == 1) {matrix a[n][1]; return (a)}  //if there is only one column, we could return the nx0 matrix but for the use of this function it is easier to set it to the zero matrix
2520  if (i==1) {
2521    matrix new[n][m-1] = mat[1..n,2..m];
2522    return(new);
2523  }
2524  if (i==m) {
2525    matrix new[n][m-1] = mat[1..n,1..m-1];
2526    return(new);
2527  }
2528  matrix thing1[n][i-1] = mat[1..n,1..i-1];
2529  matrix thing2[n][m-i] = mat[1..n,i+1..m];
2530  matrix new[n][m-1] = concat(thing1,thing2);
2531  return(new);
2532}
2533
2534
2535////////////////////////////////////////////////////////////////////////////////////////////////////////
2536
2537
2538static proc convertMat2Vec(matrix A, Module M)
2539"USAGE = convertMat2Vectors(M); A matrix s.th. the columns of A are in M, M Module
2540RETURN: list of columns as Vectors in M"
2541{
2542  list ret;
2543  vector v;
2544  int i;
2545  int rows = nrows(A);
2546  for (i=1;i<=ncols(A);i++){
2547    v = [A[1..rows,i]];
2548    ret = ret + list(makeVector(v,M));
2549  }
2550  return(ret);
2551}
2552
2553
Note: See TracBrowser for help on using the repository browser.