Baer和を計算する関数

２つの拡大
0 -> B -> E0 -> A -> 0
0 -> B -> E1 -> A -> 0
のBaer和を計算する．
拡大の情報はext = {torA, torB, torE, imf, img} で与える．
 ここで，torA, torB, torEはそれぞれZ加群A,B,Eのねじれ群の情報を与える．0はZとする．
 例えば{0,0,4,2}はZ+Z+Z4+Z2である．
 imfは f: B->E の行列表示を，imgは g: E-> Aの行列表示．

BaerSum[ext0_,ext1_]:=If[ext0[[1;;2]]≠ext1[[1;;2]],Print["A and B are not in common."],
Module[{torE0E1,imf,img,Mg,Mf,u,Λ,v,torE,pos1,imfp,imgp,torA,torB,torE0,torE1,imf0,imf1,img0,img1},
{torA,torB}=ext0[[1;;2]];
{torE0,imf0,img0}=ext0[[3;;5]];
{torE1,imf1,img1}=ext1[[3;;5]];
torE0E1=Join[torE0,torE1];
imf=ArrayFlatten[{{imf0,-imf1}}];
img=Join[img0,-img1];
Mg(*ker g*)=MyLatticeReduce[LatticeNullSpace[(Join[img,DiagonalMatrix[torA]])\[Transpose]][[All,;;Length[torE0E1]]]];
Mf(*im f*)=Join[imf,DiagonalMatrix[torE0E1]];
Mf.PseudoInverse[Mg];
{u,Λ,v}=SmithDecomposition[Mf.PseudoInverse[Mg]];
torE=Abs[Diagonal[Λ]];
pos1(*\kerg/imfの，(Subscript[Z, 1])なる群の基底番号*)=Position[Diagonal[Λ],1];
imfp=ArrayFlatten[{{imf0,Table[0,{i,Length[torB]},{j,Length[torE1]}]}}].PseudoInverse[Mg].v;
imgp=(Inverse[v].Mg)[[All,;;Length[torE0]]].img0;
torE=Delete[#,pos1]&[torE];
imfp=Delete[#,pos1]&/@imfp;
(*imfp=Table[Table[If[torE[[i]]≠0,Mod[x[[i]],torE[[i]]],x[[i]]],{i,Length[x]}],{x,imfp}];*)
imgp=Delete[#,pos1]&[imgp];
(*imgp=Table[Table[If[torA[[i]]≠0,Mod[x[[i]],torA[[i]]],x[[i]]],{i,Length[x]}],{x,imgp}];*)
If[Norm[Table[Table[If[torA[[i]]≠0,Mod[x[[i]],torA[[i]]],x[[i]]],{i,Length[x]}],{x,imfp.imgp}]]>0,Print["Error"];];
Return[{torA,torB,torE,imfp,imgp}];
];
];

(*例：*)
ext0={{4},{2,0},{0,2,2},{{2,1,0},{0,0,1}},{{1},{2},{0}}};
ext1={{4},{2,0},{0,8},{{1,0},{0,4}},{{0},{1}}};
BaerSum[ext0,ext1]