class_docstr: Estimate the number of non-Clifford gates and logical qubits for a quantum phase estimation
  algorithm in second quantization with a double-factorized Hamiltonian.
  
  Atomic units are used throughout the class.
  
  Args:
      one_electron (array[array[float]]): one-electron integrals
      two_electron (tensor_like): two-electron integrals
      error (float): target error in the algorithm
      rank_r (int): rank of the first factorization of the two-electron integral tensor
      rank_m (int): average rank of the second factorization of the two-electron integral tensor
      tol_factor (float): threshold error value for discarding the negligible factors
      tol_eigval (float): threshold error value for discarding the negligible factor eigenvalues
      br (int): number of bits for ancilla qubit rotation
      alpha (int): number of bits for the keep register
      beta (int): number of bits for the rotation angles
      chemist_notation (bool): if True, the two-electron integrals need to be in chemist notation
  
  **Example**
  
  >>> symbols  = ['O', 'H', 'H']
  >>> geometry = np.array([[0.00000000,  0.00000000,  0.28377432],
  >>>                      [0.00000000,  1.45278171, -1.00662237],
  >>>                      [0.00000000, -1.45278171, -1.00662237]], requires_grad = False)
  >>> mol = qml.qchem.Molecule(symbols, geometry, basis_name='sto-3g')
  >>> core, one, two = qml.qchem.electron_integrals(mol)()
  >>> algo = DoubleFactorization(one, two)
  >>> print(algo.lamb,  # the 1-Norm of the Hamiltonian
  >>>       algo.gates, # estimated number of non-Clifford gates
  >>>       algo.qubits # estimated number of logical qubits
  >>>       )
  53.62085493277858 103969925 290
  
  .. details::
      :title: Theory
  
      To estimate the gate and qubit costs for implementing this method, the Hamiltonian needs to
      be factorized using the :func:`~.pennylane.qchem.factorize` function following
      [`PRX Quantum 2, 030305 (2021) <https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.2.030305>`_].
      The objective of the factorization is to find a set of symmetric matrices, :math:`L^{(r)}`,
      such that the two-electron integral tensor in
      `chemist notation <http://vergil.chemistry.gatech.edu/notes/permsymm/permsymm.pdf>`_,
      :math:`V`, can be computed as
  
      .. math::
  
             V_{ijkl} = \sum_r^R L_{ij}^{(r)} L_{kl}^{(r) T},
  
      with the rank :math:`R \leq n^2`, where :math:`n` is the number of molecular orbitals. The
      matrices :math:`L^{(r)}` are diagonalized and for each matrix the eigenvalues that are
      smaller than a given threshold (and their corresponding eigenvectors) are discarded. The
      average number of the retained eigenvalues, :math:`M`, determines the rank of the second
      factorization step. The 1-norm of the Hamiltonian can then be computed using the
      :func:`~.pennylane.resource.DoubleFactorization.norm` function from the electron integrals
      and the eigenvalues of the matrices :math:`L^{(r)}`.
  
      The total number of gates and qubits for implementing the quantum phase estimation algorithm
      for the given Hamiltonian can then be computed using the functions
      :func:`~.pennylane.resource.DoubleFactorization.gate_cost` and
      :func:`~.pennylane.resource.DoubleFactorization.qubit_cost` with a target error that has the
      default value of 0.0016 Ha (chemical accuracy). The costs are computed using Eqs. (C39-C40)
      of [`PRX Quantum 2, 030305 (2021) <https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.2.030305>`_].
