KoehnLab / lizard

A quantum chemistry application used for the symbolic derivation and manipulation of equations based on second quantization.
BSD 3-Clause "New" or "Revised" License
1 stars 0 forks source link

Detect tensor element equality through different indexing #15

Open Krzmbrzl opened 1 year ago

Krzmbrzl commented 1 year ago

Consider the terms

I1[i⁺j⁺a⁻k⁻](/\/\) = - H[i⁺j⁺a⁻b⁻](....) T1[b⁺k⁻](..)

and

I2[i⁺j⁺a⁻k⁻](/\\/) = H[i⁺j⁺b⁻a⁻](....) T1[b⁺k⁻](..)

From this, it can be seen that the following relations between the intermediates:

I2[i⁺j⁺a⁻k](/\\/) = - I1[j⁺i⁺a⁻k⁻](/\/\)
ak-ustutt commented 1 year ago

Are these two intermediates occurring in two different contexts? For a single context (i.e. if the two terms in the example arise from one and the same term generated by GeCCo), we should avoid this by keeping the canonical initial indexing (i.e. the interchange of a and b in the "H" tensor should not happen). I think I need more context to give a more helpful comment without confusing everyone.

Krzmbrzl commented 1 year ago

In this specific example (CC2 singles residual) the terms are coming from the same diagram:

>>>> R1[a⁺i⁻](||) -= 0.5 * H[j⁺k⁺b⁻c⁻](||||) T1[b⁺i⁻](||) T2[a⁺c⁺j⁻k⁻](||||) <<<<
# of Terms: 4
- 1: {
  H_T1[i⁺j⁺a⁻k⁻](/\/\) -= H[i⁺j⁺a⁻b⁻](....) T1[b⁺k⁻](..)
}
- 2: {
  H_T1[i⁺j⁺a⁻k⁻](/\\/) += H[i⁺j⁺b⁻a⁻](....) T1[b⁺k⁻](..)
}
- 3: {
  H_T1[i⁺j⁺a⁻k⁻](////) -= H[i⁺j⁺a⁻b⁻](....) T1[b⁺k⁻](..)
  H_T1[i⁺j⁺a⁻k⁻](////) += H[i⁺j⁺b⁻a⁻](....) T1[b⁺k⁻](..)
}
- 4: {
  R1[a⁺i⁻](..) -= 0.5 * H_T1[j⁺k⁺b⁻i⁻](////) T2[a⁺b⁺j⁻k⁻](....)
  R1[a⁺i⁻](..) += 0.5 * H_T1[j⁺k⁺b⁻i⁻](////) T2[a⁺b⁺k⁻j⁻](....)
  R1[a⁺i⁻](..) -= H_T1[j⁺k⁺b⁻i⁻](/\\/) T2[a⁺b⁺j⁻k⁻](....)
}

As can be seen, in this case the abab spin case of H_T1 isn't even needed in the first place.

This issue isn't about optimizing a special case though. Rather it shall server as an example to test the general optimizer capabilities on, with the hope that when dealing with arbitrary inputs, this kind of optimization may end up being useful in some places.


we should avoid this by keeping the canonical initial indexing (i.e. the interchange of a and b in the "H" tensor should not happen).

see #16

ak-ustutt commented 1 year ago

The two intermediates are equivalent, indeed. This can be better understood by replacing the actual indices by their orbital space identifier (I think your considerations concerning introduction of the TensorBlock object were in this direction). If we use the ITF nomenclature: "e" external=virtual and "c" closed=occupied, the Intermediate is: H_T1[ccec] From this we see that the two creation indices (i and j) run over the same index space such that the assignment of either /\ or \/ does not make a difference (in the sense that these cases can be mapped to one unique element).

Two small comments:

The second issue may be a bit challenging in the general case, but we should keep an eye on it.