class_docstr: Estimate the number of non-Clifford gates and logical qubits for a quantum phase estimation
  algorithm in first quantization using a plane-wave basis.
  
  To estimate the gate and qubit costs for implementing this method, the number of plane waves,
  the number of electrons and the lattice vectors need to be defined. The costs can then be
  computed using the functions :func:`~.pennylane.resource.FirstQuantization.gate_cost` and
  :func:`~.pennylane.resource.FirstQuantization.qubit_cost` with a target error that has the default
  value of 0.0016 Ha (chemical accuracy). Atomic units are used throughout the class.
  
  Args:
      n (int): number of plane waves
      eta (int): number of electrons
      omega (float): unit cell volume
      error (float): target error in the algorithm
      charge (int): total electric charge of the system
      br (int): number of bits for ancilla qubit rotation
      vectors (array[float]): lattice vectors
  
  **Example**
  
  >>> n = 100000
  >>> eta = 156
  >>> vectors = np.array([[10.46219511,  0.00000000,  0.00000000],
  ...                     [ 0.00000000, 10.46219511,  0.00000000],
  ...                     [ 0.00000000,  0.00000000, 10.46219511]])
  >>> algo = FirstQuantization(n, eta, vectors=vectors)
  >>> print(algo.lamb,  # the 1-Norm of the Hamiltonian
  >>>       algo.gates, # estimated number of non-Clifford gates
  >>>       algo.qubits # estimated number of logical qubits
  >>>       )
  649912.4804278888 1.1e+13 4416
  
  .. details::
      :title: Theory
  
      Following `PRX Quantum 2, 040332 (2021) <https://link.aps.org/doi/10.1103/PRXQuantum.2.040332>`_
      , the target algorithm error, :math:`\epsilon`, is distributed among four different sources
      of error using Eq. (131)
  
      .. math::
          \epsilon^2 \geq \epsilon_{qpe}^2 + (\epsilon_{\mathcal{M}} + \epsilon_R + \epsilon_T)^2,
  
      where :math:`\epsilon_{qpe}` is the quantum phase estimation error and
      :math:`\epsilon_{\mathcal{M}}`, :math:`\epsilon_R`, and :math:`\epsilon_T` are defined in
      Eqs. (132-134).
  
      Here, we fix :math:`\epsilon_{\mathcal{M}} = \epsilon_R = \epsilon_T = \alpha \epsilon` with
      a default value of :math:`\alpha = 0.01` and obtain
  
      .. math::
          \epsilon_{qpe} = \sqrt{\epsilon^2 [1 - (3 \alpha)^2]}.
  
      Note that the user only needs to define the target algorithm error :math:`\epsilon`. The
      error distribution takes place inside the functions.