class_docstr_tok: ["Estimate","the","number","of","non-Clifford","gates","and","logical","qubits","for","a","quantum","phase","estimation","algorithm","in","second","quantization","with","a","double-factorized","Hamiltonian",".","Atomic","units","are","used","throughout","the","class",".","Args",":","one_electron","(","array","[","array","[","float","]","]",")",":","one-electron","integrals","two_electron","(","tensor_like",")",":","two-electron","integrals","error","(","float",")",":","target","error","in","the","algorithm","rank_r","(","int",")",":","rank","of","the","first","factorization","of","the","two-electron","integral","tensor","rank_m","(","int",")",":","average","rank","of","the","second","factorization","of","the","two-electron","integral","tensor","tol_factor","(","float",")",":","threshold","error","value","for","discarding","the","negligible","factors","tol_eigval","(","float",")",":","threshold","error","value","for","discarding","the","negligible","factor","eigenvalues","br","(","int",")",":","number","of","bits","for","ancilla","qubit","rotation","alpha","(","int",")",":","number","of","bits","for","the","keep","register","beta","(","int",")",":","number","of","bits","for","the","rotation","angles","chemist_notation","(","bool",")",":","if","True",",","the","two-electron","integrals","need","to","be","in","chemist","notation","*","*","Example","*","*",">",">",">","symbols","=","[","'","O","'",",","'","H","'",",","'","H","'","]",">",">",">","geometry","=","np.array","(","[","[","0.00000000",",","0.00000000",",","0.28377432","]",",",">",">",">","[","0.00000000",",","1.45278171",",","-1.00662237","]",",",">",">",">","[","0.00000000",",","-1.45278171",",","-1.00662237","]","]",",","requires_grad","=","False",")",">",">",">","mol","=","qml.qchem.Molecule","(","symbols",",","geometry",",","basis_name='sto-3g","'",")",">",">",">","core",",","one",",","two","=","qml.qchem.electron_integrals","(","mol",")","(",")",">",">",">","algo","=","DoubleFactorization","(","one",",","two",")",">",">",">","print","(","algo.lamb",",","#","the","1-Norm","of","the","Hamiltonian",">",">",">","algo.gates",",","#","estimated","number","of","non-Clifford","gates",">",">",">","algo.qubits","#","estimated","number","of","logical","qubits",">",">",">",")","53.62085493277858","103969925","290","..","details",":",":",":","title",":","Theory","To","estimate","the","gate","and","qubit","costs","for","implementing","this","method",",","the","Hamiltonian","needs","to","be","factorized","using","the",":","func",":","`","~.pennylane.qchem.factorize","`","function","following","[","`","PRX","Quantum","2",",","030305","(","2021",")","<","https",":","\/\/journals.aps.org\/prxquantum\/abstract\/10.1103\/PRXQuantum.2.030305",">","`","_","]",".","The","objective","of","the","factorization","is","to","find","a","set","of","symmetric","matrices",",",":","math",":","`","L^","{","(","r",")","}","`",",","such","that","the","two-electron","integral","tensor","in","`","chemist","notation","<","http",":","\/\/vergil.chemistry.gatech.edu\/notes\/permsymm\/permsymm.pdf",">","`","_",",",":","math",":","`","V","`",",","can","be","computed","as","..","math",":",":","V_","{","ijkl","}","=","\\sum_r^R","L_","{","ij","}","^","{","(","r",")","}","L_","{","kl","}","^","{","(","r",")","T","}",",","with","the","rank",":","math",":","`","R","\\leq","n^2","`",",","where",":","math",":","`","n","`","is","the","number","of","molecular","orbitals",".","The","matrices",":","math",":","`","L^","{","(","r",")","}","`","are","diagonalized","and","for","each","matrix","the","eigenvalues","that","are","smaller","than","a","given","threshold","(","and","their","corresponding","eigenvectors",")","are","discarded",".","The","average","number","of","the","retained","eigenvalues",",",":","math",":","`","M","`",",","determines","the","rank","of","the","second","factorization","step",".","The","1-norm","of","the","Hamiltonian","can","then","be","computed","using","the",":","func",":","`","~.pennylane.resource.DoubleFactorization.norm","`","function","from","the","electron","integrals","and","the","eigenvalues","of","the","matrices",":","math",":","`","L^","{","(","r",")","}","`",".","The","total","number","of","gates","and","qubits","for","implementing","the","quantum","phase","estimation","algorithm","for","the","given","Hamiltonian","can","then","be","computed","using","the","functions",":","func",":","`","~.pennylane.resource.DoubleFactorization.gate_cost","`","and",":","func",":","`","~.pennylane.resource.DoubleFactorization.qubit_cost","`","with","a","target","error","that","has","the","default","value","of","0.0016","Ha","(","chemical","accuracy",")",".","The","costs","are","computed","using","Eqs",".","(","C39-C40",")","of","[","`","PRX","Quantum","2",",","030305","(","2021",")","<","https",":","\/\/journals.aps.org\/prxquantum\/abstract\/10.1103\/PRXQuantum.2.030305",">","`","_","]","."]
docstr: Return the number of Toffoli gates and the expansion factor needed to implement a QROM
  for the double factorization method.
  
  The complexity of a QROM computation in the most general form is given by (see Eq. (C39) in
  [`PRX Quantum 2, 030305 (2021) <https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.2.030305>`_])
  
  .. math::
  
      \text{cost} = \left \lceil \frac{a + b}{k} \right \rceil + \left \lceil \frac{c}{k} \right
      \rceil + d \left ( k + e \right ),
  
  where :math:`a, b, c, d, e` are constants that depend on the nature of the QROM
  implementation and the expansion factor :math:`k = 2^n` minimizes the cost. This function
  computes the optimum :math:`k` and the minimum cost for a QROM specification.
  
  To obtain the optimum values of :math:`k`, we first assume that the cost function is
  continuous and use differentiation to obtain the value of :math:`k` that minimizes the cost.
  This value of :math:`k` is not necessarily an integer power of 2. We then obtain the value
  of :math:`n` as :math:`n = \log_2(k)` and compute the cost for
  :math:`n_{int}= \left \{\left \lceil n \right \rceil, \left \lfloor n \right \rfloor \right \}`.
  The value of :math:`n_{int}` that gives the smaller cost is used to compute the optimim
  :math:`k`.
  
  Args:
      constants (tuple[float]): constants specifying a QROM
  
  Returns:
      tuple(int, int): the cost and the expansion factor for the QROM
  
  **Example**
  
  >>> constants = (151.0, 7.0, 151.0, 30.0, -1.0)
  >>> _qrom_cost(constants)
  168, 4
