26 #include "Correlations.h" 28 #include "MPIchemps2.h" 43 Cspin =
new double[L*L];
44 Cdens =
new double[L*L];
45 Cspinflip =
new double[L*L];
46 Cdirad =
new double[L*L];
47 MutInfo =
new double[L*L];
49 for (
int cnt=0; cnt<L*L; cnt++){ Cspin[cnt] = 0.0; }
50 for (
int cnt=0; cnt<L*L; cnt++){ Cdens[cnt] = 0.0; }
51 for (
int cnt=0; cnt<L*L; cnt++){ Cspinflip[cnt] = 0.0; }
52 for (
int cnt=0; cnt<L*L; cnt++){ Cdirad[cnt] = 0.0; }
53 for (
int cnt=0; cnt<L*L; cnt++){ MutInfo[cnt] = 0.0; }
55 FillSpinDensSpinflip();
69 void CheMPS2::Correlations::FillSpinDensSpinflip(){
72 for (
int row=0; row<L; row++){
73 for (
int col=0; col<L; col++){
80 for (
int row=0; row<L; row++){
81 for (
int col=0; col<L; col++){
88 for (
int row=0; row<L; row++){
89 for (
int col=0; col<L; col++){
92 Cspinflip[row + L*row] += the2DM->
get1RDM_DMRG(row, row);
96 for (
int row=0; row<L; row++){
97 for (
int col=0; col<L; col++){
167 const double val4 = 0.5 * the2DM->
getTwoDMA_DMRG(index,index,index,index);
169 const double val1 = 1.0 - val4 - 2*val23;
171 double entropy = 0.0;
172 if (val1 > CheMPS2::CORRELATIONS_discardEig){ entropy -= val1 * log(val1 ); }
173 if (val23 > CheMPS2::CORRELATIONS_discardEig){ entropy -= 2 * val23 * log(val23); }
174 if (val4 > CheMPS2::CORRELATIONS_discardEig){ entropy -= val4 * log(val4 ); }
191 for (
int row=0; row<L; row++){
192 for (
int col=0; col<L; col++){
194 Idist += MutInfo[row + L*col] * pow(abs(row - col), power);
202 #ifdef CHEMPS2_MPI_COMPILATION 206 MPIchemps2::broadcast_array_double( MutInfo, size, MPI_CHEMPS2_MASTER );
207 MPIchemps2::broadcast_array_double( Cdirad, size, MPI_CHEMPS2_MASTER );
214 const int theindex = denT->
gIndex();
216 double * workmem =
new double[MAXDIM*MAXDIM];
218 double * RDM =
new double[lindimRDM*lindimRDM];
219 int lwork = 3*lindimRDM - 1;
220 double * work =
new double[lwork];
221 double * eigs =
new double[lindimRDM];
223 const double prefactorSpin = 1.0/(Prob->
gTwoS() + 1.0);
224 const double sqrt_one_half = sqrt(0.5);
226 for (
int previousindex=0; previousindex<theindex; previousindex++){
228 const bool equalIrreps = (denBK->
gIrrep(previousindex) == denBK->
gIrrep(theindex)) ?
true :
false;
229 const double diag1 = diagram3(denT, Gtensors[previousindex], workmem) * prefactorSpin * 0.5 * sqrt_one_half;
230 const double diag2 = 0.125 * ( the2DM->
getTwoDMB_DMRG(previousindex,theindex,theindex,previousindex)
231 - the2DM->
getTwoDMA_DMRG(previousindex,theindex,theindex,previousindex) );
233 const double val1 = diagram1(denT, Ytensors[previousindex], workmem) * prefactorSpin;
234 const double val2 = diagram2(denT, Ztensors[previousindex], workmem) * prefactorSpin;
235 const double val3 = diag1 + diag2;
236 const double val4 = diagram1(denT, Gtensors[previousindex], workmem) * prefactorSpin * sqrt_one_half;
237 const double val5 = diagram3(denT, Ytensors[previousindex], workmem) * prefactorSpin * 0.5;
238 const double val6 = (equalIrreps) ? ( diagram4(denT, Ktensors[previousindex], workmem) * prefactorSpin * 0.5 ) : 0.0 ;
239 const double val7 = diagram2(denT, Gtensors[previousindex], workmem) * prefactorSpin * sqrt_one_half;
240 const double val8 = diagram3(denT, Ztensors[previousindex], workmem) * prefactorSpin * 0.5;
241 const double val9 = (equalIrreps) ? ( diagram5(denT, Mtensors[previousindex], workmem) * prefactorSpin * 0.5 ) : 0.0 ;
244 const double alpha = diagram2(denT, Ytensors[previousindex], workmem) * prefactorSpin;
245 const double gamma = diagram1(denT, Ztensors[previousindex], workmem) * prefactorSpin;
246 const double beta = diag1 - diag2;
247 const double lambda = 2*diag2;
248 const double delta = (equalIrreps) ? ( - diagram5(denT, Ktensors[previousindex], workmem) * prefactorSpin * 0.5 ) : 0.0;
249 const double epsilon = (equalIrreps) ? ( diagram4(denT, Mtensors[previousindex], workmem) * prefactorSpin * 0.5 ) : 0.0;
250 const double kappa = 0.5 * the2DM->
getTwoDMA_DMRG(previousindex,previousindex,theindex,theindex);
273 for (
int cnt=0; cnt<lindimRDM*lindimRDM; cnt++){ RDM[cnt] = 0.0; }
274 RDM[0 + lindimRDM * 0 ] = val1;
275 RDM[15 + lindimRDM * 15] = val2;
276 RDM[5 + lindimRDM * 5 ] = RDM[10 + lindimRDM * 10] = val3;
277 RDM[1 + lindimRDM * 1 ] = RDM[3 + lindimRDM * 3 ] = val4;
278 RDM[2 + lindimRDM * 2 ] = RDM[4 + lindimRDM * 4 ] = val5;
279 RDM[1 + lindimRDM * 2 ] = RDM[2 + lindimRDM * 1 ] = RDM[3 + lindimRDM * 4 ] = RDM[4 + lindimRDM * 3 ] = val6;
280 RDM[11 + lindimRDM * 11] = RDM[13 + lindimRDM * 13] = val7;
281 RDM[12 + lindimRDM * 12] = RDM[14 + lindimRDM * 14] = val8;
282 RDM[11 + lindimRDM * 12] = RDM[12 + lindimRDM * 11] = RDM[13 + lindimRDM*14] = RDM[14 + lindimRDM*13] = val9;
283 RDM[6 + lindimRDM * 6 ] = alpha;
284 RDM[7 + lindimRDM * 7 ] = RDM[8 + lindimRDM * 8 ] = beta;
285 RDM[9 + lindimRDM * 9 ] = gamma;
286 RDM[6 + lindimRDM * 7 ] = RDM[7 + lindimRDM * 6 ] = delta;
287 RDM[6 + lindimRDM * 8 ] = RDM[8 + lindimRDM * 6 ] = - delta;
288 RDM[7 + lindimRDM * 9 ] = RDM[9 + lindimRDM * 7 ] = epsilon;
289 RDM[8 + lindimRDM * 9 ] = RDM[9 + lindimRDM * 8 ] = - epsilon;
290 RDM[6 + lindimRDM * 9 ] = RDM[9 + lindimRDM * 6 ] = kappa;
291 RDM[7 + lindimRDM * 8 ] = RDM[8 + lindimRDM * 7 ] = lambda;
293 if (CheMPS2::CORRELATIONS_debugPrint){
294 const double RDM_1orb_prev_4 = 0.5 * the2DM->
getTwoDMA_DMRG(previousindex,previousindex,previousindex,previousindex);
295 const double RDM_1orb_prev_23 = 0.5 * ( the2DM->
get1RDM_DMRG(previousindex, previousindex)
296 - the2DM->
getTwoDMA_DMRG(previousindex,previousindex,previousindex,previousindex) );
297 const double RDM_1orb_prev_1 = 1.0 - RDM_1orb_prev_4 - 2*RDM_1orb_prev_23;
299 const double RDM_1orb_curr_4 = 0.5 * the2DM->
getTwoDMA_DMRG(theindex,theindex,theindex,theindex);
300 const double RDM_1orb_curr_23 = 0.5 * ( the2DM->
get1RDM_DMRG(theindex, theindex) - the2DM->
getTwoDMA_DMRG(theindex,theindex,theindex,theindex) );
301 const double RDM_1orb_curr_1 = 1.0 - RDM_1orb_curr_4 - 2*RDM_1orb_curr_23;
303 cout <<
" Correlations::FillSite : Looking at DMRG sites (" << previousindex <<
"," << theindex <<
")." << endl;
306 double fulltrace = 0.0;
307 for (
int cnt=0; cnt<lindimRDM; cnt++){ fulltrace += RDM[ cnt * ( 1 + lindimRDM ) ]; }
308 cout <<
" 1 - trace(2-orb RDM) = " << 1.0 - fulltrace << endl;
311 double getal1 = RDM[0 + lindimRDM * 0 ] + RDM[1 + lindimRDM * 1 ] + RDM[3 + lindimRDM * 3 ] + RDM[9 + lindimRDM * 9 ] - RDM_1orb_curr_1;
312 double getal2 = RDM[2 + lindimRDM * 2 ] + RDM[5 + lindimRDM * 5 ] + RDM[8 + lindimRDM * 8 ] + RDM[12 + lindimRDM * 12] - RDM_1orb_curr_23;
313 double getal3 = RDM[4 + lindimRDM * 4 ] + RDM[7 + lindimRDM * 7 ] + RDM[10 + lindimRDM * 10] + RDM[14 + lindimRDM * 14] - RDM_1orb_curr_23;
314 double getal4 = RDM[6 + lindimRDM * 6 ] + RDM[11 + lindimRDM * 11] + RDM[13 + lindimRDM * 13] + RDM[15 + lindimRDM * 15] - RDM_1orb_curr_4;
315 double RMS = sqrt(getal1*getal1 + getal2*getal2 + getal3*getal3 + getal4*getal4);
316 cout <<
" 2-norm difference of one-orb RDM of the CURRENT site via 2DM and via trace(2-orb RDM) = " << RMS << endl;
319 getal1 = RDM[0 + lindimRDM * 0 ] + RDM[2 + lindimRDM * 2 ] + RDM[4 + lindimRDM * 4 ] + RDM[6 + lindimRDM * 6 ] - RDM_1orb_prev_1;
320 getal2 = RDM[1 + lindimRDM * 1 ] + RDM[5 + lindimRDM * 5 ] + RDM[7 + lindimRDM * 7 ] + RDM[11 + lindimRDM * 11] - RDM_1orb_prev_23;
321 getal3 = RDM[3 + lindimRDM * 3 ] + RDM[8 + lindimRDM * 8 ] + RDM[10 + lindimRDM * 10] + RDM[13 + lindimRDM * 13] - RDM_1orb_prev_23;
322 getal4 = RDM[9 + lindimRDM * 9 ] + RDM[12 + lindimRDM * 12] + RDM[14 + lindimRDM * 14] + RDM[15 + lindimRDM * 15] - RDM_1orb_prev_4;
323 RMS = sqrt(getal1*getal1 + getal2*getal2 + getal3*getal3 + getal4*getal4);
324 cout <<
" 2-norm difference of one-orb RDM of the PREVIOUS site via 2DM and via trace(2-orb RDM) = " << RMS << endl;
330 dsyev_(&jobz, &uplo, &lindimRDM, RDM, &lindimRDM, eigs, work, &lwork, &info);
332 double entropy = 0.0;
333 for (
int cnt=0; cnt<lindimRDM; cnt++){
334 if (eigs[cnt] > CheMPS2::CORRELATIONS_discardEig){
335 entropy -= eigs[cnt] * log(eigs[cnt]);
340 MutInfo[previousindex + L * theindex] = MutInfo[theindex + L * previousindex] = thisMutInfo;
341 Cdirad[previousindex + L * theindex] += 2 * beta;
342 Cdirad[theindex + L * previousindex] += 2 * beta;
353 double CheMPS2::Correlations::diagram1(
TensorT * denT,
TensorGYZ * denY,
double * workmem)
const{
355 const int theindex = denT->
gIndex();
359 for (
int NR = denBK->
gNmin(theindex+1); NR <= denBK->
gNmax(theindex+1); NR++){
360 for (
int TwoSR = denBK->
gTwoSmin(theindex+1,NR); TwoSR <= denBK->
gTwoSmax(theindex+1,NR); TwoSR += 2){
363 int dimL = denBK->
gCurrentDim(theindex, NR, TwoSR, IR);
364 int dimR = denBK->
gCurrentDim(theindex+1, NR, TwoSR, IR);
366 if ((dimL>0)&&(dimR>0)){
368 double * blockT = denT->
gStorage(NR,TwoSR,IR,NR,TwoSR,IR);
369 double * blockY = denY->
gStorage(NR,TwoSR,IR,NR,TwoSR,IR);
374 dgemm_(¬rans, ¬rans, &dimL, &dimR, &dimL, &alpha, blockY, &dimL, blockT, &dimL, &beta, workmem, &dimL);
376 int length = dimL*dimR;
378 total += (TwoSR + 1.0) * ddot_(&length, workmem, &inc, blockT, &inc);
389 double CheMPS2::Correlations::diagram2(
TensorT * denT,
TensorGYZ * denZ,
double * workmem)
const{
391 const int theindex = denT->
gIndex();
395 for (
int NR = denBK->
gNmin(theindex+1); NR <= denBK->
gNmax(theindex+1); NR++){
396 for (
int TwoSR = denBK->
gTwoSmin(theindex+1,NR); TwoSR <= denBK->
gTwoSmax(theindex+1,NR); TwoSR += 2){
399 int dimL = denBK->
gCurrentDim(theindex, NR-2, TwoSR, IR);
400 int dimR = denBK->
gCurrentDim(theindex+1, NR, TwoSR, IR);
402 if ((dimL>0)&&(dimR>0)){
404 double * blockT = denT->
gStorage(NR-2,TwoSR,IR,NR, TwoSR,IR);
405 double * blockZ = denZ->
gStorage(NR-2,TwoSR,IR,NR-2,TwoSR,IR);
410 dgemm_(¬rans, ¬rans, &dimL, &dimR, &dimL, &alpha, blockZ, &dimL, blockT, &dimL, &beta, workmem, &dimL);
412 int length = dimL*dimR;
414 total += (TwoSR + 1.0) * ddot_(&length, workmem, &inc, blockT, &inc);
425 double CheMPS2::Correlations::diagram3(
TensorT * denT,
TensorGYZ * denG,
double * workmem)
const{
427 const int theindex = denT->
gIndex();
431 for (
int NR = denBK->
gNmin(theindex+1); NR <= denBK->
gNmax(theindex+1); NR++){
432 for (
int TwoSR = denBK->
gTwoSmin(theindex+1,NR); TwoSR <= denBK->
gTwoSmax(theindex+1,NR); TwoSR += 2){
435 int dimR = denBK->
gCurrentDim(theindex+1, NR, TwoSR, IR);
440 for (
int TwoSL = TwoSR-1; TwoSL <= TwoSR+1; TwoSL+=2){
442 int dimL = denBK->
gCurrentDim(theindex, NR-1, TwoSL, IL);
446 double * blockT = denT->
gStorage(NR-1,TwoSL,IL,NR, TwoSR,IR);
447 double * blockG = denG->
gStorage(NR-1,TwoSL,IL,NR-1,TwoSL,IL);
452 dgemm_(¬rans, ¬rans, &dimL, &dimR, &dimL, &alpha, blockG, &dimL, blockT, &dimL, &beta, workmem, &dimL);
454 int length = dimL*dimR;
456 total += (TwoSR + 1.0) * ddot_(&length, workmem, &inc, blockT, &inc);
469 double CheMPS2::Correlations::diagram4(
TensorT * denT,
TensorKM * denK,
double * workmem)
const{
471 const int theindex = denT->
gIndex();
475 for (
int NR = denBK->
gNmin(theindex+1); NR <= denBK->
gNmax(theindex+1); NR++){
476 for (
int TwoSR = denBK->
gTwoSmin(theindex+1,NR); TwoSR <= denBK->
gTwoSmax(theindex+1,NR); TwoSR += 2){
479 int dimR = denBK->
gCurrentDim(theindex+1, NR, TwoSR, IR);
480 int dimLup = denBK->
gCurrentDim(theindex, NR, TwoSR, IR);
483 if ((dimR>0) && (dimLup>0)){
485 for (
int TwoSLdown = TwoSR-1; TwoSLdown <= TwoSR+1; TwoSLdown += 2){
487 int dimLdown = denBK->
gCurrentDim(theindex, NR-1, TwoSLdown, ILdown);
491 double * blockTup = denT->
gStorage(NR, TwoSR, IR, NR, TwoSR, IR);
492 double * blockTdown = denT->
gStorage(NR-1, TwoSLdown, ILdown, NR, TwoSR, IR);
493 double * blockK = denK->
gStorage(NR-1, TwoSLdown, ILdown, NR, TwoSR, IR);
498 dgemm_(¬rans, ¬rans, &dimLdown, &dimR, &dimLup, &alpha, blockK, &dimLdown, blockTup, &dimLup, &beta, workmem, &dimLdown);
500 int length = dimLdown*dimR;
502 total += (TwoSR + 1.0) * ddot_(&length, workmem, &inc, blockTdown, &inc);
515 double CheMPS2::Correlations::diagram5(
TensorT * denT,
TensorKM * denM,
double * workmem)
const{
517 const int theindex = denT->
gIndex();
521 for (
int NR = denBK->
gNmin(theindex+1); NR <= denBK->
gNmax(theindex+1); NR++){
522 for (
int TwoSR = denBK->
gTwoSmin(theindex+1,NR); TwoSR <= denBK->
gTwoSmax(theindex+1,NR); TwoSR += 2){
525 int dimR = denBK->
gCurrentDim(theindex+1, NR, TwoSR, IR);
526 int dimLdown = denBK->
gCurrentDim(theindex, NR-2, TwoSR, IR);
529 if ((dimR>0) && (dimLdown>0)){
531 for (
int TwoSLup = TwoSR-1; TwoSLup <= TwoSR+1; TwoSLup += 2){
533 int dimLup = denBK->
gCurrentDim(theindex, NR-1, TwoSLup, ILup);
537 double * blockTdown = denT->
gStorage(NR-2, TwoSR, IR, NR, TwoSR, IR);
538 double * blockTup = denT->
gStorage(NR-1, TwoSLup, ILup, NR, TwoSR, IR);
539 double * blockM = denM->
gStorage(NR-2, TwoSR, IR, NR-1, TwoSLup, ILup);
544 dgemm_(¬rans, ¬rans, &dimLdown, &dimR, &dimLup, &alpha, blockM, &dimLdown, blockTup, &dimLup, &beta, workmem, &dimLdown);
546 int length = dimLdown*dimR;
548 const int fase = ((((TwoSLup + 1 - TwoSR)/2)%2)!=0)?-1:1;
549 total += fase * sqrt((TwoSLup+1.0)*(TwoSR+1)) * ddot_(&length, workmem, &inc, blockTdown, &inc);
562 void CheMPS2::Correlations::PrintTableNice(
const double * table,
const int sPrecision,
const int columnsPerLine)
const{
564 std::stringstream thestream;
565 thestream.precision(sPrecision);
566 thestream << std::fixed;
568 int numGroups = L / columnsPerLine;
569 if (numGroups * columnsPerLine < L){ numGroups++; }
571 std::string prefix =
" ";
573 for (
int groups=0; groups<numGroups; groups++){
574 const int startCol = groups * columnsPerLine + 1;
575 const int stopCol = min( (groups + 1) * columnsPerLine , L );
576 thestream << prefix <<
"Columns " << startCol <<
" to " << stopCol <<
"\n \n";
577 for (
int row=0; row<L; row++){
578 for (
int col=startCol-1; col<stopCol; col++){
579 if ((row==col) && (table==MutInfo)){
580 thestream << prefix <<
" 0 ";
581 for (
int cnt=0; cnt<sPrecision; cnt++){ thestream <<
" "; }
583 int row2 = (Prob->
gReorder()) ? Prob->
gf1(row) : row;
584 int col2 = (Prob->
gReorder()) ? Prob->
gf1(col) : col;
585 if (table[row2 + L*col2] < 0.0){
586 thestream << prefix << table[row2 + L*col2];
588 thestream << prefix <<
" " << table[row2 + L*col2];
598 cout << thestream.str();
604 cout <<
"--------------------------------------------------------" << endl;
605 cout <<
"Spin correlation function = 4 * ( < S_i^z S_j^z > - < S_i^z > * < S_j^z > ) \nHamiltonian index order is used!\n" << endl;
606 PrintTableNice( Cspin , precision, columnsPerLine );
607 cout <<
"--------------------------------------------------------" << endl;
608 cout <<
"Spin-flip correlation function = < S_i^+ S_j^- > + < S_i^- S_j^+ > \nHamiltonian index order is used!\n" << endl;
609 PrintTableNice( Cspinflip , precision, columnsPerLine);
610 cout <<
"--------------------------------------------------------" << endl;
611 cout <<
"Density correlation function = < n_i n_j > - < n_i > * < n_j > \nHamiltonian index order is used!\n" << endl;
612 PrintTableNice( Cdens , precision, columnsPerLine );
613 cout <<
"--------------------------------------------------------" << endl;
614 cout <<
"Singlet diradical correlation function = < d_i,up d_j,down > + < d_i,down d_j,up > - < d_i,up > * < d_j,down > - < d_i,down > * < d_j,up > \nHamiltonian index order is used!\n" << endl;
615 PrintTableNice( Cdirad , precision, columnsPerLine );
616 cout <<
"--------------------------------------------------------" << endl;
617 cout <<
"Two-orbital mutual information = 0.5 * ( s1(i) + s1(j) - s2(i,j) ) * ( 1 - delta(i,j) ) \nHamiltonian index order is used!\n" << endl;
618 PrintTableNice( MutInfo , precision, columnsPerLine );
619 cout <<
"--------------------------------------------------------" << endl;
int gNmin(const int boundary) const
Get the min. possible particle number for a certain boundary.
Correlations(const SyBookkeeper *denBKIn, const Problem *ProbIn, TwoDM *the2DMin)
Constructor.
bool gReorder() const
Get whether the Hamiltonian orbitals are reordered for the DMRG calculation.
int gIndex() const
Get the location index.
double getMutualInformation_HAM(const int row, const int col) const
Get a mutual information term, using the HAM indices.
double getMutualInformation_DMRG(const int row, const int col) const
Get a mutual information term, using the DMRG indices.
void FillSite(TensorT *denT, TensorGYZ **Gtensors, TensorGYZ **Ytensors, TensorGYZ **Ztensors, TensorKM **Ktensors, TensorKM **Mtensors)
Fill at the current step of the iterations the two-orbital mutual information and the remaining part ...
int gCurrentDim(const int boundary, const int N, const int TwoS, const int irrep) const
Get the current virtual dimensions.
void Print(const int precision=6, const int columnsPerLine=8) const
Print the correlation functions and two-orbital mutual information.
double getCdens_HAM(const int row, const int col) const
Get a Cdens term, using the HAM indices.
double getCdirad_HAM(const int row, const int col) const
Get a Cdirad term, using the HAM indices.
double SingleOrbitalEntropy_HAM(const int index) const
Get the single-orbital entropy for a certain site, using hte HAM indices.
double getTwoDMB_DMRG(const int cnt1, const int cnt2, const int cnt3, const int cnt4) const
Get a 2DM_B term, using the DMRG indices.
double SingleOrbitalEntropy_DMRG(const int index) const
Get the single-orbital entropy for a certain site, using the DMRG indices.
void mpi_broadcast()
Broadcast the diradical correlation function and the two-orbital mutual information.
double getCspin_HAM(const int row, const int col) const
Get a Cspin term, using the HAM indices.
int gTwoSmin(const int boundary, const int N) const
Get the minimum possible spin value for a certain boundary and particle number.
int gTwoSmax(const int boundary, const int N) const
Get the maximum possible spin value for a certain boundary and particle number.
double getCspinflip_HAM(const int row, const int col) const
Get a Cspinflip term, using the HAM indices.
double getCspin_DMRG(const int row, const int col) const
Get a Cspin term, using the DMRG indices.
int gTwoS() const
Get twice the targeted spin.
double * gStorage()
Get the pointer to the storage.
virtual ~Correlations()
Destructor.
double get1RDM_DMRG(const int cnt1, const int cnt2) const
Get a 1-RDM term, using the DMRG indices.
double getTwoDMA_DMRG(const int cnt1, const int cnt2, const int cnt3, const int cnt4) const
Get a 2DM_A term, using the DMRG indices.
double getCspinflip_DMRG(const int row, const int col) const
Get a Cspinflip term, using the DMRG indices.
double * gStorage()
Get the pointer to the storage.
double MutualInformationDistance(const double power) const
Return Idistance(power) (see return for definition)
int gf1(const int HamOrb) const
Get the DMRG index corresponding to a Ham index.
static int directProd(const int Irrep1, const int Irrep2)
Get the direct product of the irreps with numbers Irrep1 and Irrep2: a bitwise XOR for psi4's convent...
double getCdens_DMRG(const int row, const int col) const
Get a Cdens term, using the DMRG indices.
int getNumberOfIrreps() const
Get the total number of irreps.
int gL() const
Get the number of orbitals.
int gMaxDimAtBound(const int boundary) const
Get the maximum virtual dimension at a certain boundary.
int gNmax(const int boundary) const
Get the max. possible particle number for a certain boundary.
int gIrrep(const int orbital) const
Get an orbital irrep.
double getCdirad_DMRG(const int row, const int col) const
Get a Cdirad term, using the DMRG indices.