Flow tree formula for quivers

Based on the paper `Attractor flow trees, BPS indices and quivers,’’ by S. Alexandrov and B. Pioline,  arXiv:1804.06928

SetDirectory[NotebookDirectory[]];
<<CoulombHiggs`

Optimizing Flow Tree Formula:  perturb only FI parameters

ClearAll[FLowTreeFormulaRat,EvalTreeIndex,TreeIndex]

FlowTreeFormulaRat[Mat_,Cvec_,Nvec_]:=Module[{QPoinca,Cvec0},
  If[Length[Union[{Length[Cvec],Length[Mat],Length[Nvec]}]]>1,      
 Print["FlowTreeFormula: Length of DSZ matrices, FI and dimension vectors do not match !"]];
  If[Max[Abs[Flatten[Mat+Transpose[Mat]]]]>$QuiverPrecision,
		Print["FlowTreeFormulaRat: DSZ matrix is not antisymmetric !"]];
  If[Max[Nvec]<0,Print["FlowTreeFormulaRat: The dimension vector must be positive !"]];
  If[Plus@@Nvec==0,Return[0]];
  If[Plus@@Nvec==1,Return[1]];
Cvec0=Cvec-(Plus@@(Nvec Cvec))/(Plus@@Nvec);
  If[(Abs[Plus@@(Nvec Cvec)]>$QuiverPrecision)&&$QuiverVerbose,       
		Print["FlowTreeFormula: FI terms do not sum up to zero, shifting",Cvec," to ",Cvec0]] ;
  If[$QuiverVerbose,PrintTemporary["FlowTreeFormulaRat: Evaluating tree indices..."]]; 
  QPoinca=EvalTreeIndex[Mat,Cvec0,TreePoincarePolynomialRat[Nvec,y]] 
];

EvalTreeIndex[Mat_,Cvec_,f_]:=f/.{Treeg[Li_,y_]:>
  TreeIndex[
	Table[Sum[Li[[i,k]]Li[[j,l]]Mat[[k,l]],{k,Length[Mat]},{l,Length[Mat]}],
      {i,Length[Li]},{j,Length[Li]}],
	Table[Sum[Li[[i,k]] Cvec[[k]],{k,Length[Mat]}],{i,Length[Li]}],y]};

TreeIndex[Mat_,Cvec_,y_]:=Module[{m,ListPerm,i,j,k,RCvec},
	m=Length[Cvec];
	 If[$QuiverVerbose,
        If[Abs[Plus@@Cvec]>$QuiverPrecision,Print["TreeIndex: Cvec does not sum to zero !"]];
	];
	ListPerm=Permutations[Range[m]];
If[$QuiverVerbose,
        Do[ If[Abs[Sum[Cvec[[ListPerm[[j,i]]]],{i,k}]]<=$QuiverPrecision, 
           If[Abs[Sum[Mat[[ListPerm[[j,i1]],ListPerm[[j,i2]]]],
                {i1,k},{i2,k+1,m}]]>$QuiverPrecision,
               Print["CoulombIndex: FI sit on wall of marginal stability"];Break[]];
          ],{k,1,IntegerPart[m/2]},{j,Length[ListPerm]}
       ]];
	RCvec=1/1000/$QuiverPerturb2 Table[Random[Integer,{1,1000}],{i,m}];
	RCvec[[m]]=-Sum[RCvec[[i]],{i,m-1}];
	If[$QuiverVerbose&&m>3,PrintTemporary["TreeIndex: evaluating for ",m," centers"]];
    (y-1/y)^(1-m) (-1)^(Sum[QuiverMultiplierMat[i,j] Mat[[i,j]],{i,Length[Cvec]},{j,i+1,m}]+m-1)
 Which[$QuiverFlowTreeOpt==0,
        Sum[y^( Sum[QuiverMultiplierMat[ListPerm[[k,i]],ListPerm[[k,j]]] 
        Mat[[ListPerm[[k,i]],ListPerm[[k,j]]]],{i,m},{j,i+1,m}])
		TreeF[Table[Mat[[ListPerm[[k,i]],ListPerm[[k,j]]]],{i,m},{j,m}],
                 Table[Cvec[[ListPerm[[k,i]]]]+RCvec[[ListPerm[[k,i]]]],{i,m}]],
       {k,Length[ListPerm]}],
       $QuiverFlowTreeOpt==1,
Sum[y^( Sum[QuiverMultiplierMat[ListPerm[[k,i]],ListPerm[[k,j]]] Mat[[ListPerm[[k,i]],ListPerm[[k,j]]]],{i,m},{j,i+1,m}])
		TreeFAlt1[Table[Mat[[ListPerm[[k,i]],ListPerm[[k,j]]]],{i,m},{j,m}],
                 Table[Cvec[[ListPerm[[k,i]]]]+RCvec[[ListPerm[[k,i]]]],{i,m}]],
       {k,Length[ListPerm]}],
       $QuiverFlowTreeOpt==2,
Sum[y^( Sum[QuiverMultiplierMat[ListPerm[[k,i]],ListPerm[[k,j]]] Mat[[ListPerm[[k,i]],ListPerm[[k,j]]]],{i,m},{j,i+1,m}])
		TreeFAlt2[Table[Mat[[ListPerm[[k,i]],ListPerm[[k,j]]]],{i,m},{j,m}],
                 Table[Cvec[[ListPerm[[k,i]]]]+RCvec[[ListPerm[[k,i]]]],{i,m}]], 
       {k,Length[ListPerm]}]
       ]
];

