diff --git a/.pylintdict b/.pylintdict index 291cb12a96..7d314a76ee 100644 --- a/.pylintdict +++ b/.pylintdict @@ -140,6 +140,7 @@ eigenstate eigrange eigs eigvecs +einact einsum els endif @@ -159,6 +160,7 @@ excitations expr factorizers factr +fcidump fcompiler fermionic FermionicOperator @@ -224,6 +226,7 @@ indvar init initializer initio +inline innerproduct inreg instantiations @@ -239,6 +242,7 @@ ising isinstance iso isub +isym iteratively izaac jac @@ -249,6 +253,7 @@ jt jth jw kaicher +ket killoran kingma kitaev @@ -317,6 +322,7 @@ msq multiclass multinomial multiprocess +namelist nan narray nasdaq @@ -326,6 +332,7 @@ ndarray ndarray's negoro nelder +nelec neq nevals newtons's @@ -338,6 +345,7 @@ nn noancilla noint noqa +norb norbs nosignatures np @@ -350,14 +358,16 @@ objval occ oe ok -oneee +onee online onwards oplus optim optimizer's optimizers +orbsym org +outpath overfit params parentname @@ -581,4 +591,4 @@ zzz ucc uccd UCCS -vir \ No newline at end of file +vir diff --git a/qiskit/chemistry/drivers/__init__.py b/qiskit/chemistry/drivers/__init__.py index a8a9dc3e67..2e7580657a 100644 --- a/qiskit/chemistry/drivers/__init__.py +++ b/qiskit/chemistry/drivers/__init__.py @@ -2,7 +2,7 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2019. +# (C) Copyright IBM 2018, 2020. # # This code is licensed under the Apache License, Version 2.0. You may # obtain a copy of this license in the LICENSE.txt file in the root directory @@ -78,6 +78,7 @@ """ from ._basedriver import BaseDriver, UnitsType, HFMethodType +from .fcidumpd import FCIDumpDriver from .gaussiand import GaussianDriver from .hdf5d import HDF5Driver from .psi4d import PSI4Driver @@ -87,6 +88,7 @@ __all__ = ['BaseDriver', 'UnitsType', 'HFMethodType', + 'FCIDumpDriver', 'GaussianDriver', 'HDF5Driver', 'PSI4Driver', diff --git a/qiskit/chemistry/drivers/fcidumpd/__init__.py b/qiskit/chemistry/drivers/fcidumpd/__init__.py new file mode 100644 index 0000000000..be203f3048 --- /dev/null +++ b/qiskit/chemistry/drivers/fcidumpd/__init__.py @@ -0,0 +1,22 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +"""FCIDump driver package. + +Contains tools to parse and dump FCIDump files. +""" + +from .fcidumpdriver import FCIDumpDriver + +__all__ = ['FCIDumpDriver'] diff --git a/qiskit/chemistry/drivers/fcidumpd/dumper.py b/qiskit/chemistry/drivers/fcidumpd/dumper.py new file mode 100644 index 0000000000..7c8e29bc31 --- /dev/null +++ b/qiskit/chemistry/drivers/fcidumpd/dumper.py @@ -0,0 +1,122 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +"""FCIDump dumper.""" + +from typing import List, Optional +from io import TextIOWrapper +import itertools +import numpy as np + + +def dump(outpath: str, norb: int, nelec: int, hijs: List[float], hijkls: List[float], einact: float, + ms2: int = 0, orbsym: Optional[List[int]] = None, isym: int = 1 + ) -> None: + # pylint: disable=wrong-spelling-in-docstring + """Generates a FCIDump output. + + Args: + outpath: Path to the output file. + norb: The number of orbitals. + nelec: The number of electrons. + hijs: The pair of alpha and beta 1-electron integrals. The latter may be None. + hijkls: The triplet of alpha/alpha, beta/alpha and beta/beta 2-electron integrals. The + latter two may be None. + einact: The inactive energy. + ms2: 2*S, where S is the spin quantum number. + orbsym: A list of spatial symmetries of the orbitals. + isym: The spatial symmetry of the wave function. + """ + hij, hij_b = hijs + hijkl, hijkl_ba, hijkl_bb = hijkls + # assert that either all beta variables are None or all of them are not + assert all([h is None for h in [hij_b, hijkl_ba, hijkl_bb]]) \ + or all([h is not None for h in [hij_b, hijkl_ba, hijkl_bb]]) + assert norb == hij.shape[0] == hijkl.shape[0] + mos = range(norb) + with open(outpath, 'w') as outfile: + # print header + outfile.write('&FCI NORB={:4d},NELEC={:4d},MS2={:4d}\n'.format(norb, nelec, ms2)) + if orbsym is None: + outfile.write(' ORBSYM=' + '1,'*norb + '\n') + else: + assert len(orbsym) == norb + outfile.write(' ORBSYM=' + ','.join(orbsym) + '\n') + outfile.write(' ISYM={:d},\n/&END\n'.format(isym)) + # append 2e integrals + _dump_2e_ints(hijkl, mos, outfile) + if hijkl_ba is not None: + _dump_2e_ints(hijkl_ba.transpose(), mos, outfile, beta=1) + if hijkl_bb is not None: + _dump_2e_ints(hijkl_bb, mos, outfile, beta=2) + # append 1e integrals + _dump_1e_ints(hij, mos, outfile) + if hij_b is not None: + _dump_1e_ints(hij_b, mos, outfile, beta=True) + # TODO append MO energies (last three indices are 0) + # append inactive energy + _write_to_outfile(outfile, einact, (0, 0, 0, 0)) + + +def _dump_1e_ints(hij: List[float], mos: List[int], outfile: TextIOWrapper, + beta: bool = False) -> None: + idx_offset = 1 if not beta else 1+len(mos) + hij_elements = set() + for i, j in itertools.product(mos, repeat=2): + if i == j: + _write_to_outfile(outfile, hij[i][j], (i+idx_offset, j+idx_offset, 0, 0)) + continue + if (j, i) in hij_elements and np.isclose(hij[i][j], hij[j][i]): + continue + _write_to_outfile(outfile, hij[i][j], (i+idx_offset, j+idx_offset, 0, 0)) + hij_elements.add((i, j)) + + +def _dump_2e_ints(hijkl: List[float], mos: List[int], outfile: TextIOWrapper, + beta: int = 0) -> None: + idx_offsets = [1, 1] + for b in range(beta): + idx_offsets[1-b] += len(mos) + hijkl_elements = set() + # pylint: disable=invalid-name + for elem in itertools.product(mos, repeat=4): + if np.isclose(hijkl[elem], 0.0, atol=1e-14): + continue + if len(set(elem)) == 1: + _write_to_outfile(outfile, hijkl[elem], (*[e+idx_offsets[0] for e in elem[:2]], + *[e+idx_offsets[1] for e in elem[2:]])) + continue + if beta != 1 and elem[::-1] in hijkl_elements and \ + np.isclose(hijkl[elem], hijkl[elem[::-1]]): + continue + bra_perms = set(itertools.permutations(elem[:2])) + ket_perms = set(itertools.permutations(elem[2:])) + if beta == 1: + permutations = itertools.product(bra_perms, ket_perms) + else: + permutations = itertools.chain( + itertools.product(bra_perms, ket_perms), + itertools.product(ket_perms, bra_perms) + ) + for perm in {e1 + e2 for e1, e2 in permutations}: + if perm in hijkl_elements and np.isclose(hijkl[elem], hijkl[perm]): + break + else: + _write_to_outfile(outfile, hijkl[elem], (*[e+idx_offsets[0] for e in elem[:2]], + *[e+idx_offsets[1] for e in elem[2:]])) + hijkl_elements.add(elem) + + +def _write_to_outfile(outfile: str, value: float, indices: List[int]): + outfile.write('{:23.16E}{:4d}{:4d}{:4d}{:4d}\n'.format(value, *indices)) diff --git a/qiskit/chemistry/drivers/fcidumpd/fcidumpdriver.py b/qiskit/chemistry/drivers/fcidumpd/fcidumpdriver.py new file mode 100644 index 0000000000..f74a2af4ce --- /dev/null +++ b/qiskit/chemistry/drivers/fcidumpd/fcidumpdriver.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +"""FCIDump Driver.""" + +from typing import List, Optional +from qiskit.chemistry.drivers import BaseDriver +from qiskit.chemistry import QiskitChemistryError, QMolecule +from .dumper import dump +from .parser import parse + + +class FCIDumpDriver(BaseDriver): + """Python implementation of an FCIDump driver. + + The FCIDump format is partially defined in Knowles1989. + + References: + Knowles1989: Peter J. Knowles, Nicholas C. Handy, + A determinant based full configuration interaction program, + Computer Physics Communications, Volume 54, Issue 1, 1989, Pages 75-83, + ISSN 0010-4655, https://doi.org/10.1016/0010-4655(89)90033-7. + """ + + def __init__(self, fcidump_input: str, atoms: Optional[List[str]] = None) -> None: + """ + Args: + fcidump_input: Path to the FCIDump file. + atoms: Allows to specify the atom list of the molecule. If it is provided, the created + QMolecule instance will permit frozen core Hamiltonians. This list must consist of + valid atom symbols. + + Raises: + QiskitChemistryError: If ``fcidump_input`` is not a string or if ``atoms`` is not a list + of valid atomic symbols as specified in ``QMolecule``. + """ + super().__init__() + + if not isinstance(fcidump_input, str): + raise QiskitChemistryError( + "The fcidump_input must be str, not '{}'".format(fcidump_input)) + self._fcidump_input = fcidump_input + + if atoms and not isinstance(atoms, list) \ + and not all([sym in QMolecule.symbols for sym in atoms]): + raise QiskitChemistryError( + "The atoms must be a list of valid atomic symbols, not '{}'".format(atoms)) + self.atoms = atoms + + def run(self) -> QMolecule: + """Constructs a QMolecule instance out of a FCIDump file. + + Returns: + A QMolecule instance populated with a minimal set of required data. + """ + fcidump_data = parse(self._fcidump_input) + + q_mol = QMolecule() + + q_mol.nuclear_repulsion_energy = fcidump_data.get('ecore', None) + q_mol.num_orbitals = fcidump_data.get('NORB') + q_mol.multiplicity = fcidump_data.get('MS2', 0) + 1 + q_mol.charge = 0 # ensures QMolecule.log() works + q_mol.num_beta = (fcidump_data.get('NELEC') - (q_mol.multiplicity - 1)) // 2 + q_mol.num_alpha = fcidump_data.get('NELEC') - q_mol.num_beta + if self.atoms is not None: + q_mol.num_atoms = len(self.atoms) + q_mol.atom_symbol = self.atoms + q_mol.atom_xyz = [[float('NaN')] * 3] * len(self.atoms) # ensures QMolecule.log() works + + q_mol.mo_onee_ints = fcidump_data.get('hij', None) + q_mol.mo_onee_ints_b = fcidump_data.get('hij_b', None) + q_mol.mo_eri_ints = fcidump_data.get('hijkl', None) + q_mol.mo_eri_ints_bb = fcidump_data.get('hijkl_bb', None) + q_mol.mo_eri_ints_ba = fcidump_data.get('hijkl_ba', None) + + return q_mol + + @staticmethod + def dump(q_mol: QMolecule, outpath: str, orbsym: Optional[List[int]] = None, + isym: int = 1) -> None: + """Convenience method to produce an FCIDump output file. + + Args: + outpath: Path to the output file. + q_mol: QMolecule data to be dumped. It is assumed that the nuclear_repulsion_energy in + this QMolecule instance contains the inactive core energy. + orbsym: A list of spatial symmetries of the orbitals. + isym: The spatial symmetry of the wave function. + """ + dump(outpath, + q_mol.num_orbitals, q_mol.num_alpha + q_mol.num_beta, + (q_mol.mo_onee_ints, q_mol.mo_onee_ints_b), + (q_mol.mo_eri_ints, q_mol.mo_eri_ints_ba, q_mol.mo_eri_ints_bb), + q_mol.nuclear_repulsion_energy, ms2=q_mol.multiplicity - 1, orbsym=orbsym, isym=isym) diff --git a/qiskit/chemistry/drivers/fcidumpd/parser.py b/qiskit/chemistry/drivers/fcidumpd/parser.py new file mode 100644 index 0000000000..df7f6d73a7 --- /dev/null +++ b/qiskit/chemistry/drivers/fcidumpd/parser.py @@ -0,0 +1,241 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +"""FCIDump parser.""" + +from typing import Any, Dict, List, Set +import itertools +import re +import numpy as np + +from qiskit.chemistry import QiskitChemistryError + + +def parse(fcidump: str) -> Dict[str, Any]: + # pylint: disable=wrong-spelling-in-comment + """Parses a FCIDump output. + + Args: + fcidump: Path to the FCIDump file. + Raises: + QiskitChemistryError: If the input file cannot be found, if a required field in the FCIDump + file is missing, if wrong integral indices are encountered, or if the alpha/beta or + beta/alpha 2-electron integrals are mixed. + Returns: + A dictionary storing the parsed data. + """ + try: + with open(fcidump, 'r') as file: + fcidump_str = file.read() + except OSError: + raise QiskitChemistryError("Input file '{}' cannot be read!".format(fcidump)) + + output = {} + + # FCIDump starts with a Fortran namelist of meta data + namelist_end = re.search('(/|&END)', fcidump_str) + metadata = fcidump_str[:namelist_end.start(0)] + metadata = ' '.join(metadata.split()) # replace duplicate whitespace and newlines + # we know what elements to look for so we don't get too fancy with the parsing + # pattern explanation: + # .*? any text + # (*|*), match either part of this group followed by a comma + # [-+]? match up to a single - or + + # \d*.\d+ number format + pattern = r'.*?([-+]?\d*\.\d+|[-+]?\d+),' + # we parse the values in the order in which they are listed in Knowles1989 + _norb = re.search('NORB'+pattern, metadata) + if _norb is None: + raise QiskitChemistryError("The required NORB entry of the FCIDump format is missing!") + norb = int(_norb.groups()[0]) + output['NORB'] = norb + _nelec = re.search('NELEC'+pattern, metadata) + if _nelec is None: + raise QiskitChemistryError("The required NELEC entry of the FCIDump format is missing!") + output['NELEC'] = int(_nelec.groups()[0]) + # the rest of these values may occur and are set to their defaults otherwise + _ms2 = re.search('MS2'+pattern, metadata) + output['MS2'] = int(_ms2.groups()[0]) if _ms2 else 0 + _isym = re.search('ISYM'+pattern, metadata) + output['ISYM'] = int(_isym.groups()[0]) if _isym else 1 + # ORBSYM holds a list, thus it requires a little different treatment + _orbsym = re.search(r'ORBSYM.*?'+r'(\d+),'*norb, metadata) + output['ORBSYM'] = [int(s) for s in _orbsym.groups()] if _orbsym else [1] * len(norb) + _iprtim = re.search('IPRTIM'+pattern, metadata) + output['IPRTIM'] = int(_iprtim.groups()[0]) if _iprtim else -1 + _int = re.search('INT'+pattern, metadata) + output['INT'] = int(_int.groups()[0]) if _int else 5 + _memory = re.search('MEMORY'+pattern, metadata) + output['MEMORY'] = int(_memory.groups()[0]) if _memory else 10000 + _core = re.search('CORE'+pattern, metadata) + output['CORE'] = float(_core.groups()[0]) if _core else 0.0 + _maxit = re.search('MAXIT'+pattern, metadata) + output['MAXIT'] = int(_maxit.groups()[0]) if _maxit else 25 + _thr = re.search('THR'+pattern, metadata) + output['THR'] = float(_thr.groups()[0]) if _thr else 1e-5 + _thrres = re.search('THRRES'+pattern, metadata) + output['THRRES'] = float(_thrres.groups()[0]) if _thrres else 0.1 + _nroot = re.search('NROOT'+pattern, metadata) + output['NROOT'] = int(_nroot.groups()[0]) if _nroot else 1 + + # If the FCIDump file resulted from an unrestricted spin calculation the indices will label spin + # rather than molecular orbitals. This means, that a line must exist which encodes the + # coefficient for the spin orbital with index (norb*2, norb*2). By checking for such a line we + # can distinguish between unrestricted and restricted FCIDump files. + _uhf = bool(re.search(r'.*(\s+{}\s+{}\s+0\s+0)'.format(norb*2, norb*2), + fcidump_str[namelist_end.start(0):])) + + # the rest of the FCIDump will hold lines of the form x i a j b + # a few cases have to be treated differently: + # i, a, j and b are all zero: x is the core energy + # TODO: a, j and b are all zero: x is the energy of the i-th MO (often not supported) + # j and b are both zero: x is the 1e-integral between i and a (x = ) + # otherwise: x is the Coulomb integral ( x = (ia|jb) ) + hij = np.zeros((norb, norb)) + hij_elements = set(itertools.product(range(norb), repeat=2)) + hijkl = np.zeros((norb, norb, norb, norb)) + hijkl_elements = set(itertools.product(range(norb), repeat=4)) + hij_b = hijkl_ab = hijkl_ba = hijkl_bb = None + hij_b_elements = hijkl_ab_elements = hijkl_ba_elements = hijkl_bb_elements = set() + if _uhf: + beta_range = [n+norb for n in range(norb)] + hij_b = np.zeros((norb, norb)) + hij_b_elements = set(itertools.product(beta_range, repeat=2)) + hijkl_ab = np.zeros((norb, norb, norb, norb)) + hijkl_ba = np.zeros((norb, norb, norb, norb)) + hijkl_bb = np.zeros((norb, norb, norb, norb)) + hijkl_ab_elements = set(itertools.product( + range(norb), range(norb), beta_range, beta_range + )) + hijkl_ba_elements = set(itertools.product( + beta_range, beta_range, range(norb), range(norb) + )) + hijkl_bb_elements = set(itertools.product(beta_range, repeat=4)) + orbital_data = fcidump_str[namelist_end.end(0):].split('\n') + for orbital in orbital_data: + if not orbital: + continue + x = float(orbital.split()[0]) + # Note: differing naming than ijkl due to E741 and this iajb is inline with this: + # https://hande.readthedocs.io/en/latest/manual/integrals.html#fcidump-format + i, a, j, b = [int(i) for i in orbital.split()[1:]] # pylint: disable=invalid-name + if i == a == j == b == 0: + output['ecore'] = x + elif a == j == b == 0: + # TODO: x is the energy of the i-th MO + continue + elif j == b == 0: + try: + hij_elements.remove((i-1, a-1)) + hij[i-1][a-1] = x + except KeyError: + if _uhf: + hij_b_elements.remove((i-1, a-1)) + hij_b[i-1-norb][a-1-norb] = x + else: + raise QiskitChemistryError("Unkown 1-electron integral indices encountered in \ + '{}'".format((i, a))) + else: + try: + hijkl_elements.remove((i-1, a-1, j-1, b-1)) + hijkl[i-1][a-1][j-1][b-1] = x + except KeyError: + if _uhf: + try: + hijkl_ab_elements.remove((i-1, a-1, j-1, b-1)) + hijkl_ab[i-1][a-1][j-1-norb][b-1-norb] = x + except KeyError: + try: + hijkl_ba_elements.remove((i-1, a-1, j-1, b-1)) + hijkl_ba[i-1-norb][a-1-norb][j-1][b-1] = x + except KeyError: + hijkl_bb_elements.remove((i-1, a-1, j-1, b-1)) + hijkl_bb[i-1-norb][a-1-norb][j-1-norb][b-1-norb] = x + else: + raise QiskitChemistryError("Unkown 2-electron integral indices encountered in \ + '{}'".format((i, a, j, b))) + + # iterate over still empty elements in 1-electron matrix and populate with symmetric ones + # if any elements are not populated these will be zero + _permute_1e_ints(hij, hij_elements, norb) + + if _uhf: + # do the same for beta spin + _permute_1e_ints(hij_b, hij_b_elements, norb, beta=True) + + # do the same of the 2-electron 4D matrix + _permute_2e_ints(hijkl, hijkl_elements, norb) + + if _uhf: + # do the same for beta spin + _permute_2e_ints(hijkl_bb, hijkl_bb_elements, norb, beta=2) + _permute_2e_ints(hijkl_ab, hijkl_ab_elements, norb, beta=1) + _permute_2e_ints(hijkl_ba, hijkl_ba_elements, norb, beta=1) + + # assert that EITHER hijkl_ab OR hijkl_ba were given + if np.allclose(hijkl_ab, 0.0) == np.allclose(hijkl_ba, 0.0): + raise QiskitChemistryError("Encountered mixed sets of indices for the 2-electron \ + integrals. Either alpha/beta or beta/alpha matrix should be specified.") + + if np.allclose(hijkl_ba, 0.0): + hijkl_ba = hijkl_ab.transpose() + + output['hij'] = hij + output['hij_b'] = hij_b + output['hijkl'] = hijkl + output['hijkl_ba'] = hijkl_ba + output['hijkl_bb'] = hijkl_bb + + return output + + +def _permute_1e_ints(hij: List[float], elements: Set[int], norb: int, + beta: bool = False) -> None: + for elem in elements.copy(): + shifted = tuple(e-(beta * norb) for e in elem) + hij[shifted] = hij[shifted[::-1]] + elements.remove(elem) + + +def _permute_2e_ints(hijkl: List[float], elements: Set[int], norb: int, + beta: bool = False) -> None: + # pylint: disable=wrong-spelling-in-comment + for elem in elements.copy(): + shifted = tuple(e-((e >= norb) * norb) for e in elem) + # initially look for "transposed" element if spins are equal + if beta != 1 and elem[::-1] not in elements: + hijkl[shifted] = hijkl[shifted[::-1]] + elements.remove(elem) + continue + # then look at permutations of indices within the bra and ket respectively + bra_perms = set(itertools.permutations(elem[:2])) + ket_perms = set(itertools.permutations(elem[2:])) + if beta == 1: + # generally (ij|ab) != (ab|ij) + # thus, the possible permutations are much less when the spins differ + permutations = itertools.product(bra_perms, ket_perms) + else: + # ( ij | kl ) gives { ( ij | kl ), ( ij | lk ), ( ji | kl ), ( ji | lk ) } + # AND { ( kl | ij ), ( kl | ji ), ( lk | ij ), ( lk | ji ) } + # BUT NOT ( ik | jl ) etc. + permutations = itertools.chain( + itertools.product(bra_perms, ket_perms), + itertools.product(ket_perms, bra_perms) + ) + for perm in {e1 + e2 for e1, e2 in permutations}: + if perm in elements: + continue + hijkl[shifted] = hijkl[tuple([e-((e >= norb) * norb) for e in perm])] + elements.remove(elem) + break diff --git a/qiskit/chemistry/qmolecule.py b/qiskit/chemistry/qmolecule.py index b4a6322763..fe505d8398 100644 --- a/qiskit/chemistry/qmolecule.py +++ b/qiskit/chemistry/qmolecule.py @@ -2,7 +2,7 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2019 +# (C) Copyright IBM 2018, 2020. # # This code is licensed under the Apache License, Version 2.0. You may # obtain a copy of this license in the LICENSE.txt file in the root directory @@ -14,6 +14,7 @@ """ QMolecule """ +from typing import List import os import logging import tempfile @@ -137,8 +138,14 @@ def Z(self, natom): # pylint: disable=invalid-name return QMolecule.symbols.index(self.atom_symbol[natom].lower().capitalize()) @property - def core_orbitals(self): - """ returns core orbitals """ + def core_orbitals(self) -> List[int]: + """ + Returns: + A list of core orbital indices. + """ + if self.num_atoms is None: + logger.warning("Missing molecule information! Returning empty core orbital list.") + return [] count = 0 for i in range(self.num_atoms): z = self.Z(i) @@ -552,8 +559,9 @@ def log(self): logger.info("Computed Hartree-Fock energy: %s", self.hf_energy) logger.info("Nuclear repulsion energy: %s", self.nuclear_repulsion_energy) - logger.info("One and two electron Hartree-Fock energy: %s", - self.hf_energy - self.nuclear_repulsion_energy) + if None not in (self.hf_energy, self.nuclear_repulsion_energy): + logger.info("One and two electron Hartree-Fock energy: %s", + self.hf_energy - self.nuclear_repulsion_energy) logger.info("Number of orbitals is %s", self.num_orbitals) logger.info("%s alpha and %s beta electrons", self.num_alpha, self.num_beta) logger.info("Molecule comprises %s atoms and in xyz format is ::", self.num_atoms) diff --git a/test/chemistry/test_driver.py b/test/chemistry/test_driver.py index a7a11dc6e8..40b7048061 100644 --- a/test/chemistry/test_driver.py +++ b/test/chemistry/test_driver.py @@ -2,7 +2,7 @@ # This code is part of Qiskit. # -# (C) Copyright IBM 2018, 2019. +# (C) Copyright IBM 2018, 2020. # # This code is licensed under the Apache License, Version 2.0. You may # obtain a copy of this license in the LICENSE.txt file in the root directory @@ -27,7 +27,7 @@ def __init__(self): @abstractmethod def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None): - """ asset Almost Equal """ + """ assert Almost Equal """ raise Exception('Abstract method') @abstractmethod @@ -106,7 +106,7 @@ def test_driver_orbital_energies(self): [-0.5806, 0.6763], decimal=4) def test_driver_mo_onee_ints(self): - """ driver mo oneee ints test """ + """ driver mo onee ints test """ self.log.debug('QMolecule MO one electron integrals {}'.format(self.qmolecule.mo_onee_ints)) self.assertEqual(self.qmolecule.mo_onee_ints.shape, (2, 2)) np.testing.assert_array_almost_equal(np.absolute(self.qmolecule.mo_onee_ints), diff --git a/test/chemistry/test_driver_fcidump.py b/test/chemistry/test_driver_fcidump.py new file mode 100644 index 0000000000..a3eb9c62e6 --- /dev/null +++ b/test/chemistry/test_driver_fcidump.py @@ -0,0 +1,188 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" Test Driver FCIDump """ + +import unittest +from abc import ABC, abstractmethod +from test.chemistry import QiskitChemistryTestCase +import numpy as np +from qiskit.chemistry.drivers import FCIDumpDriver + + +class BaseTestDriverFCIDump(ABC): + """FCIDump Driver base test class. + + In contrast to the other driver tests this one does *not* derive from TestDriver because the + interface is fundamentally different. + """ + + def __init__(self): + self.log = None + self.qmolecule = None + self.nuclear_repulsion_energy = None + self.num_orbitals = None + self.num_alpha = None + self.num_beta = None + self.mo_onee = None + self.mo_onee_b = None + self.mo_eri = None + self.mo_eri_ba = None + self.mo_eri_bb = None + + @abstractmethod + def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None): + """ assert Almost Equal """ + raise Exception('Abstract method') + + @abstractmethod + def assertEqual(self, first, second, msg=None): + """ assert equal """ + raise Exception('Abstract method') + + @abstractmethod + def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): + """ assert Sequence Equal """ + raise Exception('Abstract method') + + def test_driver_inactive_energy(self): + """ driver inactive energy test """ + self.log.debug('QMolecule inactive energy is {}'.format( + self.qmolecule.nuclear_repulsion_energy)) + self.assertAlmostEqual(self.qmolecule.nuclear_repulsion_energy, + self.nuclear_repulsion_energy, places=3) + + def test_driver_num_orbitals(self): + """ driver num orbitals test """ + self.log.debug('QMolecule Number of orbitals is {}'.format(self.qmolecule.num_orbitals)) + self.assertEqual(self.qmolecule.num_orbitals, self.num_orbitals) + + def test_driver_num_alpha(self): + """ driver num alpha test """ + self.log.debug('QMolecule Number of alpha electrons is {}'.format(self.qmolecule.num_alpha)) + self.assertEqual(self.qmolecule.num_alpha, self.num_alpha) + + def test_driver_num_beta(self): + """ driver num beta test """ + self.log.debug('QMolecule Number of beta electrons is {}'.format(self.qmolecule.num_beta)) + self.assertEqual(self.qmolecule.num_beta, self.num_beta) + + def test_driver_mo_onee_ints(self): + """ driver alpha mo onee ints test """ + self.log.debug('QMolecule MO alpha one electron integrals are {}'.format( + self.qmolecule.mo_onee_ints)) + self.assertEqual(self.qmolecule.mo_onee_ints.shape, self.mo_onee.shape) + np.testing.assert_array_almost_equal(np.absolute(self.qmolecule.mo_onee_ints), + np.absolute(self.mo_onee), decimal=4) + + def test_driver_mo_onee_b_ints(self): + """ driver beta mo onee ints test """ + if self.mo_onee_b is None: + return + self.log.debug('QMolecule MO beta one electron integrals are {}'.format( + self.qmolecule.mo_onee_ints_b)) + self.assertEqual(self.qmolecule.mo_onee_ints_b.shape, self.mo_onee_b.shape) + np.testing.assert_array_almost_equal(np.absolute(self.qmolecule.mo_onee_ints_b), + np.absolute(self.mo_onee_b), decimal=4) + + def test_driver_mo_eri_ints(self): + """ driver alpha-alpha mo eri ints test """ + self.log.debug('QMolecule MO alpha-alpha two electron integrals are {}'.format( + self.qmolecule.mo_eri_ints)) + self.assertEqual(self.qmolecule.mo_eri_ints.shape, self.mo_eri.shape) + np.testing.assert_array_almost_equal(np.absolute(self.qmolecule.mo_eri_ints), + np.absolute(self.mo_eri), decimal=4) + + def test_driver_mo_eri_ints_ba(self): + """ driver beta-alpha mo eri ints test """ + if self.mo_eri_ba is None: + return + self.log.debug('QMolecule MO beta-alpha two electron integrals are {}'.format( + self.qmolecule.mo_eri_ints_ba)) + self.assertEqual(self.qmolecule.mo_eri_ints_ba.shape, self.mo_eri_ba.shape) + np.testing.assert_array_almost_equal(np.absolute(self.qmolecule.mo_eri_ints_ba), + np.absolute(self.mo_eri_ba), decimal=4) + + def test_driver_mo_eri_ints_bb(self): + """ driver beta-beta mo eri ints test """ + if self.mo_eri_bb is None: + return + self.log.debug('QMolecule MO beta-beta two electron integrals are {}'.format( + self.qmolecule.mo_eri_ints_bb)) + self.assertEqual(self.qmolecule.mo_eri_ints_bb.shape, self.mo_eri_bb.shape) + np.testing.assert_array_almost_equal(np.absolute(self.qmolecule.mo_eri_ints_bb), + np.absolute(self.mo_eri_bb), decimal=4) + + +class TestDriverFCIDumpH2(QiskitChemistryTestCase, BaseTestDriverFCIDump): + """RHF FCIDump Driver tests.""" + + def setUp(self): + super().setUp() + self.nuclear_repulsion_energy = 0.7199 + self.num_orbitals = 2 + self.num_alpha = 1 + self.num_beta = 1 + self.mo_onee = np.array([[1.2563, 0.0], [0.0, 0.4719]]) + self.mo_onee_b = None + self.mo_eri = np.array([[[[0.6757, 0.0], [0.0, 0.6646]], + [[0.0, 0.1809], [0.1809, 0.0]]], + [[[0.0, 0.1809], [0.1809, 0.0]], + [[0.6646, 0.0], [0.0, 0.6986]]]]) + self.mo_eri_ba = None + self.mo_eri_bb = None + driver = FCIDumpDriver(self.get_resource_path('test_driver_fcidump_h2.fcidump')) + self.qmolecule = driver.run() + + +class TestDriverFCIDumpLiH(QiskitChemistryTestCase, BaseTestDriverFCIDump): + """RHF FCIDump Driver tests.""" + + def setUp(self): + super().setUp() + self.nuclear_repulsion_energy = 0.9924 + self.num_orbitals = 6 + self.num_alpha = 2 + self.num_beta = 2 + loaded = np.load(self.get_resource_path('test_driver_fcidump_lih.npz')) + self.mo_onee = loaded['mo_onee'] + self.mo_onee_b = None + self.mo_eri = loaded['mo_eri'] + self.mo_eri_ba = None + self.mo_eri_bb = None + driver = FCIDumpDriver(self.get_resource_path('test_driver_fcidump_lih.fcidump')) + self.qmolecule = driver.run() + + +class TestDriverFCIDumpOH(QiskitChemistryTestCase, BaseTestDriverFCIDump): + """RHF FCIDump Driver tests.""" + + def setUp(self): + super().setUp() + self.nuclear_repulsion_energy = 11.3412 + self.num_orbitals = 6 + self.num_alpha = 5 + self.num_beta = 4 + loaded = np.load(self.get_resource_path('test_driver_fcidump_oh.npz')) + self.mo_onee = loaded['mo_onee'] + self.mo_onee_b = loaded['mo_onee_b'] + self.mo_eri = loaded['mo_eri'] + self.mo_eri_ba = loaded['mo_eri_ba'] + self.mo_eri_bb = loaded['mo_eri_bb'] + driver = FCIDumpDriver(self.get_resource_path('test_driver_fcidump_oh.fcidump')) + self.qmolecule = driver.run() + + +if __name__ == '__main__': + unittest.main() diff --git a/test/chemistry/test_driver_fcidump_dumper.py b/test/chemistry/test_driver_fcidump_dumper.py new file mode 100644 index 0000000000..6bf75ff126 --- /dev/null +++ b/test/chemistry/test_driver_fcidump_dumper.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" Test Driver FCIDump Dumping """ + +import tempfile +import unittest +from abc import ABC, abstractmethod +from test.chemistry import QiskitChemistryTestCase +import numpy as np +from qiskit.chemistry import QiskitChemistryError +from qiskit.chemistry.drivers import FCIDumpDriver, PySCFDriver, UnitsType + + +class BaseTestDriverFCIDumpDumper(ABC): + """FCIDump Driver dumping base test class.""" + + def __init__(self): + self.log = None + self.dumped = None + self.core_energy = None + self.num_orbitals = None + self.num_electrons = None + self.spin_number = None + self.wf_symmetry = None + self.orb_symmetries = None + self.mo_onee = None + self.mo_eri = None + + @abstractmethod + def assertAlmostEqual(self, first, second, places=None, msg=None, delta=None): + """ assert Almost Equal """ + raise Exception('Abstract method') + + @abstractmethod + def assertEqual(self, first, second, msg=None): + """ assert equal """ + raise Exception('Abstract method') + + @abstractmethod + def assertSequenceEqual(self, seq1, seq2, msg=None, seq_type=None): + """ assert Sequence Equal """ + raise Exception('Abstract method') + + def test_dumped_inactive_energy(self): + """ dumped inactive energy test """ + self.log.debug('Dumped inactive energy is {:g}'.format(self.dumped['ECORE'])) + self.assertAlmostEqual(self.dumped['ECORE'], self.core_energy, places=3) + + def test_dumped_num_orbitals(self): + """ dumped number of orbitals test """ + self.log.debug('Dumped number of orbitals is {:d}'.format(self.dumped['NORB'])) + self.assertEqual(self.dumped['NORB'], self.num_orbitals) + + def test_dumped_num_electrons(self): + """ dumped number of electrons test """ + self.log.debug('Dumped number of electrons is {:d}'.format(self.dumped['NELEC'])) + self.assertEqual(self.dumped['NELEC'], self.num_electrons) + + def test_dumped_spin_number(self): + """ dumped spin number test """ + self.log.debug('Dumped spin number is {:d}'.format(self.dumped['MS2'])) + self.assertEqual(self.dumped['MS2'], self.spin_number) + + def test_dumped_wave_function_sym(self): + """ dumped wave function symmetry test """ + self.log.debug('Dumped wave function symmetry is {:d}'.format(self.dumped['ISYM'])) + self.assertEqual(self.dumped['ISYM'], self.wf_symmetry) + + def test_dumped_orbital_syms(self): + """ dumped orbital symmetries test """ + self.log.debug('Dumped orbital symmetries is %s', self.dumped['ORBSYM']) + self.assertEqual(self.dumped['ORBSYM'], self.orb_symmetries) + + def test_dumped_h1(self): + """ dumped h1 integrals test """ + self.log.debug('Dumped h1 integrals are %s', self.dumped['H1']) + np.testing.assert_array_almost_equal(np.absolute(self.dumped['H1']), + np.absolute(self.mo_onee), decimal=4) + + def test_dumped_h2(self): + """ dumped h2 integrals test """ + self.log.debug('Dumped h2 integrals are %s', self.dumped['H2']) + np.testing.assert_array_almost_equal(np.absolute(self.dumped['H2']), + np.absolute(self.mo_eri), decimal=4) + + +class TestDriverFCIDumpDumpH2(QiskitChemistryTestCase, BaseTestDriverFCIDumpDumper): + """RHF FCIDump Driver tests.""" + + def setUp(self): + super().setUp() + self.core_energy = 0.7199 + self.num_orbitals = 2 + self.num_electrons = 2 + self.spin_number = 0 + self.wf_symmetry = 1 + self.orb_symmetries = [1, 1] + self.mo_onee = [[1.2563, 0.0], [0.0, 0.4719]] + self.mo_eri = [0.6757, 0.0, 0.1809, 0.6646, 0.0, 0.6986] + try: + driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735', + unit=UnitsType.ANGSTROM, + charge=0, + spin=0, + basis='sto3g') + except QiskitChemistryError: + self.skipTest('PYSCF driver does not appear to be installed') + + qmolecule = driver.run() + + dump = tempfile.NamedTemporaryFile() + FCIDumpDriver.dump(qmolecule, dump.name) + + from pyscf.tools import fcidump as pyscf_fcidump # pylint: disable=import-outside-toplevel + self.dumped = pyscf_fcidump.read(dump.name) + + dump.close() + + +if __name__ == '__main__': + unittest.main() diff --git a/test/chemistry/test_driver_fcidump_h2.fcidump b/test/chemistry/test_driver_fcidump_h2.fcidump new file mode 100644 index 0000000000..973cf4b89a --- /dev/null +++ b/test/chemistry/test_driver_fcidump_h2.fcidump @@ -0,0 +1,12 @@ +&FCI NORB= 2,NELEC= 2,MS2= 0, + ORBSYM=1,1, + ISYM=0, + / + 6.7571015480351648E-01 1 1 1 1 + 6.6458173025529665E-01 1 1 2 2 + 1.8093119978423133E-01 1 2 1 2 + 6.9857372273201834E-01 2 2 2 2 +-1.2563390730032502E+00 1 1 0 0 +-2.3575299028703285E-16 1 2 0 0 +-4.7189600728114062E-01 2 2 0 0 + 7.1996899444897966E-01 0 0 0 0 diff --git a/test/chemistry/test_driver_fcidump_lih.fcidump b/test/chemistry/test_driver_fcidump_lih.fcidump new file mode 100644 index 0000000000..02f77b8063 --- /dev/null +++ b/test/chemistry/test_driver_fcidump_lih.fcidump @@ -0,0 +1,128 @@ +&FCI NORB= 6,NELEC= 4,MS2= 0, + ORBSYM=1,1,1,1,1,1, + ISYM=0, + / + 1.6586546376776659E+00 1 1 1 1 +-1.1185240211600889E-01 1 1 1 2 + 1.3848665625981069E-01 1 1 1 3 + 1.1480489585912616E-12 1 1 1 4 + 5.3156150905632020E-02 1 1 1 6 + 3.6672307192919318E-01 1 1 2 2 +-1.3490862041788740E-02 1 1 2 3 +-4.1444544917724473E-02 1 1 2 6 + 3.9560609300166527E-01 1 1 3 3 +-1.7570190757927876E-02 1 1 3 6 + 3.9615805756229605E-01 1 1 4 4 + 3.9615805756231426E-01 1 1 5 5 + 3.6156268752540510E-01 1 1 6 6 + 1.3361925233149283E-02 1 2 1 2 +-1.1220132228289466E-02 1 2 1 3 +-8.9193406150758145E-03 1 2 1 6 + 6.1864696170519356E-03 1 2 2 2 + 3.3624105319467082E-03 1 2 2 3 + 4.6968249080026094E-03 1 2 2 6 +-1.1076181824135573E-02 1 2 3 3 + 3.6636805364300491E-03 1 2 3 6 +-4.3826190559740179E-03 1 2 4 4 +-4.3826190559700749E-03 1 2 5 5 + 3.2605442674869881E-03 1 2 6 6 + 2.1650293378449925E-02 1 3 1 3 + 2.3597082406981952E-03 1 3 1 6 + 1.5927544903074058E-02 1 3 2 2 + 1.9457359831490838E-04 1 3 2 3 +-5.7994711121253336E-04 1 3 2 6 +-1.8364753300464771E-03 1 3 3 3 + 4.4001136995770957E-03 1 3 3 6 + 5.0103349844383832E-03 1 3 4 4 + 5.0103349844262289E-03 1 3 5 5 + 1.1416837042889703E-02 1 3 6 6 + 9.8198689221677370E-03 1 4 1 4 + 7.5164446293970412E-03 1 4 2 4 +-1.0272658234905148E-02 1 4 3 4 +-6.1418191132375502E-03 1 4 4 6 + 9.8198689221912529E-03 1 5 1 5 + 7.5164446294140033E-03 1 5 2 5 +-1.0272658234932364E-02 1 5 3 5 +-6.1418191132447050E-03 1 5 5 6 + 8.5520281395617993E-03 1 6 1 6 +-6.8305742787635928E-03 1 6 2 2 +-1.7070775019968380E-03 1 6 2 3 + 1.2089575141012997E-04 1 6 2 6 + 1.0473652589391213E-02 1 6 3 3 +-4.2963064292415630E-03 1 6 3 6 + 6.0733702880809708E-04 1 6 4 4 + 6.0733702880693037E-04 1 6 5 5 +-3.0763611785068596E-03 1 6 6 6 + 4.8696923615603571E-01 2 2 2 2 + 4.8673192906504369E-02 2 2 2 3 + 1.2682585153426007E-01 2 2 2 6 + 2.2207684582544082E-01 2 2 3 3 + 5.1725041788584156E-02 2 2 3 6 + 2.6931057460912416E-01 2 2 4 4 + 2.6931057460913743E-01 2 2 5 5 + 4.5344862228143717E-01 2 2 6 6 + 1.3074357366741222E-02 2 3 2 3 + 3.4532278168798614E-02 2 3 2 6 +-7.6521522213230837E-03 2 3 3 3 + 9.5005232735582892E-03 2 3 3 6 +-5.7112650518622958E-03 2 3 4 4 +-5.7112650518572963E-03 2 3 5 5 + 4.3501724977949845E-02 2 3 6 6 + 2.3612689364016230E-02 2 4 2 4 +-1.9660010050143773E-02 2 4 3 4 +-1.9736571778768752E-02 2 4 4 6 + 2.3612689364026114E-02 2 5 2 5 +-1.9660010050139950E-02 2 5 3 5 +-1.9736571778750635E-02 2 5 5 6 + 1.2383163324182184E-01 2 6 2 6 +-1.1902300947385589E-02 2 6 3 3 + 3.1858316517801188E-02 2 6 3 6 +-1.5864225587806421E-02 2 6 4 4 +-1.5864225587796446E-02 2 6 5 5 + 1.3454832317431481E-01 2 6 6 6 + 3.3745516239657347E-01 3 3 3 3 +-3.6097312553601379E-02 3 3 3 6 + 2.8072389691079030E-01 3 3 4 4 + 2.8072389691079774E-01 3 3 5 5 + 2.3939716830479155E-01 3 3 6 6 + 4.1574401040021657E-02 3 4 3 4 + 1.4171696707401834E-02 3 4 4 6 + 4.1574401040012310E-02 3 5 3 5 + 1.4171696707380650E-02 3 5 5 6 + 2.6484660219304429E-02 3 6 3 6 +-2.1453620360574097E-03 3 6 4 4 +-2.1453620360655104E-03 3 6 5 5 + 4.4525329121800961E-02 3 6 6 6 + 3.1126171165226496E-01 4 4 4 4 +-3.3192265569307155E-07 4 4 4 5 + 2.7803357200249446E-01 4 4 5 5 + 2.6678403197166090E-01 4 4 6 6 + 1.6765218621834339E-02 4 5 4 5 + 3.3192265588819713E-07 4 5 5 5 + 1.9844263796503305E-02 4 6 4 6 + 3.1126171165226457E-01 5 5 5 5 + 2.6678403197164940E-01 5 5 6 6 + 1.9844263796465179E-02 5 6 5 6 + 4.5318537347316701E-01 6 6 6 6 +-4.7274928345697500E+00 1 1 0 0 + 1.0566592300600668E-01 1 2 0 0 +-1.6697933722736052E-01 1 3 0 0 +-1.1477850544437628E-12 1 4 0 0 + 2.9699404559664083E-17 1 5 0 0 +-3.4798155871967530E-02 1 6 0 0 +-1.4926089003683276E+00 2 2 0 0 +-3.2911492320197279E-02 2 3 0 0 +-1.0062808512802502E-15 2 4 0 0 + 5.5865269181193328E-17 2 5 0 0 +-5.2856194853614598E-02 2 6 0 0 +-1.1246113418866224E+00 3 3 0 0 +-3.6185603973485621E-16 3 4 0 0 + 2.8998241944651825E-17 3 5 0 0 +-3.1417780899706871E-02 3 6 0 0 +-1.1347793078137312E+00 4 4 0 0 +-1.0151507269873706E-16 4 5 0 0 +-2.1038003802663802E-16 4 6 0 0 +-1.1347793078136172E+00 5 5 0 0 +-8.9271852787184578E-18 5 6 0 0 +-9.5059645051377517E-01 6 6 0 0 + 9.9239946791345224E-01 0 0 0 0 diff --git a/test/chemistry/test_driver_fcidump_lih.npz b/test/chemistry/test_driver_fcidump_lih.npz new file mode 100644 index 0000000000..5287032ddd Binary files /dev/null and b/test/chemistry/test_driver_fcidump_lih.npz differ diff --git a/test/chemistry/test_driver_fcidump_oh.fcidump b/test/chemistry/test_driver_fcidump_oh.fcidump new file mode 100644 index 0000000000..8fdc76614c --- /dev/null +++ b/test/chemistry/test_driver_fcidump_oh.fcidump @@ -0,0 +1,625 @@ +&FCI NORB= 6,NELEC= 9,MS2= 0, + ORBSYM=1,1,1,1,1,1, + ISYM=0, + / + 8.3932976385361187E+00 1 1 1 1 + 1.1397638067939933E+00 1 1 1 2 +-4.0815571479588941E-01 1 1 1 3 +-3.5796008385929779E-11 1 1 1 5 +-4.1162429351360125E-01 1 1 1 6 + 1.3975060539424409E+00 1 1 2 2 +-1.9635337204790776E-01 1 1 2 3 +-9.6794427348050918E-12 1 1 2 5 +-3.2718822280409504E-01 1 1 2 6 + 1.1173573829376495E+00 1 1 3 3 +-6.5489221332099921E-12 1 1 3 5 +-3.2971698011317752E-01 1 1 3 6 + 1.3344266219316934E+00 1 1 4 4 + 1.3344266219315311E+00 1 1 5 5 +-9.6465873591004049E-12 1 1 5 6 + 9.9560561375745127E-01 1 1 6 6 + 1.9160079862834287E-01 1 2 1 2 +-6.6222024211216091E-02 1 2 1 3 +-5.6400516858516186E-12 1 2 1 5 +-7.1866418705512372E-02 1 2 1 6 + 8.8263124878437405E-02 1 2 2 2 +-2.2896587649139957E-02 1 2 2 3 +-1.8469267138669646E-12 1 2 2 5 +-2.4010503240357594E-02 1 2 2 6 + 5.6230117079805693E-02 1 2 3 3 +-1.6088419774556044E-02 1 2 3 6 + 6.4060934081906301E-02 1 2 4 4 + 6.4060934081936444E-02 1 2 5 5 + 4.8620922991837859E-02 1 2 6 6 + 3.8177132549354120E-02 1 3 1 3 + 1.6429939823265163E-12 1 3 1 5 + 1.0132775543765963E-02 1 3 1 6 +-4.0097076151456919E-02 1 3 2 2 +-1.3294808955434214E-02 1 3 2 3 + 1.1280452114196527E-12 1 3 2 5 + 2.4641439203630433E-02 1 3 2 6 +-1.0679421411374372E-02 1 3 3 3 + 7.7174543960997928E-04 1 3 3 6 +-2.2988927822968800E-02 1 3 4 4 +-2.2988927822990862E-02 1 3 5 5 +-3.0264726068228505E-02 1 3 6 6 + 2.5638292877003522E-02 1 4 1 4 +-3.4091771711064076E-02 1 4 2 4 + 1.1456652921713609E-02 1 4 3 4 + 1.1326267629617404E-12 1 4 4 5 + 1.0374389483416140E-02 1 4 4 6 + 2.5638292876982608E-02 1 5 1 5 + 1.6103047932103540E-12 1 5 1 6 +-3.5538843589485932E-12 1 5 2 2 + 1.3963358363187664E-12 1 5 2 3 +-3.4091771710975174E-02 1 5 2 5 + 1.6150111887084078E-12 1 5 2 6 +-1.6410230779689067E-12 1 5 3 3 + 1.1456652921674214E-02 1 5 3 5 +-1.2197318342089742E-12 1 5 4 4 + 1.0107716436940133E-12 1 5 5 5 + 1.0374389483414116E-02 1 5 5 6 +-1.4952649221721107E-12 1 5 6 6 + 4.1143815648829324E-02 1 6 1 6 +-2.4287318775890097E-02 1 6 2 2 + 2.7793029226624324E-02 1 6 2 3 + 1.2851329118660713E-12 1 6 2 5 +-6.0711501577723793E-03 1 6 2 6 +-2.9242260894106059E-02 1 6 3 3 + 1.0684113127057948E-02 1 6 3 6 +-2.2723591363929131E-02 1 6 4 4 +-2.2723591363918889E-02 1 6 5 5 +-5.3329314987169097E-03 1 6 6 6 + 7.8954566387011194E-01 2 2 2 2 +-4.6561275831296361E-03 2 2 2 3 + 5.0741646342031551E-12 2 2 2 5 +-1.2487609471255214E-01 2 2 2 6 + 6.9595496819467295E-01 2 2 3 3 +-5.3929249894749851E-12 2 2 3 5 +-1.1607069092962087E-01 2 2 3 6 + 7.8448381717624993E-01 2 2 4 4 + 7.8448381717613436E-01 2 2 5 5 +-4.7985628699907814E-12 2 2 5 6 + 6.4964772876329158E-01 2 2 6 6 + 1.4444971448519792E-01 2 3 2 3 +-2.3872253962660416E-12 2 3 2 5 +-2.5577726237563506E-02 2 3 2 6 +-4.8959219923890365E-02 2 3 3 3 + 1.1937021234401864E-12 2 3 3 5 + 9.2638931487307660E-02 2 3 3 6 +-6.9378177817693773E-02 2 3 4 4 +-6.9378177817692288E-02 2 3 5 5 + 6.3037969244299567E-12 2 3 5 6 + 7.6315984602985582E-02 2 3 6 6 + 1.5634124449820219E-01 2 4 2 4 +-4.2107008545703109E-02 2 4 3 4 +-3.7294910005473277E-12 2 4 4 5 +-4.1302427395260140E-02 2 4 4 6 + 1.5634124449822509E-01 2 5 2 5 +-1.8561932529055226E-12 2 5 2 6 + 1.5533711340149367E-12 2 5 3 3 +-4.2107008545717868E-02 2 5 3 5 + 5.3832947076008831E-12 2 5 3 6 +-3.0358925251522434E-12 2 5 4 4 +-1.0486630073780601E-11 2 5 5 5 +-4.1302427395291115E-02 2 5 5 6 + 2.5757385275399300E-12 2 5 6 6 + 9.2491473223624845E-02 2 6 2 6 +-3.6203091998213921E-02 2 6 3 3 + 4.1473438978958583E-12 2 6 3 5 + 5.7072993723670765E-02 2 6 3 6 +-1.2246030835729248E-01 2 6 4 4 +-1.2246030835729456E-01 2 6 5 5 + 1.5230587578846982E-12 2 6 5 6 +-5.2157534615417354E-02 2 6 6 6 + 7.1892601814184987E-01 3 3 3 3 +-2.1462527961244731E-12 3 3 3 5 +-1.0168065139814793E-01 3 3 3 6 + 6.8985680679607897E-01 3 3 4 4 + 6.8985680679595685E-01 3 3 5 5 +-3.3334445090800934E-12 3 3 5 6 + 6.2710821004609518E-01 3 3 6 6 + 4.6922107699702842E-02 3 4 3 4 +-1.0009959324427865E-02 3 4 4 6 + 4.6922107699706582E-02 3 5 3 5 + 1.1378124855100904E-12 3 5 3 6 +-3.1772542227036041E-12 3 5 4 4 +-1.8079868580588070E-12 3 5 5 5 +-1.0009959324413467E-02 3 5 5 6 + 1.5399058597106602E-01 3 6 3 6 +-1.5178408931185386E-01 3 6 4 4 +-1.5178408931183254E-01 3 6 5 5 + 4.6859932436871072E-12 3 6 5 6 + 1.5121610111750611E-02 3 6 6 6 + 8.8015909104971357E-01 4 4 4 4 + 7.8527020278998061E-01 4 4 5 5 +-5.0605686141576212E-12 4 4 5 6 + 5.9883768537036675E-01 4 4 6 6 + 4.7444446293220387E-02 4 5 4 5 + 2.9245259894370119E-02 4 6 4 6 + 8.8015909104941747E-01 5 5 5 5 +-4.5888451529157230E-12 5 5 5 6 + 5.9883768537025228E-01 5 5 6 6 + 2.9245259894373828E-02 5 6 5 6 + 1.3272325925797602E-12 5 6 6 6 + 6.9736740407352993E-01 6 6 6 6 + 8.3984091837142412E+00 1 1 7 7 + 1.0799365965176753E+00 1 1 7 8 + 4.8970425786106131E-01 1 1 7 9 +-4.2679679282498830E-11 1 1 7 10 +-4.4053618166908781E-01 1 1 7 12 + 1.3358351903013295E+00 1 1 8 8 + 2.3694359594507838E-01 1 1 8 9 +-1.1210785117698176E-11 1 1 8 10 +-3.5320904543712922E-01 1 1 8 12 + 1.1213221836524117E+00 1 1 9 9 + 5.8388096190513892E-12 1 1 9 10 + 3.0256641715811733E-01 1 1 9 12 + 1.3344266219315337E+00 1 1 10 10 +-8.2923077860163023E-12 1 1 10 12 + 1.3344266219316927E+00 1 1 11 11 + 1.0482001315056988E+00 1 1 12 12 + 1.1406237541411006E+00 1 2 7 7 + 1.8177369404220034E-01 1 2 7 8 + 8.0125591391565137E-02 1 2 7 9 +-6.7979521831802692E-12 1 2 7 10 +-7.6864899305632867E-02 1 2 7 12 + 8.2289710618610429E-02 1 2 8 8 + 2.5990290986352242E-02 1 2 8 9 +-2.0048831724951659E-12 1 2 8 10 +-2.5375596314754480E-02 1 2 8 12 + 5.8157875400842170E-02 1 2 9 9 + 1.3778493907121018E-02 1 2 9 12 + 6.4060934081936569E-02 1 2 10 10 + 6.4060934081906273E-02 1 2 11 11 + 5.1806631583523798E-02 1 2 12 12 +-4.0845412326744696E-01 1 3 7 7 +-6.2524612195795207E-02 1 3 7 8 +-4.2379679363461015E-02 1 3 7 9 + 2.0982149285388190E-12 1 3 7 10 + 1.1342414697804245E-02 1 3 7 12 +-3.9167428711587543E-02 1 3 8 8 + 1.0614574221398099E-02 1 3 8 9 + 1.1401956781355055E-12 1 3 8 10 + 2.5378500326730214E-02 1 3 8 12 +-9.1209035289715364E-03 1 3 9 9 + 1.0397116530978779E-03 1 3 9 12 +-2.2988927822990911E-02 1 3 10 10 +-1.0297899158899448E-12 1 3 10 12 +-2.2988927822968786E-02 1 3 11 11 +-3.2454482918944212E-02 1 3 12 12 +-1.0608679088577506E-11 1 4 7 10 + 2.5562845281250936E-02 1 4 7 11 + 1.3633053590799799E-11 1 4 8 10 +-3.2850445167036009E-02 1 4 8 11 + 5.8067679435823644E-12 1 4 9 10 +-1.3992092931196418E-02 1 4 9 11 + 1.3518611328818334E-12 1 4 10 11 +-4.7329435718709646E-12 1 4 10 12 + 1.1404575495286713E-02 1 4 11 12 +-3.5823236111112825E-11 1 5 7 7 +-5.2589796864047185E-12 1 5 7 8 +-1.9407943921533558E-12 1 5 7 9 + 2.5562845281230248E-02 1 5 7 10 + 1.0608683256666237E-11 1 5 7 11 + 1.7732536287324552E-12 1 5 7 12 +-3.5399312843723071E-12 1 5 8 8 +-1.7276627344852032E-12 1 5 8 9 +-3.2850445166949939E-02 1 5 8 10 +-1.3633073789460612E-11 1 5 8 11 + 1.6658410041076188E-12 1 5 8 12 +-1.9561602626593500E-12 1 5 9 9 +-1.3992092931151362E-02 1 5 9 10 +-5.8067785182026389E-12 1 5 9 11 + 1.4492397216532774E-12 1 5 10 10 + 1.1404575495282360E-02 1 5 10 12 +-1.2197321899832721E-12 1 5 11 11 + 4.7329439809237280E-12 1 5 11 12 +-1.6052939557864474E-12 1 5 12 12 +-4.1194575738653855E-01 1 6 7 7 +-6.8472419570206305E-02 1 6 7 8 +-1.5928362815132550E-02 1 6 7 9 + 1.9941553510107608E-12 1 6 7 10 + 4.3519418876214619E-02 1 6 7 12 +-2.1042550190119622E-02 1 6 8 8 +-2.7480717413766346E-02 1 6 8 9 + 1.3468439290134535E-12 1 6 8 10 +-5.7529984812231590E-03 1 6 8 12 +-3.1955465829682242E-02 1 6 9 9 + 1.0034907325983803E-12 1 6 9 10 +-1.0785350407223787E-02 1 6 9 12 +-2.2723591363918934E-02 1 6 10 10 +-2.2723591363929117E-02 1 6 11 11 +-5.5430312759749065E-03 1 6 12 12 + 1.3979029920980972E+00 2 2 7 7 + 8.3374706627614717E-02 2 2 7 8 + 4.5976132018954771E-02 2 2 7 9 +-4.0968918130286469E-12 2 2 7 10 +-2.6261073207490018E-02 2 2 7 12 + 7.7609351568859375E-01 2 2 8 8 + 1.9995736969528562E-02 2 2 8 9 + 4.5015087246500363E-12 2 2 8 10 +-1.3691794628073770E-01 2 2 8 12 + 6.8929914361168265E-01 2 2 9 9 + 6.1122237384373193E-12 2 2 9 10 + 1.0844963935390116E-01 2 2 9 12 + 7.8448381717613591E-01 2 2 10 10 +-4.4959415436319254E-12 2 2 10 12 + 7.8448381717624949E-01 2 2 11 11 + 6.6935876337214850E-01 2 2 12 12 +-1.9645306125505840E-01 2 3 7 7 +-2.2116448396856090E-02 2 3 7 8 + 1.0712982409652246E-02 2 3 7 9 + 1.4505347559445240E-12 2 3 7 10 + 2.8967595215960849E-02 2 3 7 12 + 1.1644689325025414E-02 2 3 8 8 +-1.4398947546590496E-01 2 3 8 9 +-1.9034019218533194E-12 2 3 8 10 +-2.1902818017374953E-02 2 3 8 12 +-6.0559291551819557E-02 2 3 9 9 +-9.2457771945711142E-02 2 3 9 12 +-6.9378177817692427E-02 2 3 10 10 + 6.7886821999262906E-12 2 3 10 12 +-6.9378177817693745E-02 2 3 11 11 + 7.1714928529910030E-02 2 3 12 12 + 1.4008515542348319E-11 2 4 7 10 +-3.3755163745613666E-02 2 4 7 11 +-6.2846081889790496E-11 2 4 8 10 + 1.5143489652707881E-01 2 4 8 11 +-2.2196590965621987E-11 2 4 9 10 + 5.3485248730269296E-02 2 4 9 11 +-4.6956346501417501E-12 2 4 10 11 + 1.9247928865099584E-11 2 4 10 12 +-4.6380098206618488E-02 2 4 11 12 +-9.6851920863591788E-12 2 5 7 7 +-1.8650285482944070E-12 2 5 7 8 +-1.3998458670372316E-12 2 5 7 9 +-3.3755163745524751E-02 2 5 7 10 +-1.4008535113980842E-11 2 5 7 11 + 1.3043012263989520E-12 2 5 7 12 + 6.1720891642570424E-12 2 5 8 8 + 3.2275327289134808E-12 2 5 8 9 + 1.5143489652709938E-01 2 5 8 10 + 6.2846066974374842E-11 2 5 8 11 +-1.7465939929055756E-12 2 5 8 12 + 2.6538185589069710E-12 2 5 9 9 + 5.3485248730286573E-02 2 5 9 10 + 2.2196583436544119E-11 2 5 9 11 +-5.7825771068624896E-12 2 5 9 12 +-1.2418916247877904E-11 2 5 10 10 +-4.6380098206649845E-02 2 5 10 12 +-3.0358918659315678E-12 2 5 11 11 +-1.9247915683638310E-11 2 5 11 12 + 2.3152651978699656E-12 2 5 12 12 +-3.2729774040947479E-01 2 6 7 7 +-2.2348322820290638E-02 2 6 7 8 +-2.5641189367752702E-02 2 6 7 9 + 1.8065647699713124E-12 2 6 7 10 +-5.9727635858912017E-03 2 6 7 12 +-1.1882498195912480E-01 2 6 8 8 + 1.4101461096733747E-02 2 6 8 9 +-1.6095447599939438E-12 2 6 8 10 + 9.9452512041869556E-02 2 6 8 12 +-2.9722886945516808E-02 2 6 9 9 +-4.7187953147856436E-12 2 6 9 10 +-5.0937176565907898E-02 2 6 9 12 +-1.2246030835729479E-01 2 6 10 10 + 1.1178566943917211E-12 2 6 10 12 +-1.2246030835729242E-01 2 6 11 11 +-6.4579334816162987E-02 2 6 12 12 + 1.1176083888376469E+00 3 3 7 7 + 5.3360318956451935E-02 3 3 7 8 + 1.5034599855653868E-02 3 3 7 9 +-1.9354725554356202E-12 3 3 7 10 +-3.0927487493359548E-02 3 3 7 12 + 6.8576642257966169E-01 3 3 8 8 + 5.3060096190714133E-02 3 3 8 9 + 1.0997711459339924E-12 3 3 8 10 +-4.3245119883076083E-02 3 3 8 12 + 7.1805041654220270E-01 3 3 9 9 + 1.9713173382052727E-12 3 3 9 10 + 1.0005114694642503E-01 3 3 9 12 + 6.8985680679595818E-01 3 3 10 10 +-3.4584385320811627E-12 3 3 10 12 + 6.8985680679607853E-01 3 3 11 11 + 6.3792135136076067E-01 3 3 12 12 +-4.7134049615950181E-12 3 4 7 10 + 1.1357505117311902E-02 3 4 7 11 + 1.6401185434774824E-11 3 4 8 10 +-3.9520546997985025E-02 3 4 8 11 + 2.0400008866458176E-11 3 4 9 10 +-4.9156178655542122E-02 3 4 9 11 + 1.0656564868022107E-12 3 4 10 11 + 4.1280267540429069E-12 3 4 10 12 +-9.9469635552992871E-03 3 4 11 12 +-6.5490956519697593E-12 3 5 7 7 + 1.1357505117272484E-02 3 5 7 10 + 4.7134130625436034E-12 3 5 7 11 +-5.2437914366798531E-12 3 5 8 8 +-1.9753276792568109E-12 3 5 8 9 +-3.9520546997998847E-02 3 5 8 10 +-1.6401177478635968E-11 3 5 8 11 + 4.3206950614439775E-12 3 5 8 12 +-2.6115957443338199E-12 3 5 9 9 +-4.9156178655547340E-02 3 5 9 10 +-2.0400003564406529E-11 3 5 9 11 +-1.0381359201118551E-12 3 5 10 10 +-9.9469635552844552E-03 3 5 10 12 +-3.1772543022592408E-12 3 5 11 11 +-4.1280306402426802E-12 3 5 11 12 +-3.2978850997187364E-01 3 6 7 7 +-1.5205006642834799E-02 3 6 7 8 +-2.1098551579868193E-03 3 6 7 9 + 1.1150304217643726E-02 3 6 7 12 +-9.8121822778930445E-02 3 6 8 8 +-1.0193526589330122E-01 3 6 8 9 + 5.7438805323103277E-12 3 6 8 10 + 6.8182604298208868E-02 3 6 8 12 +-1.0298853628416273E-01 3 6 9 9 +-1.4968117430041294E-01 3 6 9 12 +-1.5178408931183285E-01 3 6 10 10 + 4.5903837007877835E-12 3 6 10 12 +-1.5178408931185378E-01 3 6 11 11 +-1.4478432942298153E-03 3 6 12 12 + 1.3347130690982560E+00 4 4 7 7 + 6.0520225727235887E-02 4 4 7 8 + 2.7448150110838981E-02 4 4 7 9 +-1.5976881802518711E-12 4 4 7 10 +-2.4288862080683555E-02 4 4 7 12 + 7.6296206088779106E-01 4 4 8 8 + 8.5890944102072750E-02 4 4 8 9 +-3.6353330457922754E-12 4 4 8 10 +-1.3616250782860637E-01 4 4 8 12 + 6.8896099749179129E-01 4 4 9 9 + 3.0524163805680507E-12 4 4 9 10 + 1.4304797998786714E-01 4 4 9 12 + 7.8527020278998205E-01 4 4 10 10 +-3.9915888421919240E-11 4 4 10 11 +-4.6167213059576820E-12 4 4 10 12 + 8.8015909104971313E-01 4 4 11 11 + 6.2096880379655528E-01 4 4 12 12 + 1.1225870848059466E-12 4 5 7 11 +-3.4255423728530221E-12 4 5 8 11 +-3.8842644202276924E-11 4 5 10 10 + 4.7444446293220421E-02 4 5 10 11 + 3.8842377481226332E-11 4 5 11 11 +-4.2693034940662114E-12 4 6 7 10 + 1.0287381120116812E-02 4 6 7 11 + 1.6808097630043819E-11 4 6 8 10 +-4.0501045584173882E-02 4 6 8 11 +-2.6175537477945015E-12 4 6 9 10 + 6.3073031193063185E-03 4 6 9 11 +-1.3011920207994978E-11 4 6 10 12 + 3.1353723885682687E-02 4 6 11 12 + 1.3347130690980942E+00 5 5 7 7 + 6.0520225727265120E-02 5 5 7 8 + 2.7448150110862601E-02 5 5 7 9 +-2.4288862080673837E-02 5 5 7 12 + 7.6296206088767538E-01 5 5 8 8 + 8.5890944102070682E-02 5 5 8 9 +-1.0476732618366261E-11 5 5 8 10 +-1.3616250782860714E-01 5 5 8 12 + 6.8896099749167050E-01 5 5 9 9 + 1.5411525863989261E-12 5 5 9 10 + 1.4304797998784557E-01 5 5 9 12 + 8.8015909104941925E-01 5 5 10 10 + 3.9916131449759682E-11 5 5 10 11 +-3.8642886517133398E-12 5 5 10 12 + 7.8527020278998017E-01 5 5 11 11 + 6.2096880379643937E-01 5 5 12 12 +-9.6480397975212592E-12 5 6 7 7 + 1.0287381120114732E-02 5 6 7 10 + 4.2693034876509047E-12 5 6 7 11 +-4.2430286343084282E-12 5 6 8 8 +-6.7327034514483187E-12 5 6 8 9 +-4.0501045584203740E-02 5 6 8 10 +-1.6808087481301058E-11 5 6 8 11 + 1.9707518149856144E-12 5 6 8 12 +-3.7756048938200858E-12 5 6 9 9 + 6.3073031192898525E-03 5 6 9 10 + 2.6175574111616700E-12 5 6 9 11 +-4.3469611671992306E-12 5 6 9 12 +-4.2287885480232328E-12 5 6 10 10 + 3.1353723885687211E-02 5 6 10 12 +-5.0605704841378735E-12 5 6 11 11 + 1.3011916434356377E-11 5 6 11 12 + 9.9582458073510971E-01 6 6 7 7 + 4.5709767612618142E-02 6 6 7 8 + 3.3105005403248511E-02 6 6 7 9 +-1.8239361240607673E-12 6 6 7 10 +-6.2002230154778147E-03 6 6 7 12 + 6.5438949213609365E-01 6 6 8 8 +-7.3393477719290251E-02 6 6 8 9 + 2.6237777007910592E-12 6 6 8 10 +-5.1722318649959256E-02 6 6 8 12 + 6.1876271653843617E-01 6 6 9 9 +-1.7855713800074235E-02 6 6 9 12 + 5.9883768537025350E-01 6 6 10 10 + 1.5322039548326488E-12 6 6 10 12 + 5.9883768537036652E-01 6 6 11 11 + 7.0075216723073230E-01 6 6 12 12 + 8.4035245886995149E+00 7 7 7 7 + 1.0807524205201766E+00 7 7 7 8 + 4.9006502436133986E-01 7 7 7 9 +-4.2712117031111401E-11 7 7 7 10 +-4.4088004349265869E-01 7 7 7 12 + 1.3362055392188550E+00 7 7 8 8 + 2.3705735665790076E-01 7 7 8 9 +-1.1217333109045236E-11 7 7 8 10 +-3.5332476009502378E-01 7 7 8 12 + 1.1215815132063478E+00 7 7 9 9 + 5.8382202202821361E-12 7 7 9 10 + 3.0262751312137426E-01 7 7 9 12 + 1.3347130690980968E+00 7 7 10 10 +-8.2931725547453580E-12 7 7 10 12 + 1.3347130690982556E+00 7 7 11 11 + 1.0484335042604009E+00 7 7 12 12 + 1.7245799914154741E-01 7 8 7 8 + 7.5727703753318637E-02 7 8 7 9 +-6.3567423006536427E-12 7 8 7 10 +-7.3225157441445990E-02 7 8 7 12 + 7.7699013983499238E-02 7 8 8 8 + 2.5008365952685675E-02 7 8 8 9 +-2.0110727029114106E-12 7 8 8 10 +-2.3629685662219114E-02 7 8 8 12 + 5.5240090052449613E-02 7 8 9 9 + 1.3042279783880034E-02 7 8 9 12 + 6.0520225727265217E-02 7 8 10 10 + 6.0520225727235852E-02 7 8 11 11 + 4.8689865158237228E-02 7 8 12 12 + 4.7615454388337142E-02 7 9 7 9 +-2.4782491423185021E-12 7 9 7 10 +-1.7521224632200929E-02 7 9 7 12 + 4.4567026839524147E-02 7 9 8 8 +-7.8813740323346523E-03 7 9 8 9 +-1.4195380476068475E-12 7 9 8 10 +-2.6463618546155736E-02 7 9 8 12 + 1.3714851498593321E-02 7 9 9 9 + 1.7709770321577603E-04 7 9 9 12 + 2.7448150110862653E-02 7 9 10 10 + 1.0376595148408890E-12 7 9 10 12 + 2.7448150110838964E-02 7 9 11 11 + 3.5473092439462353E-02 7 9 12 12 + 2.5488126129327583E-02 7 10 7 10 + 2.1854392647265109E-12 7 10 7 12 +-4.0497549696214582E-12 7 10 8 8 +-1.8035469530660267E-12 7 10 8 9 +-3.2524841243605523E-02 7 10 8 10 + 1.8661125584689573E-12 7 10 8 12 +-2.2521615026337488E-12 7 10 9 9 +-1.3868535483662120E-02 7 10 9 10 + 1.0469858415096316E-12 7 10 10 10 + 1.1306950216164598E-02 7 10 10 12 +-1.5976896094285191E-12 7 10 11 11 +-1.9561823242240290E-12 7 10 12 12 + 2.5488126129348053E-02 7 11 7 11 +-3.2524841243691614E-02 7 11 8 11 +-1.3868535483707206E-02 7 11 9 11 + 1.3397119494939293E-12 7 11 10 11 + 1.1306950216169004E-02 7 11 11 12 + 4.6043316834310087E-02 7 12 7 12 +-2.2837804356356513E-02 7 12 8 8 +-2.8682668795348563E-02 7 12 8 9 + 1.3716808901052835E-12 7 12 8 10 +-5.6323333704049400E-03 7 12 8 12 +-3.3756920436940896E-02 7 12 9 9 + 1.0222670384967837E-12 7 12 9 10 +-1.1225435705738425E-02 7 12 9 12 +-2.4288862080673886E-02 7 12 10 10 +-2.4288862080683545E-02 7 12 11 11 +-6.4501970994602009E-03 7 12 12 12 + 7.6539161669110034E-01 8 8 8 8 + 2.5849508133395194E-03 8 8 8 9 + 5.6384059804806896E-12 8 8 8 10 +-1.2966829323356024E-01 8 8 8 12 + 6.7825358336144315E-01 8 8 9 9 + 6.0667869516305124E-12 8 8 9 10 + 9.1142332786148667E-02 8 8 9 12 + 7.6296206088767693E-01 8 8 10 10 +-3.9700542089630044E-12 8 8 10 12 + 7.6296206088779062E-01 8 8 11 11 + 6.7223388143428520E-01 8 8 12 12 + 1.4505237667877396E-01 8 9 8 9 + 2.6829695386275416E-12 8 9 8 10 + 9.3857262925516900E-03 8 9 8 12 + 6.4046770671099484E-02 8 9 9 9 + 1.7404309271901158E-12 8 9 9 10 + 1.0098015853347460E-01 8 9 9 12 + 8.5890944102070849E-02 8 9 10 10 +-7.1897808867328988E-12 8 9 10 12 + 8.5890944102072694E-02 8 9 11 11 +-6.7083126756308495E-02 8 9 12 12 + 1.4673894061577775E-01 8 10 8 10 +-1.4675277882353182E-12 8 10 8 12 + 2.1408971979642442E-12 8 10 9 9 + 5.0562223705319292E-02 8 10 9 10 +-6.1196289154313892E-12 8 10 9 12 +-1.2339607023072922E-11 8 10 10 10 +-4.5466113813319248E-02 8 10 10 12 +-3.6353245363380307E-12 8 10 11 11 + 2.3150700264371978E-12 8 10 12 12 + 1.4673894061575946E-01 8 11 8 11 + 5.0562223705303146E-02 8 11 9 11 +-4.3569850621099932E-12 8 11 10 11 +-4.5466113813289057E-02 8 11 11 12 + 1.0744490300537572E-01 8 12 8 12 +-3.6503647061307230E-02 8 12 9 9 +-4.9004912762090583E-12 8 12 9 10 +-6.1627207735530584E-02 8 12 9 12 +-1.3616250782860739E-01 8 12 10 10 + 1.5507043703636583E-12 8 12 10 12 +-1.3616250782860628E-01 8 12 11 11 +-6.5597729861012005E-02 8 12 12 12 + 7.1850774876547352E-01 9 9 9 9 + 2.4603116405275398E-12 9 9 9 10 + 1.0158490532272765E-01 9 9 9 12 + 6.8896099749167183E-01 9 9 10 10 +-3.9689931722280425E-12 9 9 10 12 + 6.8896099749179096E-01 9 9 11 11 + 6.2909161501147293E-01 9 9 12 12 + 5.2244890142054877E-02 9 10 9 10 + 5.8445855751775308E-03 9 10 10 12 + 3.0524173459810195E-12 9 10 11 11 + 5.2244890142047952E-02 9 11 9 11 +-1.2039527694299482E-12 9 11 10 11 + 5.8445855751944808E-03 9 11 11 12 + 1.4585914930926186E-01 9 12 9 12 + 1.4304797998784588E-01 9 12 10 10 +-4.2629230970586652E-12 9 12 10 12 + 1.4304797998786706E-01 9 12 11 11 +-2.1432615718804428E-03 9 12 12 12 + 8.8015909104942103E-01 10 10 10 10 +-3.4506160625427164E-12 10 10 10 12 + 7.8527020278998183E-01 10 10 11 11 + 6.2096880379644059E-01 10 10 12 12 + 4.7444446293220449E-02 10 11 10 11 + 3.3674948082128689E-02 10 12 10 12 +-4.6167231976934533E-12 10 12 11 11 + 1.1041185078205548E-12 10 12 12 12 + 8.8015909104971279E-01 11 11 11 11 + 6.2096880379655495E-01 11 11 12 12 + 3.3674948082123339E-02 11 12 11 12 + 7.0647341276318509E-01 12 12 12 12 +-3.7378218662230807E+01 1 1 0 0 +-1.6109626120285978E+00 1 2 0 0 + 5.6582303274564305E-01 1 3 0 0 +-1.6294740965697518E-15 1 4 0 0 + 4.5569403048979912E-11 1 5 0 0 + 5.8415414514866115E-01 1 6 0 0 +-7.9539209228946293E+00 2 2 0 0 + 4.9941952940139345E-01 2 3 0 0 + 1.8862647132371680E-15 2 4 0 0 + 1.6263793985979169E-11 2 5 0 0 + 1.1447853392042677E+00 2 6 0 0 +-6.6784658007277615E+00 3 3 0 0 +-7.5062372327854663E-16 3 4 0 0 + 2.9816468932827697E-11 3 5 0 0 + 1.3965738119200168E+00 3 6 0 0 +-7.4140559108788988E+00 4 4 0 0 + 3.4042808549019895E-11 4 5 0 0 +-4.1784938184684966E-17 4 6 0 0 +-7.4140559636206591E+00 5 5 0 0 + 4.5627945055805027E-11 5 6 0 0 +-5.3721802144192221E+00 6 6 0 0 +-3.7387372486455334E+01 7 7 0 0 +-1.4938785928617559E+00 7 8 0 0 +-6.6648663471260983E-01 7 9 0 0 + 5.4600226292736458E-11 7 10 0 0 +-4.9926088475812518E-16 7 11 0 0 + 6.1504040960153961E-01 7 12 0 0 +-7.7653168708034457E+00 8 8 0 0 +-6.7843966885405182E-01 8 9 0 0 + 2.4182232082187102E-11 8 10 0 0 + 3.2055571898255862E-16 8 11 0 0 + 1.3139770573810625E+00 8 12 0 0 +-6.6529043446842930E+00 9 9 0 0 +-3.0216136032630840E-11 9 10 0 0 + 1.2874641513592135E-16 9 11 0 0 +-1.3362720803875301E+00 9 12 0 0 +-7.4140564143334586E+00 10 10 0 0 + 3.4591305878196864E-11 10 11 0 0 + 4.1676625823502530E-11 10 12 0 0 +-7.4140563610481731E+00 11 11 0 0 +-1.1007478302298119E-16 11 12 0 0 +-5.5798726261674512E+00 12 12 0 0 + 1.1341212902204017E+01 0 0 0 0 diff --git a/test/chemistry/test_driver_fcidump_oh.npz b/test/chemistry/test_driver_fcidump_oh.npz new file mode 100644 index 0000000000..e5ca67d7f5 Binary files /dev/null and b/test/chemistry/test_driver_fcidump_oh.npz differ diff --git a/test/chemistry/test_driver_methods_fcidump.py b/test/chemistry/test_driver_methods_fcidump.py new file mode 100644 index 0000000000..8edc46f3f4 --- /dev/null +++ b/test/chemistry/test_driver_methods_fcidump.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- + +# This code is part of Qiskit. +# +# (C) Copyright IBM 2020. +# +# This code is licensed under the Apache License, Version 2.0. You may +# obtain a copy of this license in the LICENSE.txt file in the root directory +# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. +# +# Any modifications or derivative works of this code must retain this +# copyright notice, and modified files need to carry a notice indicating +# that they have been altered from the originals. + +""" Test Driver Methods FCIDump """ + +from test.chemistry import QiskitChemistryTestCase +from test.chemistry.test_driver_methods import TestDriverMethods +from qiskit.chemistry.drivers import FCIDumpDriver + + +class TestDriverMethodsFCIDump(TestDriverMethods): + """ Driver Methods FCIDump tests """ + + def test_lih(self): + """ LiH test """ + driver = FCIDumpDriver(self.get_resource_path('test_driver_fcidump_lih.fcidump')) + result = self._run_driver(driver, freeze_core=False) + self._assert_energy(result, 'lih') + + def test_oh(self): + """ OH test """ + driver = FCIDumpDriver(self.get_resource_path('test_driver_fcidump_oh.fcidump')) + result = self._run_driver(driver, freeze_core=False) + self._assert_energy(result, 'oh') + + def test_lih_freeze_core(self): + """ LiH freeze core test """ + with self.assertLogs('qiskit.chemistry', level='WARNING') as log: + driver = FCIDumpDriver(self.get_resource_path('test_driver_fcidump_lih.fcidump')) + result = self._run_driver(driver, freeze_core=True) + self._assert_energy(result, 'lih') + warning = 'WARNING:qiskit.chemistry.qmolecule:' + \ + 'Missing molecule information! Returning empty core orbital list.' + self.assertIn(warning, log.output) + + def test_oh_freeze_core(self): + """ OH freeze core test """ + with self.assertLogs('qiskit.chemistry', level='WARNING') as log: + driver = FCIDumpDriver(self.get_resource_path('test_driver_fcidump_oh.fcidump')) + result = self._run_driver(driver, freeze_core=True) + self._assert_energy(result, 'oh') + warning = 'WARNING:qiskit.chemistry.qmolecule:' + \ + 'Missing molecule information! Returning empty core orbital list.' + self.assertIn(warning, log.output) + + def test_lih_with_atoms(self): + """ LiH with num_atoms test """ + driver = FCIDumpDriver(self.get_resource_path('test_driver_fcidump_lih.fcidump'), + atoms=['Li', 'H']) + result = self._run_driver(driver, freeze_core=True) + self._assert_energy(result, 'lih') + + def test_oh_with_atoms(self): + """ OH with num_atoms test """ + driver = FCIDumpDriver(self.get_resource_path('test_driver_fcidump_oh.fcidump'), + atoms=['O', 'H']) + result = self._run_driver(driver, freeze_core=True) + self._assert_energy(result, 'oh') + + +class TestFCIDumpDriverQMolecule(QiskitChemistryTestCase): + """QMolecule FCIDumpDriver tests.""" + + def test_qmolecule_log(self): + """Test QMolecule log function.""" + qmolecule = FCIDumpDriver(self.get_resource_path('test_driver_fcidump_h2.fcidump')).run() + with self.assertLogs('qiskit.chemistry', level='DEBUG') as _: + qmolecule.log() + + def test_qmolecule_log_with_atoms(self): + """Test QMolecule log function.""" + qmolecule = FCIDumpDriver(self.get_resource_path('test_driver_fcidump_h2.fcidump'), + atoms=['H', 'H']).run() + with self.assertLogs('qiskit.chemistry', level='DEBUG') as _: + qmolecule.log()