//Test if still an eigenvector with zero eigenvalue
if(abs(Vtest[i])>1e-10*d2V.Mag[a2]){
//If component not consistent, then store position of vector that failed...
Gpos[kminus]=k;
// and increase count of candidates which fail...
kminus++;
i=d2V.size()-1;// skip checks of remaining components since the vector has failed
}
}
}
}
// Directions which are not flat and may be curved eigen-drections
unsignedintkleft=kminus+d2V.size()-kflat;
kminus2=kleft;//kminus2 will contain the number of directions that will mix. So in the worst case everything left will mix
if(kleft>1){
double*Mtest;
double*MtestOut;
vector<double>tempvec(d2V.size(),0);
vector<vector<double>>Basis(kleft,tempvec),BasisStore(kleft,tempvec);//Basis composed of eigenvectors of the reference matrix, and Store Space for basis vectors as they are accepted or rejected
Mtest=newdouble[kleft*kleft];//Space for reference matrix being checked
MtestOut=newdouble[(kleft+1)*kleft];//Eigenvalues and eigenvectors of the reference matrix
//Initialise basis using the first reference matrix that was used when finding candidates
////First place the rejected flat directions of the reference matrix
unsignedinta2ref2=a2ref;//Integer to loop over other matrices to check their eigenvectors
unsignedintkaccept=0;//Counter of the curved directions that are accepted
unsignedintdimN=kleft;//Dimension of the subspace under inspection
while(a2ref2<d2V[0][0].size()&&dimN>0){//Use matrix a2ref2 as reference if there is a subspace to check
//Initialise the reference matrix a2ref2 in the basis of the subspace being checked
for(size_tk1=0;k1!=dimN;++k1){
for(size_tk2=0;k2!=dimN;++k2){
Mtest[k1*dimN+k2]=0e0;
for(size_ti=0;i!=d2V.size();++i){
doubleTempSum=0e0;
for(size_tj=0;j!=d2V.size();++j)
TempSum+=d2V[i][j][orderdV[a2ref2]]*Basis[k2][j];
Mtest[k1*dimN+k2]+=Basis[k1][i]*TempSum;
}
}
}
//Compute the eigenvalues of the reference matrix in this basis
EigenSystemRsym(dimN,Mtest,MtestOut);
size_tkfail=0;//Integer to count vectors that are rejected
//Loop over all vectors to check if any can be a curved eigendirection
for(size_tk=0;k!=dimN;++k){
// Expand back the eigenvector in the original basis
for(size_ti=0;i!=d2V.size();++i){
tempvec[i]=0e0;
for(size_tk2=0;k2!=dimN;++k2)
tempvec[i]+=MtestOut[(k+1)*dimN+k2]*Basis[k2][i];
if(abs(tempvec[i])<1e-10)
tempvec[i]=0e0;//Chop numerical errors
}
//Check this eigenvector if the eigenvalue is non-zero, to see if it can be a curved eigendirection
if(MtestOut[k]!=0){
///test other matrices against such vector
booltestcurv=false;//logical switch to check if the direction has been accepted
for(size_ta2=a2ref;a2!=d2V[0][0].size();++a2){
//loop over all other matrices
if(a2!=a2ref2){
//test vector against matrix
testcurv=TestCurved(a2,NIC,d2V,orderdV,tempvec);
if(nottestcurv){
//Direction failed to be accepted....
for(size_ti=0;i!=d2V.size();++i){
if(abs(tempvec[i])>1e-10)
BasisStore[kfail][i]=tempvec[i];//Store basis in the first range from k=0 with increasing kfail as failed directions are spotted
else
BasisStore[kfail][i]=0e0;//Chop numerical errors (note the condition above is good because the eigenvectors are normalised)
}
kfail++;//Add to the counter of vectors that have been excluded
a2=d2V[0][0].size()-1;// avoid check of other matrices since the direction is already excluded
}
}
}
// Case when the direction was accepted in the previous loop
if(testcurv){
kaccept++;//increase counter of accepted curved directions
for(size_ti=0;i!=d2V.size();++i){//And store vector in the top end of the k range (rejected directions are stored down up, and accepted directions, top down)
else{//Otherwise its a "null" eigendirection so we cannot accept it as a curved direction or reject it (because it may be an eigendirection of one or more of the other matrices with non-zero eigenvalue)
for(size_ti=0;i!=d2V.size();++i){
//Store direction that may or may not be curved
if(abs(tempvec[i])>1e-10)
BasisStore[kfail][i]=tempvec[i];
else
BasisStore[kfail][i]=0e0;//Chop numerical errors
}
kfail++;//Icrease count od directions of the new subspace to be checked in the next round of a2ref2
}
}
dimN=kleft-kaccept;// Dimension of new subspace to be checked
//Set new basis for (possibly) smaller subspace using the stored basis vectors
for(size_tk=0;k!=dimN;++k)
for(size_tj=0;j!=d2V.size();++j)
Basis[k][j]=BasisStore[k][j];
a2ref2++;
}
//The new basis has been defined with the directions that will mix in the lower sector of BasisStore and the curved eigendirections in the upper sector of the array (in k)
//// Replace the vectors in TempOut which were candidate flat directions that failed the tests by the first few vectors in BasisStore
doublelambda=Vtest[i]/vec[i];//lambda obtained from this component
//Check if the current component is consistent with the eigenvalue estimate
if(abs(lambdaEst-lambda)>1e-10*d2V.Mag[a2]){
result=false;//If no, i.e. estimate differs too much from the current component then reject
i=d2V.size()-1;// avoid continuing the computation of other matrix elements
}
}
elseif(abs(Vtest[i])>1e-10*d2V.Mag[a2]){//In this case lambda should be zero so it is inconsistent to have a non-zero value for any of the components of Vtest. Then reject candidate.
result=false;
i=d2V.size()-1;// cancel further checks of matrix elements
///Converting system to basis with a priori diagonal directions. The basis will be composed first by the vectors which are not eigenvectors and then the a priori eigen-vectors
//// If there are zero matrices before the reference matrix, set them to zero
for(size_ta2=NIC;a2!=a2ref;++a2)
for(size_ti=0;i!=d2V.size();++i)
for(size_tj=0;j!=d2V.size();j++)
d2Vnew[i][j][orderdV[a2]]=0e0;
//// Counter of non-eigen directions
unsignedintkNo=0,kYesF=0,kYesC=0;
/// Place non-eigen directions first in the matrix
for(size_ti=0;i!=d2V.size();++i){
//Test if the ith direction is an eigen direction
boolaccept=true;
boolflat=false;
if(i<kflat)
flat=true;
//Loop over non-eigen directions
if(kminus>kminus2){//Case when the number of rejected flat directions is larger than the number of directions that will mix which means that all mixing directions are part of this set and other directions are curved eigendirections
for(size_tk1=0;k1!=kminus;++k1){
//reject ith direction in case it's on the list Gpos
if(Gpos[k1]==i)
accept=false;
else
flat=true;
}
}
else{//Complementary case when some of the mixing directions are in the set counted by kminus and others are from the initial candidate curved eigendirections
for(size_tk1=0;k1!=kminus;++k1){
//reject ith direction in case it's on the list Gpos
if(Gpos[k1]==i)
accept=false;
else
flat=true;
}
for(intk1=kflat;k1!=kflat+kminus2-kminus;++k1){
//reject ith direction in case it has been rejected in the list of potential curved eigen-directions
if(k1==i)
accept=false;
}
}
// If rejected then place the corresponding eigenvalue in the kth position and, increase the count by 1 and place the eigenvector in TempM for simplicity