ClearAll[fullBasisIndex0or3,fullBasisIndex1or2,fullBasisTotal, characteristic,  monodromyBasisIndex0or3, m0, imagesOfElements, monodromyBasisIndex0or3,  monodromyBasisTotal, centralBasisIndex0or3,  centralBasisTotal,a1, a2, a3, a4, aD, aU4, aU8, b1, b2, b3, cD, cU4, b4, bD, bU4, bU8, obstruction0, obstruction1, repConstructor, repTest, repeat, centralBasisIndex0or3Test, monodromyBasisIndex0or3Test, monodromyBasisIndex1or2Test, repTest, m0Test];

Linear Algebra

(*matrix operations and converting into matrices  ====================================================*)
e[i_,j_, m_, n_]:=Table[If[k==i && l==j,1,0], {k, 1,m },{l,1,n}]; (*basis for matrices*)

conjugate[X_, Y_, char_]:=If[char==0,Inverse[Y].X.Y, Mod[Inverse[Y, Modulus->char].X.Y,char]]; (*this definition of conjugate is made to apply the left representation of Gamma_Delta and hence a right representation of Pi1(L_Delta)*)



matrixify[operator_, domainbasis_, targetbasis_, char_]:=Module[{A=Transpose[Table[Flatten[targetbasis[[i]]], {i, 1, Length[targetbasis]}]]},
If[char==0, Transpose[Table[LinearSolve[A, Flatten[operator[domainbasis[[i]]]]], {i, 1, Length[domainbasis]}]],Transpose[Table[LinearSolve[A, Flatten[operator[domainbasis[[i]]]], Modulus->char], {i, 1, Length[domainbasis]}]]]];

