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","."]
code: def __init__(
      self,
      n,
      eta,
      omega=None,
      error=0.0016,
      charge=0,
      br=7,
      vectors=None,
  ):
      self.n = n
      self.eta = eta
      self.omega = omega
      self.error = error
      self.charge = charge
      self.br = br
      self.vectors = vectors
      self.cubic = True
  
      if omega is None and vectors is None:
          raise ValueError("The lattice vectors must be provided.")
  
      if omega is not None and vectors is not None:
          raise ValueError(
              "The lattice vectors and the unit cell volume should not be provided"
              " together. Please provide only one of them."
          )
  
      if self.vectors is not None:
          self.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
              / self.omega
              * np.array(
                  [
                      np.cross(vectors[i], vectors[j])
                      for i, j in [(1, 2), (2, 0), (0, 1)]
                  ]
              )
          )
          bbt = np.matrix(recip_vectors) @ np.matrix(recip_vectors).T
          self.cubic = (
              np.linalg.norm(
                  bbt - (recip_vectors**2).max() * np.identity(3)
              )
              < 1e-6
          )
  
      self.lamb = self.norm(
          self.n,
          self.eta,
          self.omega,
          self.error,
          self.br,
          self.charge,
          self.cubic,
          self.vectors,
      )
  
      self.gates = self.gate_cost(
          self.n,
          self.eta,
          self.omega,
          self.error,
          self.br,
          self.charge,
          self.cubic,
          self.vectors,
      )
  
      self.qubits = self.qubit_cost(
          self.n,
          self.eta,
          self.omega,
          self.error,
          self.br,
          self.charge,
          self.cubic,
          self.vectors,
      )
  
      super().__init__(wires=range(self.qubits))
  
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 1 to create a new FirstQuantization object from inherited base classes: Operation with example: obj = FirstQuantization(n, eta, omega, error, charge, br, vectors)