class_docstr_tok: ["Estimate","the","number","of","non-Clifford","gates","and","logical","qubits","for","a","quantum","phase","estimation","algorithm","in","first","quantization","using","a","plane-wave","basis",".","To","estimate","the","gate","and","qubit","costs","for","implementing","this","method",",","the","number","of","plane","waves",",","the","number","of","electrons","and","the","lattice","vectors","need","to","be","defined",".","The","costs","can","then","be","computed","using","the","functions",":","func",":","`","~.pennylane.resource.FirstQuantization.gate_cost","`","and",":","func",":","`","~.pennylane.resource.FirstQuantization.qubit_cost","`","with","a","target","error","that","has","the","default","value","of","0.0016","Ha","(","chemical","accuracy",")",".","Atomic","units","are","used","throughout","the","class",".","Args",":","n","(","int",")",":","number","of","plane","waves","eta","(","int",")",":","number","of","electrons","omega","(","float",")",":","unit","cell","volume","error","(","float",")",":","target","error","in","the","algorithm","charge","(","int",")",":","total","electric","charge","of","the","system","br","(","int",")",":","number","of","bits","for","ancilla","qubit","rotation","vectors","(","array","[","float","]",")",":","lattice","vectors","*","*","Example","*","*",">",">",">","n","=","100000",">",">",">","eta","=","156",">",">",">","vectors","=","np.array","(","[","[","10.46219511",",","0.00000000",",","0.00000000","]",",","...","[","0.00000000",",","10.46219511",",","0.00000000","]",",","...","[","0.00000000",",","0.00000000",",","10.46219511","]","]",")",">",">",">","algo","=","FirstQuantization","(","n",",","eta",",","vectors=vectors",")",">",">",">","print","(","algo.lamb",",","#","the","1-Norm","of","the","Hamiltonian",">",">",">","algo.gates",",","#","estimated","number","of","non-Clifford","gates",">",">",">","algo.qubits","#","estimated","number","of","logical","qubits",">",">",">",")","649912.4804278888","1.1e+13","4416","..","details",":",":",":","title",":","Theory","Following","`","PRX","Quantum","2",",","040332","(","2021",")","<","https",":","\/\/link.aps.org\/doi\/10.1103\/PRXQuantum.2.040332",">","`","_",",","the","target","algorithm","error",",",":","math",":","`","\\epsilon","`",",","is","distributed","among","four","different","sources","of","error","using","Eq",".","(","131",")","..","math",":",":","\\epsilon^2","\\geq","\\epsilon_","{","qpe","}","^2","+","(","\\epsilon_","{","\\mathcal","{","M","}","}","+","\\epsilon_R","+","\\epsilon_T",")","^2",",","where",":","math",":","`","\\epsilon_","{","qpe","}","`","is","the","quantum","phase","estimation","error","and",":","math",":","`","\\epsilon_","{","\\mathcal","{","M","}","}","`",",",":","math",":","`","\\epsilon_R","`",",","and",":","math",":","`","\\epsilon_T","`","are","defined","in","Eqs",".","(","132-134",")",".","Here",",","we","fix",":","math",":","`","\\epsilon_","{","\\mathcal","{","M","}","}","=","\\epsilon_R","=","\\epsilon_T","=","\\alpha","\\epsilon","`","with","a","default","value","of",":","math",":","`","\\alpha","=","0.01","`","and","obtain","..","math",":",":","\\epsilon_","{","qpe","}","=","\\sqrt","{","\\epsilon^2","[","1","-","(","3","\\alpha",")","^2","]","}",".","Note","that","the","user","only","needs","to","define","the","target","algorithm","error",":","math",":","`","\\epsilon","`",".","The","error","distribution","takes","place","inside","the","functions","."]
docstr: Return the number of logical qubits needed to implement the first quantization
  algorithm for non-cubic systems.
  
  Args:
      n (int): number of plane waves
      eta (int): number of electrons
      error (float): target error in the algorithm
      br (int): number of bits for ancilla qubit rotation
      charge (int): total electric charge of the system
      vectors (array[float]): lattice vectors
  
  Returns:
      int: number of logical qubits needed to implement the first quantization algorithm
