예제 #1
0
def from_cirq(state: numpy.ndarray,
              thresh: float) -> 'wavefunction.Wavefunction':
    """Interoperability between cirq and the openfermion-fqe.  This takes a
    cirq wavefunction and creates an FQE wavefunction object initialized with
    the correct data.

    Args:
        state (numpy.array(dtype=numpy.complex128)) - a cirq wavefunction

        thresh (double) - set the limit at which a cirq element should be \
            considered zero and not make a contribution to the FQE wavefunction

    Returns:
        openfermion-fqe.Wavefunction
    """
    param = []
    nqubits = int(numpy.log2(state.size))
    norb = nqubits // 2
    for pnum in range(nqubits + 1):
        occ = qubit_particle_number_index_spin(nqubits, pnum)
        for orb in occ:
            if numpy.absolute(state[orb[0]]) > thresh:
                param.append([pnum, orb[1], norb])
    param_set = set([tuple(p) for p in param])
    param_list = [list(x) for x in param_set]
    wfn = wavefunction.Wavefunction(param_list)
    transform.from_cirq(wfn, state)
    return wfn
    def test_fqe_to_fermion_operator(self):
        """Convert the fqe representation to openfermion operators.

        Note: Due to the unique OpenFermion data structure and the conversion
        of the data internally, test requires an iterative stucture rather than
        assertDictEqual
        """
        def _calc_coeff(val):
            return round(val / numpy.sqrt(30.0), 7) + .0j

        coeff = [
            _calc_coeff(1.0),
            _calc_coeff(2.0),
            _calc_coeff(3.0),
            _calc_coeff(4.0)
        ]

        data = numpy.array([[coeff[0]], [coeff[1]], [coeff[2]], [coeff[3]]],
                           dtype=numpy.complex128)

        test = FermionOperator('0^ 1^', coeff[0])
        test += FermionOperator('0^ 3^', coeff[1])
        test += FermionOperator('2^ 1^', coeff[2])
        test += FermionOperator('2^ 3^', coeff[3])
        wfn = wavefunction.Wavefunction([[2, 0, 2]])
        data = numpy.reshape(data, (2, 2))
        passed_data = {(2, 0): data}
        wfn.set_wfn(strategy='from_data', raw_data=passed_data)
        ops = openfermion_utils.fqe_to_fermion_operator(wfn)
        self.assertListEqual(list(ops.terms.keys()), list(test.terms.keys()))
        for term in ops.terms:
            self.assertAlmostEqual(ops.terms[term], test.terms[term])
예제 #3
0
    def test_operator(self):
        """Testing base FqeOperator using a dummy class"""

        # The Test class is just to make sure the Hamiltonian class is tested.
        # pylint: disable=useless-super-delegation
        class Test(fqe_operator.FqeOperator):
            """A testing dummy class."""
            def contract(
                self,
                brastate: "wavefunction.Wavefunction",
                ketstate: "wavefunction.Wavefunction",
            ) -> complex:
                return super().contract(brastate, ketstate)

            def representation(self) -> str:
                return super().representation()

            def rank(self) -> int:
                return super().rank()

        test = Test()
        wfn = wavefunction.Wavefunction([[1, 0, 1]])
        self.assertAlmostEqual(0.0 + 0.0j, test.contract(wfn, wfn))
        self.assertEqual("fqe-operator", test.representation())
        self.assertEqual(0, test.rank())
예제 #4
0
    def test_ops_general(self):
        """Check general properties of the fqe_ops."""
        s_2 = S2Operator()
        self.assertEqual(s_2.representation(), "s_2")
        self.assertEqual(s_2.rank(), 2)

        s_z = SzOperator()
        self.assertEqual(s_z.representation(), "s_z")
        self.assertEqual(s_z.rank(), 2)

        t_r = TimeReversalOp()
        self.assertEqual(t_r.representation(), "T")
        self.assertEqual(t_r.rank(), 2)

        num = NumberOperator()
        self.assertEqual(num.representation(), "N")
        self.assertEqual(num.rank(), 2)

        wfn = wavefunction.Wavefunction([[4, 2, 4], [4, 0, 4]])
        self.assertRaises(ValueError, t_r.contract, wfn, wfn)

        wfn = wavefunction.Wavefunction([[4, -2, 4], [4, 0, 4]])
        self.assertRaises(ValueError, t_r.contract, wfn, wfn)
예제 #5
0
def Wavefunction(param: List[List[int]],
                 broken: Optional[Union[List[str], str]] = None):
    """Initialize a wavefunction through the fqe namespace

    Args:
        param (List[List[int]]) - parameters for the sectors

        broken (Union[List[str], str]) - symmetry to be broken

    Returns:
        (wavefunction.Wavefunction) - a wavefunction object meeting the \
            criteria laid out in the calling argument
    """
    return wavefunction.Wavefunction(param, broken=broken)
예제 #6
0
def get_wavefunction(nele: int, m_s: int,
                     norb: int) -> 'wavefunction.Wavefunction':
    """Build a wavefunction with definite particle number and spin.

    Args:
        nele (int) - the number of electrons in the system

        m_s (int) - the s_z spin projection of the system

        norb (int) - the number of spatial orbtials to used

    Returns:
        (wavefunction.Wavefunction) - a wavefunction object meeting the \
            criteria laid out in the calling argument
    """
    arg = [[nele, m_s, norb]]
    return wavefunction.Wavefunction(param=arg)
예제 #7
0
def get_wavefunction_multiple(param: List[List[int]]
                             ) -> List['wavefunction.Wavefunction']:
    """Generate many different wavefunctions.

    Args:
        param (list[list[nele, m_s, norb]]) - a list of parameters used to \
            initialize wavefunctions.  The arguments in the parameters are

                nele (int) - the number of electrons in the system;
                m_s (int) - the s_z spin projection of the system;
                norb (int) - the number of spatial orbtials to used

    Returns:
        list[(wavefunction.Wavefunction)] - a list of wavefunction objects
    """
    state = []
    for val in param:
        state.append(wavefunction.Wavefunction(param=[val]))
    return state
예제 #8
0
def get_number_conserving_wavefunction(nele: int, norb: int
                                      ) -> 'wavefunction.Wavefunction':
    """Build a wavefunction

    Args:
        nele (int) - the number of electrons in the system

        norb (int) - the number of orbitals

    Returns:
        (wavefunction.Wavefunction) - a wavefunction object meeting the \
            criteria laid out in the calling argument
    """
    param = []
    maxb = min(norb, nele)
    minb = nele - maxb
    for nbeta in range(minb, maxb + 1):
        m_s = nele - nbeta * 2
        param.append([nele, m_s, norb])
    return wavefunction.Wavefunction(param, broken=['spin'])
예제 #9
0
def get_spin_conserving_wavefunction(s_z: int,
                                     norb: int) -> 'wavefunction.Wavefunction':
    """Return a wavefunction which has s_z conserved

    Args:
        s_z (int) - the value of :math:`S_z`

        norb (int) - the number of orbitals in the system

    Returns:
        (Wavefunction) - wave function initialized to zero
    """
    param = []
    if s_z >= 0:
        max_ele = norb + 1
        min_ele = s_z
    if s_z < 0:
        max_ele = norb + s_z + 1
        min_ele = 0

    for nalpha in range(min_ele, max_ele):
        param.append([2 * nalpha - s_z, s_z, norb])

    return wavefunction.Wavefunction(param, broken=['number'])