(*extracts a maximal linearly independent sublist of the given list*)
maxLinIndepSublist[list_List, char_]:=Module[{elementsOfListAsColumns = Transpose[Table[Flatten[list[[i]]], {i, 1, Length[list]}]], reduced, pivotingColumns},
reduced = RowReduce[elementsOfListAsColumns, Modulus->char];
pivotingColumns = Flatten[Table[FirstPosition[reduced[[i]], x_ /; x≠0, ##&[]], {i, 1, Dimensions[reduced][[1]]}]];
list[[pivotingColumns]]]

commutatorOperator[A_,B_, char_]:=If[char==0, A.B - B.A, Mod[A.B-B.A, char]];
(*given a basis for a space V of m by m matrices, construct a basis for V^power. basisPower returns a list of power-tuples of matrices which spans the space of power-tuples of matrices*)
basisPower[m_, basis_, power_]:=If[power==1, basis, Flatten[Table[If[ k==i,basis[[j]], e[0,0, m, m]], {i, 1, power},{j,1,Length[basis]},{k, 1, power}], 1]];
(*basisPowertest=basisPower[1, 1, {{{1}}}, 1]
basisPowertest = basisPower[2, {{{1, 0}, {0, 0}}, {{0, 1}, {0, 0}}, {{0, 0}, {1, 0}}, {{0, 0}, {0, 1}}}, 2]
Table[MatrixForm /@ basisPowertest[[i]], {i, 1, Length[basisPowertest]}]*)

(*test for matrixification------------------------------------------------------------------------------*)
(*testDomainBasis = Flatten[Table[e[i, j, 2, 2], {i, 1, 2}, {j, 1, 2}], 1]
testTargetBasis ={ {{1,0},{0, 1}},{{0, 1},{1,0}}}
testOperator[M_] := Module[{vectM = Flatten[M]}, 
{{vectM .Flatten[e[1,1,2,2]] + vectM .Flatten[e[2,2,2,2]], vectM .Flatten[e[1,2,2,2]] + vectM .Flatten[e[2,1,2,2]]},{vectM .Flatten[e[1,2,2,2]] + vectM .Flatten[e[2,1,2,2]],
vectM .Flatten[e[1,1,2,2]] + vectM .Flatten[e[2,2,2,2]]}}]
matrixify[testOperator[#]&, testDomainBasis, testTargetBasis] //MatrixForm
matrixify[testOperator[#]&, testDomainBasis, testTargetBasis, 0] //MatrixForm*)

(*end of test--------------------------------------------------------------------------------------------*)

========================================The Chiang Lagrangian============================================================

Defining the Morse differentials

(*==============================================DEFINING MORSE DIFFERENTIALS=====================================================================*)

(*Morse differential from Aprime to (A1prime, A2prime, A3prime)*)d01[Aprime_, a_, b_, char_] := If[char==0,{-Aprime + conjugate[Aprime,b, char], +Aprime - conjugate[Aprime,a.b, char], -Aprime + conjugate[Aprime,a.a.b, char]}, Mod[{-Aprime + conjugate[Aprime,b, char], Aprime - conjugate[Aprime,a.b, char], -Aprime + conjugate[Aprime,a.a.b, char]}, char]];

(*Morse differential from (A1prime, A2prime, A3prime) to (A1, A2, A3)*)
d12[{A1prime_, A2prime_, A3prime_}, a_, b_, char_] := If[char==0,{A1prime + A2prime + conjugate[A2prime,a,char]+ conjugate[A3prime, a, char], conjugate[A1prime,a.a.b, char] +A2prime + conjugate[A3prime,a, char]  + A3prime, conjugate[A1prime,a.a.b, char] + conjugate[A1prime,a.a.a.b, char] + conjugate[A2prime,a.a.a.b, char] + A3prime }, 
Mod[{A1prime + A2prime + conjugate[A2prime,a,char]+ conjugate[A3prime, a, char], conjugate[A1prime,a.a.b, char] +A2prime + conjugate[A3prime,a, char]  + A3prime, conjugate[A1prime,a.a.b, char] + conjugate[A1prime,a.a.a.b, char] + conjugate[A2prime,a.a.a.b, char] + A3prime }, char]];

(*Morse differential from (A1, A2, A3) to A*)d23[{A1_, A2_, A3_}, a_, b_, char_]:= If[char==0, -A1+A2-A3 + conjugate[A1,a.a.a.b, char] - conjugate[A2,a.a.a.a.b, char] + conjugate[A3,a.a.a.a.a.b, char],
Mod[-A1+A2-A3 + conjugate[A1,a.a.a.b, char] - conjugate[A2,a.a.a.a.b, char] + conjugate[A3,a.a.a.a.a.b, char], char]];

Defining the Floer Differentials and the Obstruction

(*======================================FlOER DIFFERENTIAL======================================================================*)

(*Floer Differential from (Aprime, A1, A2, A3) to (A1prime, A2prime, A3prime, A)------------------------------------------------------------*)
dF0[{Aprime_, A1_, A2_, A3_}, a_, b_, char_]:=Module[{mLoc},
mLoc = Dimensions[a][[1]];
 If[char==0,{-a.a.b.A1 + A1.a.a.a.a.b + a.a.b.A2 - a.a.a.a.a.A2.a.a.a.a.a.b,
-a.a.b.A2 + A2.b + a.a.a.b.A3.a - A3.b,
-a.a.a.a.b.A3 + A3.b + a.A1.a.a.a.b - a.a.a.a.a.b.A1.a.a.a.a.a,
e[0, 0, mLoc,mLoc]}+
{-Aprime+conjugate[Aprime, b, char], 
+Aprime -conjugate[Aprime, a.b, char],
-Aprime + conjugate[Aprime, a.a.b, char],
-A1 + conjugate[A1, a.a.a.b, char] + A2 - conjugate[A2, a.a.a.a.b, char] - A3 + conjugate[A3, a.a.a.a.a.b, char]},

Mod[{a.a.b.A1 - A1.a.a.a.a.b - a.a.b.A2 + a.a.a.a.a.A2.a.a.a.a.a.b,
a.a.b.A2 - A2.b - a.a.a.b.A3.a + A3.b,
a.a.a.a.b.A3 - A3.b - a.A1.a.a.a.b + a.a.a.a.a.b.A1.a.a.a.a.a,
e[0, 0, mLoc, mLoc]}+
{-Aprime+conjugate[Aprime, b, char], 
Aprime - conjugate[Aprime, a.b, char],
-Aprime + conjugate[Aprime, a.a.b, char],
-A1 + conjugate[A1, a.a.a.b, char] + A2 - conjugate[A2, a.a.a.a.b, char] - A3 + conjugate[A3, a.a.a.a.a.b, char]}, char]]];

(*Floer Differential from (A1prime, A2prime, A3prime, A) to (Aprime, A1, A2, A3)--------------------------------------------------------------------------*)

dF1[{A1prime_, A2prime_, A3prime_, A_}, a_, b_, char_] := Module[{mLoc}, mLoc = Dimensions[a][[1]];If[char==0,{  b.A1prime + A2prime.a.a.a.a.b + a.a.b.A3prime -a.A -A. a.a.a.a.a,
-A.b,
-a.a.a.a.b.A,
-A.a.a.b} + 
{e[0, 0, mLoc, mLoc], 
A1prime + A2prime + conjugate[A2prime, a, char]+conjugate[A3prime, a, char],
conjugate[A1prime, a.a.b, char] + A2prime + conjugate[A3prime, a, char] + A3prime,
conjugate[A1prime, a.a.b, char] + conjugate[A1prime, a.a.a.b, char] + conjugate[A2prime, a.a.a.b, char] + A3prime },

Mod[{  b.A1prime + A2prime.Inverse[a.b, Modulus->char] + a.a.b.A3prime -a.A-A. a.a.a.a.a,
-A.b,
-a.a.a.a.b.A,
-A.a.a.b} + 
{e[0, 0, mLoc, mLoc], 
A1prime + A2prime + conjugate[A2prime, a, char]+conjugate[A3prime, a, char],
conjugate[A1prime, a.a.b, char] + A2prime + conjugate[A3prime, a, char] + A3prime,
conjugate[A1prime, a.a.b, char] + conjugate[A1prime, a.a.a.b, char] + conjugate[A2prime, a.a.a.b, char] + A3prime }, char]]]

(*the obstruction endomorphism m0 \circ alpha - \alpha \circ m0 ----------------------------------------------------------------------------------------*)
obstruction0[{Aprime_, A1_, A2_, A3_}, a_, b_, obstr_, char_] :=
If[char==0,{  (obstr.Aprime - Aprime.obstr), (obstr.A1 - A1.obstr),  (obstr.A2 - A2.obstr), (obstr.A3 - A3.obstr)},
Mod[{ ( obstr.Aprime - Aprime.obstr), ( obstr.A1 - A1.obstr), ( obstr.A2 - A2.obstr), ( obstr.A3 - A3.obstr) }, char]]

obstruction1[{A1prime_, A2prime_, A3prime_, A_}, a_, b_,obstr_,  char_] :=
If[char==0,{ (obstr.A1prime - A1prime.obstr), ( obstr.A2prime - A2prime.obstr), ( obstr.A3prime - A3prime.obstr), (obstr.A - A.obstr)},
Mod[{ (obstr.A1prime - A1prime.obstr), ( obstr.A2prime - A2prime.obstr), ( obstr.A3prime - A3prime.obstr), (obstr.A - A.obstr )}, char]]

Defining and Testing Representations of the Binary Dihedral Group

characteristic = 2;

(*a test whether something is a representation of binary dihedral - generated by the element a of order 6 and the element b of order 4*)
isARep[{dim_,a_,b_}, char_] := If[char==0, If[(a.a.a.a.a.a==IdentityMatrix[dim] ) && (a.b == b.Inverse[a])&&(b.b==a.a.a), True, False],If[(Mod[a.a.a.a.a.a,char]==IdentityMatrix[dim])  && (Mod[a.b,char] == Mod[b.Inverse[a, Modulus->char], char])&&(Mod[b.b, char]==Mod[a.a.a, char]), True, False] ] ;

(*INDECOMPOSABLE REPS OVER ZZ/2------------------------------------------------------------------------------------------------------------------*)
(*V_1 - the trivial rep:*)
a1= IdentityMatrix[1];
b1=IdentityMatrix[1];
(*V_2 - second indecomposable C4-rep *)
b2=(({{0, 1}, {1, 0}}));
(* in Jordan form *)

(*b2=(({{1, 1}, {0, 1}}));*)
a2 = Mod[b2.b2, characteristic];
(*V_3 - third indecomposable C4-rep*)
b3=(({{0, 0, 1}, {1, 0, 1}, {0, 1, 1}}));
(* in Jordan form *)
(*b3=(({{1, 1, 0}, {0, 1, 1}, {0, 0, 1}}));*)
a3 = Mod[b3.b3, characteristic];
(*V_4 - fourth indecomposable C4-rep AKA the regular C4-rep*)
b4=(({{0, 0, 0, 1}, {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}}));
(* in Jordan form *)
(*b4=(({{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 1}, {0, 0, 0, 1}}));*)
a4 = Mod[b4.b4, characteristic];
(* D - the representation of the dihedral group *)
cD = (({{0, 1}, {1, 1}}));
bD = (({{1, 1}, {0, 1}}));
aD = Mod[cD.cD.bD.bD, characteristic];
(* U4  - faithful indecomposable rep of dimension 4*)
cU4=(({{0, 1, 0, 0}, {1, 1, 0, 0}, {0, 0, 0, 1}, {0, 0, 1, 1}}));
bU4=(({{1, 1, 1, 1}, {0, 1, 0, 1}, {0, 0, 0, 1}, {0, 0, 1, 0}}));
aU4=Mod[cU4.cU4.bU4.bU4, characteristic];

listOfa = {a1, a2, a3, a4, aD, aU4};
listOfb = {b1, b2, b3, b4, bD, bU4} ;
MatrixForm /@ listOfa;
MatrixForm /@ listOfb;
Table[isARep[{Dimensions[listOfa[[i]]][[1]], listOfa[[i]], listOfb[[i]]}, characteristic], {i, 1, Length[listOfa]}]

(*the repConstructor takes a vector, specifying the multiplicities for the six indecomposable reps in the order {V1, V2, V3, V4, D, U4}
and returns a triple (dimension of composite rep, matrix for a, matrix for b) *)
repeat[m_,n_Integer]:=Sequence@@ConstantArray[m,n];
repConstructor[multiplicities_]:=Module[{useListOfa, 
useListOfb, aLoc, bLoc, mLoc },
useListOfa=  Table[repeat[listOfa[[i]], multiplicities[[i]]], {i, 1, Length[multiplicities]}];
useListOfb =Table[repeat[listOfb[[i]], multiplicities[[i]]], {i, 1, Length[multiplicities]}];
aLoc=Fold[ArrayFlatten[{{#1, 0}, {0, #2}}]&,useListOfa];
bLoc=Fold[ArrayFlatten[{{#1, 0}, {0, #2}}]&,useListOfb];
mLoc=Dimensions[aLoc][[1]];
{mLoc,aLoc, bLoc}
]

(*U8 - fathful rep of dimension 8, isomorphic to 2 copies of U4*)
(*cU8= (({{0, 1, 0, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0}, {0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 0, 1, 1}}));

bU8=(({{0, 0, 0, 0, 0, 0, 1, 1}, {0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 1, 0, 0}}));
aU8=Mod[cU8.cU8.bU8.bU8, characteristic];

(* isomorphism U8 -> U4 + U4----------------------------------------------------*)
P = (({{0, 0, 1, 0, 0, 1, 0, 1}, {0, 0, 0, 1, 1, 1, 1, 1}, {1, 0, 0, 1, 1, 0, 0, 1}, {0, 1, 1, 1, 0, 1, 1, 1}, {0, 0, 1, 1, 1, 1, 1, 0}, {0, 0, 1, 0, 1, 0, 0, 1}, {0, 1, 1, 0, 0, 1, 1, 0}, {1, 1, 0, 1, 1, 1, 0, 1}}));
{A, B} = {repConstructor[{0,0,0,0,0,2, 0}][[2]], repConstructor[{0,0,0,0,0,2, 0}][[3]]};
Mod[P.bU8- B.P, 2]//MatrixForm
Mod[P.aU8 - A.P, 2]//MatrixForm
MatrixRank[P, Modulus->2]*)

Warning: to use the repConstructor,  characteristic must be 2!
Insert a vector of multiplicities of indecomposable representations in order: {V1, V2, V3, V4, D, U4}

(*testing the repConstructor*)
(*vectorOfMultiplicitiesTest = {7, 0, 0, 0, 0,3};
repTest =repConstructor[vectorOfMultiplicitiesTest];
Dimensions[repTest[[2]]][[1]]
MatrixForm /@ repTest
isARep[repTest,characteristic]*)

Matrices in the image of the Group Ring

(*Matrices in the image of the group ring------------------------------------------------------------------------------------------------*)

imagesOfElements[a_, b_, char_] := If[char ==0, DeleteDuplicates[Table[MatrixPower[a, i].MatrixPower[b, Quotient[i, 6]],{i, 0, 11}]], DeleteDuplicates[Table[Mod[MatrixPower[a, i].MatrixPower[b, Quotient[i, 6]], char], {i, 0, 11}]]];
(*testing imagesOfElements*)(*
imagesOfElementsTest =imagesOfElements[repTest[[2]], repTest[[3]], characteristic];
basisTest = maxLinIndepSublist[imagesOfElementsTest, characteristic];
(*MatrixForm /@ imagesOfElementsTest
MatrixForm /@ basisTest*)
Length[imagesOfElementsTest]
Length[basisTest]*)

Bases For Morse Complex

(*DEFINING BASES FOR MORSE=======================================================================================================================*)
fullBasisIndex0or3[m_] := Flatten[Table[e[i, j, m, m], {i, 1, m}, {j, 1, m}], 1];
fullBasisIndex1or2[m_]:= basisPower[m, fullBasisIndex0or3[m], 3]
(*Table[MatrixForm /@ fullBasisIndex1or2[3][[i]], {i, 1, Length[fullBasisIndex1or2[3]]}]*)

monodromyBasisIndex0or3[a_, b_, char_] :=maxLinIndepSublist[imagesOfElements[a, b, char], char];
(*monodromyBasisIndex0or3Test=monodromyBasisIndex0or3[repTest[[2]], repTest[[3]], characteristic];
monodromyBasisIndex1or2Test= basisPower[repTest[[1]], monodromyBasisIndex0or3Test, 3];
(*MatrixForm /@ monodromyBasisIndex0or3Test*)
Length[monodromyBasisIndex0or3Test]
(*Table[MatrixForm /@ monodromyBasisIndex1or2Test[[i]], {i, 1, Length[monodromyBasisIndex1or2Test]}]*)
Length[monodromyBasisIndex1or2Test]*)

m0 and a basis for Central complex

(*THE OBSTRUCTION AND A BASIS FOR THE CENTRAL SUBCOMPLEX---------------------------------------------------------------------------------------*)
ClearAll[m0]
m0[a_, b_, char_] := If[char==0,a.a.a.a .b+ a.a.b + b, Mod[a.a.a.a .b+a.a.b + b, char]]
(*m0Test = m0[repTest[[2]], repTest[[3]], characteristic];
(*Print["m0 = ",MatrixForm[m0Test]]
If[MatrixRank[m0Test, Modulus->characteristic]==0, Print[Style["m0 IS 0!", 20,Green]],Print[Style["m0 IS NOT 0!", 20,Red]]] *)*)

centralBasisIndex0or3[a_, b_, m0_, char_]:=Module[{commutatorWithM0matrix, mLoc},
mLoc = Dimensions[a][[1]];
commutatorWithM0matrix = matrixify[commutatorOperator[#,m0,char]&,fullBasisIndex0or3[mLoc], fullBasisIndex0or3[mLoc], char] ;
Partition[#, mLoc]&/@ NullSpace[commutatorWithM0matrix, Modulus->char]
]


(*tests - to use, uncomment all previous tests*)
(*centralBasisIndex0or3Test = centralBasisIndex0or3[repTest[[2]], repTest[[3]], m0Test, characteristic];
centralBasisIndex0or3Test = centralBasisIndex0or3[a2, b2, m0[a2, b2, 2], 2]
centralBasisIndex1or2Test = basisPower[repTest[[1]], centralBasisIndex0or3Test, 3];
MatrixForm[#]& /@centralBasisIndex0or3Test
Length[centralBasisIndex0or3Test]
Length[maxLinIndepSublist[centralBasisIndex0or3Test, characteristic]]
Length[centralBasisIndex1or2Test]
Length[maxLinIndepSublist[centralBasisIndex1or2Test, characteristic]]*)
(*Table[MatrixForm /@ centralBasisIndex1or2Test[[i]], {i, 1, Length[centralBasisIndex1or2Test]}]*)

Bases for Floer Complex

(*BASES FOR Z/2-GRADED FLOER---------------------------------------------------------------------------------------------------------*)
fullBasisTotal[m_]:= basisPower[m, fullBasisIndex0or3[m], 4]
(*Table[MatrixForm /@ fullBasisTotal[3][[i]], {i, 1, Length[fullBasisTotal[3]]}]*)

centralBasisTotal[a_, b_,  m0_, char_] :=basisPower[Dimensions[a][[1]], centralBasisIndex0or3[a, b, m0, char], 4]
(*tests - to use uncomment all previous tests*)
(*centralBasisTotalTest = basisPower[repTest[[1]], centralBasisIndex0or3[repTest[[2]], repTest[[3]], m0Test, characteristic], 4];
Length[centralBasisTotalTest]*)

monodromyBasisTotal[a_, b_, char_]:= basisPower[Dimensions[a][[1]], monodromyBasisIndex0or3[a, b, char], 4]
(*tests - to use uncomment previous tests*)
(*monodromyBasisTotalTest = basisPower[repTest[[1]], monodromyBasisIndex0or3[repTest[[2]], repTest[[3]], characteristic], 4];
Length[monodromyBasisTotalTest]
(*Table[MatrixForm /@ monodromyBasisTotalTest[[i]], {i, 1, Length[monodromyBasisTotalTest]}]*)*)

(*======================NUMERICAL CALCULATIONS======================================*)
(*basis code: 1=full, 2=central, 3=monodromy*)

calculateHomologies[a_, b_, basis_, char_]:=Module[
{mLoc, m0Loc,fullBasisIndex0or3Loc,centralBasisIndex0or3Loc,monodromyBasisIndex0or3Loc,usedBasisIndex0or3Loc,sizeOfBasisAtaPointLoc, usedBasisIndex1or2Loc, usedBasisTotalLoc,d01matrixLoc, d12matrixLoc, d23matrixLoc, rank01, rank12, rank23, rankd12d01, rankd23d12,df0df1, df1df0, rankdf0df1, rankdf1df0, dF0matrixLoc, dF1matrixLoc, obstruction0matrixLoc, obstruction1matrixLoc,rankdf0, rankdf1, rankHM0, rankHM1, rankHM2, rankHM3, rankHF0, rankHF1},

{
mLoc = Dimensions[a][[1]],
m0Loc = m0[a, b, char],
fullBasisIndex0or3Loc =fullBasisIndex0or3[mLoc],
centralBasisIndex0or3Loc=centralBasisIndex0or3[a, b, m0Loc, char],
monodromyBasisIndex0or3Loc = monodromyBasisIndex0or3[a, b, char],
usedBasisIndex0or3Loc = If[basis==1, fullBasisIndex0or3Loc,If[basis==2, centralBasisIndex0or3Loc, monodromyBasisIndex0or3Loc]],
usedBasisIndex1or2Loc = basisPower[mLoc, usedBasisIndex0or3Loc, 3],
usedBasisTotalLoc = basisPower[mLoc, usedBasisIndex0or3Loc, 4],
Table[MatrixForm /@ usedBasisTotalLoc[[i]], {i, 1, Length[usedBasisTotalLoc]}],
sizeOfBasisAtaPointLoc = Length[usedBasisIndex0or3Loc],
Print["Size of" ,If[basis==1, " FULL ", If[basis==2, " CENTRAL ", " MONODROMY "]], "basis at a point = ", sizeOfBasisAtaPointLoc];
Print["m0 = ", MatrixForm[m0Loc]];

(*COMPUTING MORSE DIFFERENTIALS AS MATRICES--------------------------------------------------------------------------------------------------*)d01matrixLoc = matrixify[d01[#, a, b, char]&, usedBasisIndex0or3Loc, usedBasisIndex1or2Loc, char],
d12matrixLoc = matrixify[d12[#, a, b, char]&, usedBasisIndex1or2Loc, usedBasisIndex1or2Loc,char],
d23matrixLoc= matrixify[d23[#, a, b, char]&, usedBasisIndex1or2Loc, usedBasisIndex0or3Loc,char],
rank01 = MatrixRank[d01matrixLoc, Modulus->char],
rank12 = MatrixRank[d12matrixLoc, Modulus->char],
rank23 = MatrixRank[d23matrixLoc, Modulus->char],
rankd12d01 = MatrixRank[d12matrixLoc.d01matrixLoc, Modulus->char],
rankd23d12 = MatrixRank[d23matrixLoc.d12matrixLoc, Modulus->char],

(*COMPUTING THE FLOER DIFFERENTIALS AS MATRICES------------------------------------------------------------------------------------------------*)
dF0matrixLoc = If[char==0,matrixify[dF0[#, a, b, char]&, usedBasisTotalLoc, usedBasisTotalLoc, char], Mod[matrixify[dF0[#, a, b, char]&, usedBasisTotalLoc, usedBasisTotalLoc, char], char]],
dF1matrixLoc = If[char==0,matrixify[dF1[#, a, b, char]&, usedBasisTotalLoc, usedBasisTotalLoc, char], Mod[matrixify[dF1[#, a, b, char]&, usedBasisTotalLoc, usedBasisTotalLoc, char], char]],
(*COMPUTING THE SQUARE OF THE FLOER DIFFERENTIAL------------------------------------------------------------------------------------------------------*)
df1df0 = If[char==0,dF1matrixLoc.dF0matrixLoc, Mod[dF1matrixLoc.dF0matrixLoc, char]],
df0df1 = If[char==0, dF0matrixLoc.dF1matrixLoc, Mod[dF0matrixLoc.dF1matrixLoc, char]],
          rankdf0df1 = If[char==0, MatrixRank[df0df1], MatrixRank[df0df1, Modulus->char]],
rankdf1df0 = If[char==0, MatrixRank[df1df0], MatrixRank[df1df0, Modulus->char]],
(*COMPUTING OBSTRUCTION ENDOMORPHISMS AS MATRICES----------------------------------------------------------------------------------------------*)
obstruction0matrixLoc = If[characteristic==0,matrixify[obstruction0[#, a, b,m0Loc,  char]&, usedBasisTotalLoc, usedBasisTotalLoc,char], Mod[matrixify[obstruction0[#, a, b, m0Loc, char]&, usedBasisTotalLoc, usedBasisTotalLoc,char], char]],
obstruction1matrixLoc = If[char==0,matrixify[obstruction1[#, a, b, m0Loc,char]&, usedBasisTotalLoc, usedBasisTotalLoc,char], Mod[matrixify[obstruction1[#, a, b, m0Loc,char]&, usedBasisTotalLoc, usedBasisTotalLoc,char], char]],
(*RESULTS FOR MORSE----------------------------------------*)
rankHM0 =Length[usedBasisIndex0or3Loc]-rank01,
rankHM1 = Length[usedBasisIndex1or2Loc]-rank12-rank01,
rankHM2 = Length[usedBasisIndex1or2Loc]-rank23 - rank12,
rankHM3 = Length[usedBasisIndex0or3Loc]- rank23
}
(*Print["d01 = ", MatrixForm[d01matrixLoc]]
Print["rank[d01] = ",rank01]
Print["d12 = ",MatrixForm[d12matrixLoc]]
Print["rank[d12] = ",rank12]
Print["d23 = ",MatrixForm[d23matrixLoc]]
Print["rank[d23] = ",rank23]
Print["d12.d01 = ", MatrixForm[If[char==0, Simplify[d12matrixLoc.d01matrixLoc], Mod[Simplify[d12matrixLoc.d01matrixLoc], char]]]]
Print["d23.d12 =", MatrixForm[If[char==0, Simplify[d23matrixLoc.d12matrixLoc], Mod[Simplify[d23matrixLoc.d12matrixLoc], char]]]]
 If[(rankd12d01==0)&&(rankd23d12==0), Print[Style["dM^2 = 0", 16, Green]], Print[Style["dM^2 IS NOT 0!", 16, Red]]];*)

Print[Style["rank[HM^0(E,E)] = ",14, Orange], rankHM0];
Print[Style["rank[HM^1(E,E)] = ", 14, Orange], rankHM1];
Print[Style["rank[HM^2(E,E)] = ", 14, Orange], rankHM2];
Print[Style["rank[HM^3(E,E)] = ", 14, Orange],rankHM3];
(*RESULTS FOR FLOER--------------------------------------------------------------------------------------------------------------------*)
If[(rankdf0df1==0&&rankdf1df0==0), 
{Print[Style["dF^2 = 0", 20, Darker[Green]]],
{rankdf0 = If[char==0, MatrixRank[dF0matrixLoc],MatrixRank[dF0matrixLoc, Modulus->char]],
rankdf1 = If[char==0, MatrixRank[dF1matrixLoc],MatrixRank[dF1matrixLoc, Modulus->char]],
rankHF0 =  Length[usedBasisTotalLoc]-rankdf0-rankdf1,
rankHF1=  Length[usedBasisTotalLoc]-rankdf0-rankdf1},
 Print[Style["rank[HF^0(E,E)] = rank[HF^1(E,E)] = ",16, Orange], rankHF0]},
 Print[Style["dF^2 IS NOT 0!", 20,Darker[ Red]]
]
]

(*Print["dF0 = ", MatrixForm[dF0matrixLoc]];
Print["rank dF0 = ",rankdf0];
Print["dF1 = ",MatrixForm[dF1matrixLoc]];
Print["rank dF1 = ",rankdf1];
Print["dF1.dF0 = ", MatrixForm[df1df0]];
Print["dF0.dF1 = ", MatrixForm[df0df1]];*)


(*COMPARISON WITH OBSTRUCTION---------------------------------------------------------------------------------*)
If[(MatrixRank[obstruction0matrixLoc, Modulus->char]==0)&&(MatrixRank[obstruction1matrixLoc, Modulus->char]==0),Print[Style["Obstruction vanishes!", 20, Darker[Green]]], Print[Style["OBSTRUCTED!", 20,Darker[ Red]]]];
If[(MatrixRank[df1df0-obstruction0matrixLoc, Modulus->char]==0)&&(MatrixRank[df0df1- obstruction1matrixLoc,Modulus->char]==0), Print[Style["dF^2 = obstruction", 20, Darker[Green]]], Print[Style["dF^2 IS NOT THE CLAIMED OBSTRUCTION!", 20,Darker[ Red]]]]]

(*test run-------------------------------------------------------------------------*)
calculateHomologies[aU4, bU4, 2, 2]

characteristic =2;

calculateHomologiesFromMultiplicities[vectorOfMultiplicities_, basis_]:=Module[{aLoc, bLoc},
aLoc = repConstructor[vectorOfMultiplicities][[2]];
bLoc  = repConstructor[vectorOfMultiplicities][[3]];
Print["---------------------------------------------------------------------------------------------------"];
Print["Representation is ", vectorOfMultiplicities];
calculateHomologies[aLoc, bLoc, basis, characteristic]]

(*
The function calculateHomologiesFromMultiplicities takes 2 arguments
1. a vector of multiplicities for the six indecomposables in the order {V1, V2, V3, V4, D, U4}
2. the kind of homology to be computed: full = 1, central = 2, monodromy = 3.

It returns the relavant Morse and Floer cohomologies of the Chiang Lagrangian with the local system, corresponding to the specified representation.
*)

calculateHomologiesFromMultiplicities[{0,0, 0,0,0,1}, 1]

(*(*calculating all homologies for all reps*)
listOFSingleMultiplicities = Drop[Flatten[Table[{i, j, k, l, m, n}, {n, 0, 1},{m, 0, 1},{l, 0, 1},{k, 0, 1},{j, 0, 1},{i, 0, 1}], 5], 1];
Length[listOFSingleMultiplicities]
Table[calculateHomologiesFromMultiplicities[listOFSingleMultiplicities[[i]], j], {i, 1, Length[listOFSingleMultiplicities]}, {j, 1, 3}];
Export["mynotebook.pdf",EvaluationNotebook[]]*)