def contract_two_to_two(self, subscripts, two, out=None, factor=1.0, clear=True): """Contract self with a two-index to obtain a two-index. **Arguments:** subscripts Any of ``abcd,bd->ac`` (direct), ``abcd,cb->ad`` (exchange) two The input two-index object. (DenseTwoIndex) **Optional arguments:** out, factor, clear See :py:meth:`DenseLinalgFactory.einsum` """ check_options('subscripts', subscripts, 'abcd,bd->ac', 'abcd,cb->ad') if out is None: out = DenseTwoIndex(self.nbasis) if clear: out.clear() else: check_type('out', out, DenseTwoIndex) if subscripts == 'abcd,bd->ac': tmp = np.tensordot(self._array2, two._array, axes=([(1,2),(1,0)])) out._array[:] += factor*np.tensordot(self._array, tmp, [0,0]) elif subscripts == 'abcd,cb->ad': tmp = np.tensordot(self._array2, two._array, axes=([1,1])) out._array[:] += factor*np.tensordot(self._array, tmp, ([0,2],[0,2])) return out
def slice_to_two(self, subscripts, out=None, factor=1.0, clear=True): """Returns a two-index contraction of the four-index object. **Arguments:** subscripts Any of ``aabb->ab``, ``abab->ab``, ``abba->ab`` **Optional arguments:** out, factor, clear See :py:meth:`DenseLinalgFactory.einsum` """ # Error checking check_options('subscripts', subscripts, 'aabb->ab', 'abab->ab', 'abba->ab') # Handle output argument if out is None: out = DenseTwoIndex(self.nbasis) else: check_type('out', out, DenseTwoIndex) if clear: out.clear() # Actual computation if subscripts == 'aabb->ab': out._array[:] += factor*np.einsum('xab,xab->ab', self._array, self._array2) elif subscripts == 'abab->ab': out._array[:] += factor*np.einsum('xaa,xbb->ab', self._array, self._array2) elif subscripts == 'abba->ab': out._array[:] += factor*np.einsum('xab,xba->ab', self._array, self._array2) return out