docstr_tok: ["Return","the","number","of","Toffoli","gates","and","the","expansion","factor","needed","to","implement","a","QROM","for","the","double","factorization","method",".","The","complexity","of","a","QROM","computation","in","the","most","general","form","is","given","by","(","see","Eq",".","(","C39",")","in","[","`","PRX","Quantum","2",",","030305","(","2021",")","<","https",":","\/\/journals.aps.org\/prxquantum\/abstract\/10.1103\/PRXQuantum.2.030305",">","`","_","]",")","..","math",":",":","\\text","{","cost","}","=","\\left","\\lceil","\\frac","{","a","+","b","}","{","k","}","\\right","\\rceil","+","\\left","\\lceil","\\frac","{","c","}","{","k","}","\\right","\\rceil","+","d","\\left","(","k","+","e","\\right",")",",","where",":","math",":","`","a",",","b",",","c",",","d",",","e","`","are","constants","that","depend","on","the","nature","of","the","QROM","implementation","and","the","expansion","factor",":","math",":","`","k","=","2^n","`","minimizes","the","cost",".","This","function","computes","the","optimum",":","math",":","`","k","`","and","the","minimum","cost","for","a","QROM","specification",".","To","obtain","the","optimum","values","of",":","math",":","`","k","`",",","we","first","assume","that","the","cost","function","is","continuous","and","use","differentiation","to","obtain","the","value","of",":","math",":","`","k","`","that","minimizes","the","cost",".","This","value","of",":","math",":","`","k","`","is","not","necessarily","an","integer","power","of","2",".","We","then","obtain","the","value","of",":","math",":","`","n","`","as",":","math",":","`","n","=","\\log_2","(","k",")","`","and","compute","the","cost","for",":","math",":","`","n_","{","int","}","=","\\left","\\","{","\\left","\\lceil","n","\\right","\\rceil",",","\\left","\\lfloor","n","\\right","\\rfloor","\\right","\\","}","`",".","The","value","of",":","math",":","`","n_","{","int","}","`","that","gives","the","smaller","cost","is","used","to","compute","the","optimim",":","math",":","`","k","`",".","Args",":","constants","(","tuple","[","float","]",")",":","constants","specifying","a","QROM","Returns",":","tuple","(","int",",","int",")",":","the","cost","and","the","expansion","factor","for","the","QROM","*","*","Example","*","*",">",">",">","constants","=","(","151.0",",","7.0",",","151.0",",","30.0",",","-1.0",")",">",">",">","_qrom_cost","(","constants",")","168",",","4"]
code: def _qrom_cost(constants):
      r"""Return the number of Toffoli gates and the expansion factor needed to implement a QROM
      for the double factorization method.
  
      The complexity of a QROM computation in the most general form is given by (see Eq. (C39) in
      [`PRX Quantum 2, 030305 (2021) <https://journals.aps.org/prxquantum/abstract/10.1103/PRXQuantum.2.030305>`_])
  
      .. math::
  
          \text{cost} = \left \lceil \frac{a + b}{k} \right \rceil + \left \lceil \frac{c}{k} \right
          \rceil + d \left ( k + e \right ),
  
      where :math:`a, b, c, d, e` are constants that depend on the nature of the QROM
      implementation and the expansion factor :math:`k = 2^n` minimizes the cost. This function
      computes the optimum :math:`k` and the minimum cost for a QROM specification.
  
      To obtain the optimum values of :math:`k`, we first assume that the cost function is
      continuous and use differentiation to obtain the value of :math:`k` that minimizes the cost.
      This value of :math:`k` is not necessarily an integer power of 2. We then obtain the value
      of :math:`n` as :math:`n = \log_2(k)` and compute the cost for
      :math:`n_{int}= \left \{\left \lceil n \right \rceil, \left \lfloor n \right \rfloor \right \}`.
      The value of :math:`n_{int}` that gives the smaller cost is used to compute the optimim
      :math:`k`.
  
      Args:
          constants (tuple[float]): constants specifying a QROM
  
      Returns:
          tuple(int, int): the cost and the expansion factor for the QROM
  
      **Example**
  
      >>> constants = (151.0, 7.0, 151.0, 30.0, -1.0)
      >>> _qrom_cost(constants)
      168, 4
      """
      a, b, c, d, e = constants
      n = np.log2(((a + b + c) / d) ** 0.5)
      k = np.array([2 ** np.floor(n), 2 ** np.ceil(n)])
      cost = np.ceil((a + b) / k) + np.ceil(c / k) + d * (k + e)
  
      return int(cost[np.argmin(cost)]), int(k[np.argmin(cost)])
  
file_path: pennylane/pennylane/resource/second_quantization.py
imports: import numpy
  from pennylane.operation import AnyWires, Operation
  from pennylane.qchem import factorize
label_desc: Use image node_id 5 for calling the DoubleFactorization obj's underlying member method code with example usage: obj._qrom_cost(constants) and returns: int,  int