(*PlaneTreeSign[Mat_,Cvec_,Li_]:=Module[{Li1,Li2,g12,Cvec2},
  (* here Li is a grouping specifying a plane tree *)
  If[Depth[Li]==1,1,
  If[Depth[Li]==2,
    Li1=Flatten[{Li[[1]]}];
    Li2=Flatten[{Li[[2]]}];
If[DSZProdAbelian[Mat,Li1,Li2]>0 && Sum[Cvec[[Li1[[i]]]],{i,Length[Li1]}]>0,1,0]
    (*1/2(Sign[DSZProdAbelian[Mat,Li1,Li2]]+Sign[Sum[Cvec[[Li1[[i]]]],{i,Length[Li1]}]])*),
  Li1=Flatten[{Li[[1]]}];
  Li2=Flatten[{Li[[2]]}];
g12=DSZProdAbelian[Mat,Li1,Li2];
 If[(g12<=0)|| Sum[Cvec[[Li1[[i]]]],{i,Length[Li1]}]<0,0,
     Cvec2=Cvec+Sum[Cvec[[Li1[[j]]]],{j,Length[Li1]}]/g12
      Table[DSZProdAbelian[Mat,Li1,{i}]+DSZProdAbelian[Mat,Li2,{i}],{i,Length[Mat]}];
   PlaneTreeSign[Mat,Cvec2,Li[[1]]]*PlaneTreeSign[Mat,Cvec2,Li[[2]]]
  ]]]];*)

$QuiverFlowTreeOpt

Random examples of Abelian quivers without loop

n=5;
Mat=RandomDSZWithNoLoop[n,5];
QuiverPlot[Mat]

Nvec=ConstantArray[1,n];
Cvec=Table[Random[Integer,{-100,100}],{i,n}]/100;
Cvec[[n]]=-Sum[Cvec[[i]],{i,n-1}];
Cvec=-AttractorFI[Mat,Nvec];
IndexHiggs=HiggsBranchFormula[Mat,Cvec,Nvec]

IndexTree=FlowTreeFormula[Mat,Cvec,Nvec]/.{OmAtt[gam_,y_]:>0/;Plus@@gam>1}/.{OmAtt[gam_,y_]:>1}

Simplify[IndexHiggs-IndexTree]

(* testing non-Abelian case *)
Nvec=Flatten[{ConstantArray[1,n-1],2}];
Cvec[[n]]=-1/2Sum[Cvec[[i]],{i,n-1}];
Cvec=-AttractorFI[Mat,Nvec];
IndexHiggs=HiggsBranchFormula[Mat,Cvec,Nvec]

IndexTree=FlowTreeFormula[Mat,Cvec,Nvec]/.{OmAtt[gam_,y_]:>0/;Plus@@gam>1}/.{OmAtt[gam_,y_]:>1}

Simplify[IndexHiggs-IndexTree]

Random examples of Abelian quivers with loop

n=4;
Mat=RandomDSZWithLoop[n,5];
QuiverPlot[Mat]

Nvec=ConstantArray[1,n];
Cvec=Table[Random[Integer,{-100,100}],{i,n}]/100;
Cvec[[n]]=-Sum[Cvec[[i]],{i,n-1}];
IndexCoulomb=CoulombBranchFormula[Mat,Cvec,Nvec]

IndexTree=FlowTreeFormula[Mat,Cvec,Nvec]

IndexTreeQ=IndexTree/.{OmAtt[gam_,y_]:>1/;Plus@@gam==1,OmAtt[gam_,y_]:>0/;Plus@@gam==2}

Simplify[IndexTreeQ-IndexCoulomb]

Comparing various schemes for evaluating the partial tree index

n=4;Mat=RandomDSZWithLoop[n,5];
QuiverPlot[Mat]

{a1,a2,a3}={0,0,0};
Monitor[While[a1==a2 &&a2==a3,
Cvec=Table[Random[Integer,{-10000,10000}],{i,n}]/10000;
Cvec[[n]]=-Sum[Cvec[[i]],{i,n-1}];{a1,a2,a3}={TreeF[Mat,Cvec],TreeFAlt1[Mat,Cvec],TreeFAlt2[Mat,Cvec]};],{a1,a2,a3}]

{a1,a2,a3}