docstr_tok: ["Return","the","number","of","logical","qubits","needed","to","implement","the","first","quantization","algorithm","for","non-cubic","systems",".","Args",":","n","(","int",")",":","number","of","plane","waves","eta","(","int",")",":","number","of","electrons","error","(","float",")",":","target","error","in","the","algorithm","br","(","int",")",":","number","of","bits","for","ancilla","qubit","rotation","charge","(","int",")",":","total","electric","charge","of","the","system","vectors","(","array","[","float","]",")",":","lattice","vectors","Returns",":","int",":","number","of","logical","qubits","needed","to","implement","the","first","quantization","algorithm"]
code: def _qubit_cost_noncubic(n, eta, error, br, charge, vectors):
      r"""Return the number of logical qubits needed to implement the first quantization
      algorithm for non-cubic systems.
  
      Args:
          n (int): number of plane waves
          eta (int): number of electrons
          error (float): target error in the algorithm
          br (int): number of bits for ancilla qubit rotation
          charge (int): total electric charge of the system
          vectors (array[float]): lattice vectors
  
      Returns:
          int: number of logical qubits needed to implement the first quantization algorithm
      """
  
      lambda_total, _ = FirstQuantization._norm_noncubic(
          n,
          eta,
          error,
          br,
          charge,
          vectors,
      )
  
      omega = np.abs(
          np.sum((np.cross(vectors[0], vectors[1]) * vectors[2]))
      )
  
      recip_vectors = (  # taken from Eq. (35) of arXiv:2302.07981v1 (2023)
          2
          * np.pi
          / omega
          * np.array(
              [
                  np.cross(vectors[i], vectors[j])
                  for i, j in [(1, 2), (2, 0), (0, 1)]
              ]
          )
      )
  
      l_z = eta + charge
      l_nu = 2 * np.pi * n ** (2 / 3)
  
      # taken from Eq. (22) of PRX Quantum 2, 040332 (2021)
      n_p = np.ceil(np.log2(n ** (1 / 3) + 1))
  
      # defined in Eq. (F3) of arXiv:2302.07981v1 (2023)
      bmin = np.min(np.linalg.svd(recip_vectors)[1])
  
      alpha = 0.0248759298  # optimal value for lower resource estimates
  
      # errors derived according to the strategy in Appendix M.1 of arXiv:2302.07981v1 (2023)
      error_t, error_r, error_m, error_b = [alpha * error] * 4
  
      # parameters taken from PRX Quantum 2, 040332 (2021)
      n_t = int(
          np.ceil(np.log2(np.pi * lambda_total / error_t))
      )  # Eq. (134)
      n_r = int(
          np.ceil(
              np.log2((eta * l_z * l_nu) / (error_r * omega ** (1 / 3)))
          )
      )  # Eq. (133)
      n_m = int(  # taken from Eq. (J13) arXiv:2302.07981v1 (2023)
          np.ceil(
              np.log2(
                  (8 * np.pi * eta)
                  / (error_m * omega * bmin**2)
                  * (eta - 1 + 2 * l_z)
                  * (
                      7 * 2 ** (n_p + 1)
                      - 9 * n_p
                      - 11
                      - 3 * 2 ** (-1 * n_p)
                  )
              )
          )
      )
  
      # qpe error obtained to satisfy a modification of
      # inequality Eq. (131) of PRX Quantum 2, 040332 (2021) including error_b
      n_errors = 4
      error_qpe = np.sqrt(error**2 * (1 - (n_errors * alpha) ** 2))
  
      # adapted from equations (L1, L2) in Appendix L of arXiv:2302.07981v1 (2023)
      clean_temp_H_cost = max([5 * n_r - 4, 5 * n_p + 1]) + max(
          [5, n_m + 3 * n_p]
      )
      reflection_cost = (
          np.ceil(np.log2(eta + 2 * l_z))
          + 2 * np.ceil(np.log2(eta))
          + 6 * n_p
          + n_m
          + 16
          + 3
      )
      clean_temp_cost = max([clean_temp_H_cost, reflection_cost])
  
      # the expression for computing the cost is taken from Appendix C of
      # PRX Quantum 2, 040332 (2021) and adapting to non-cubic using Appendix L of
      # arXiv:2302.07981v1 (2023)
      clean_cost = 3 * eta * n_p
      clean_cost += np.ceil(
          np.log2(np.ceil(np.pi * lambda_total / (2 * error_qpe)))
      )
      clean_cost += 1 + 1 + np.ceil(np.log2(eta + 2 * l_z)) + 3 + 3
      clean_cost += 2 * np.ceil(np.log2(eta)) + 5 + 3 * (n_p + 1)
      clean_cost += (
          n_p
          + n_m
          + 3 * n_p
          + 2
          + 2 * n_p
          + 1
          + 1
          + 2
          + 2 * n_p
          + 6
          + 1
      )
  
      clean_cost += clean_temp_cost
  
      # taken from Eq. (J7) of arXiv:2302.07981v1 (2023)
      n_b = np.ceil(
          np.log2(
              4
              * np.pi
              * eta
              * 2 ** (2 * n_p - 2)
              * np.abs(
                  np.matrix(recip_vectors) @ np.matrix(recip_vectors).T
              )
              .flatten()
              .sum()
              / error_b
          )
      )
      clean_cost += np.max([n_r + 1, n_t, n_b]) + 6 + n_m + 1
  
      return int(np.ceil(clean_cost))
  
file_path: pennylane/pennylane/resource/first_quantization.py
imports: import numpy
  from scipy import integrate
  from pennylane.operation import AnyWires, Operation
label_desc: Use image node_id 12 for calling the FirstQuantization obj's underlying member method code with example usage: obj._qubit_cost_noncubic(n, eta, error, br, charge, vectors) and returns: int