Solves a block diagonal Model using diagonalization.
Solves a Model by Diagonalizing the Hamiltonian. Is similar to Diagonalizer, but is able to take advantage of a Hamiltonian's block diagonal structure. Use PropertyExtractor::BlockDiagonalizer to extract Properties.
The BlockDiagonalizer is able to take advantage of a Model's block diagonal structure if the Subindices that the Model is block diagonal in appear to the left of Subindices that are not block indices. Therefore, if for example kx, ky, and kz are block labels, while sublattice and orbital are not, make sure the Model is specified such that the Index structure is {kx, ky, kz, sublattice, orbital} rather than {sublattice, orbital, kx, ky, kz}.
Scaling behavior:
If the Model has no blocks, the scaling behavior is the same as for the Diagonalizer, but with a larger prefactor. If the Model consists of \(b\) blocks, each of dimension \(h\), the scaling behavior is:
Time: \(O(nh^3)\)
Space: \(O(nh^2)\)
If the Model consists of \(b\) blocks of varying size, the above scaling behavior instead becomes an upper bound, with \(h\) the maximum block dimension.
Example
#include "TBTK/PropertyExtractor/BlockDiagonalizer.h"
#include "TBTK/Solver/BlockDiagonalizer.h"
#include <complex>
using namespace std;
int main(){
Streams::out << "----------------\n";
for(unsigned int block = 0; block < 2; block++){
for(unsigned int state = 0; state < 2; state++){
eigenValues[{block, state}]
= propertyExtractor.getEigenValue(
{block},
state
);
for(unsigned int n = 0; n < 2; n++){
eigenVectors[{2*block + state, n}]
= propertyExtractor.getAmplitude(
{block},
state,
{n}
);
}
}
}
Streams::out << eigenValues << "\n";
Streams::out << eigenVectors << "\n";
Streams::out << "----------------\n";
for(
unsigned int state = 0;
state++
){
eigenValues[{state}] = propertyExtractor.getEigenValue(state);
for(unsigned int block = 0; block < 2; block++){
for(unsigned int n = 0; n < 2; n++){
eigenVectors[{state, 2*block + n}]
= propertyExtractor.getAmplitude(
state,
{block, n}
);
}
}
}
Streams::out << eigenValues << "\n";
Streams::out << eigenVectors << "\n";
}
Output
Basis size: 4
Hamiltonian size: 1536B
Eigenvectors size: 128B
Number of blocks: 2
Running Diagonalizer
.
----------------
[[-1, 1]
[-2, 2]]
[[(-0.707107,0), (0.707107,0)]
[(0.707107,0), (0.707107,0)]
[(-0.707107,0), (0.707107,0)]
[(0.707107,0), (0.707107,0)]]
----------------
[-1, 1, -2, 2]
[[(-0.707107,0), (0.707107,0), (0,0), (0,0)]
[(0.707107,0), (0.707107,0), (0,0), (0,0)]
[(0,0), (0,0), (-0.707107,0), (0.707107,0)]
[(0,0), (0,0), (0.707107,0), (0.707107,0)]]