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 Toffoli gates needed to implement the qubitization unitary
  operator 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: the number of Toffoli gates needed to implement the qubitization unitary operator
docstr_tok: ["Return","the","number","of","Toffoli","gates","needed","to","implement","the","qubitization","unitary","operator","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",":","the","number","of","Toffoli","gates","needed","to","implement","the","qubitization","unitary","operator"]
code: def _unitary_cost_noncubic(n, eta, error, br, charge, vectors):
      r"""Return the number of Toffoli gates needed to implement the qubitization unitary
      operator 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: the number of Toffoli gates needed to implement the qubitization unitary operator
      """
  
      lambda_total, aa_steps = 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)]
              ]
          )
      )
  
      n_tof = 500  # optimal value for lower resource estimates
  
      alpha = 0.0248759298  # optimal value for lower resource estimates
      l_z = eta + charge
      l_nu = 2 * np.pi * n ** (2 / 3)
  
      # defined in the third and second paragraphs of page 15 of PRX Quantum 2, 040332 (2021)
      n_eta = np.ceil(np.log2(eta))
      n_etaz = np.ceil(np.log2(eta + 2 * l_z))
  
      # taken from Eq. (22) of PRX Quantum 2, 040332 (2021)
      n_p = int(np.ceil(np.log2(n ** (1 / 3) + 1)))
  
      # errors in Eqs. (132-134) of PRX Quantum 2, 040332 (2021)
      error_t, error_r, error_m = [alpha * error] * 3
  
      # 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)
  
      # defined in Eq. (F3) of arXiv:2302.07981v1 (2023)
      bmin = np.min(np.linalg.svd(recip_vectors)[1])
  
      # equivalent to Eq. (J13) of arXiv:2302.07981v1 (2023)
      n_m = int(
          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)
                  )
              )
          )
      )
  
      e_r = FirstQuantization._cost_qrom(l_z)
  
      # taken from Eq. (125) of PRX Quantum 2, 040332 (2021)
      cost = (
          2 * (n_t + 4 * n_etaz + 2 * br - 12)
          + 14 * n_eta
          + 8 * br
          - 36
      )
      cost += (2 * aa_steps + 1) * (
          3 * n_p**2 + 15 * n_p - 7 + 4 * n_m * (n_p + 1)
      )
      cost += l_z + e_r + 2 * (2 * n_p + 2 * br - 7) + 12 * eta * n_p
      cost += 5 * (n_p - 1) + 2 + 24 * n_p + 6 * n_p * n_r + 18
      cost += n_etaz + 2 * n_eta + 6 * n_p + n_m + 16
  
      # taken from Eq. (J7) of arXiv:2302.07981v1 (2023)
      error_b = alpha * error
      n_b = np.ceil(
          np.log2(
              2
              * np.pi
              * eta
              * 2 ** (2 * n_p - 2)
              * np.abs(
                  np.matrix(recip_vectors) @ np.matrix(recip_vectors).T
              )
              .flatten()
              .sum()
              / error_b
          )
      )
  
      n_dirty = FirstQuantization._qubit_cost_noncubic(
          n, eta, error, br, charge, vectors
      )
      ms_cost = FirstQuantization._momentum_state_qrom(
          n_p, n_m, n_dirty, n_tof, kappa=1
      )[0]
  
      # adapted Eq. (125) of PRX Quantum 2, 040332 (2021) to the noncubic case using Appendix K of
      # arXiv:2302.07981v1 (2023)
      cost -= 2 * (3 * 2 + 2 * br - 9)
      cost += 2 * (
          2
          * (
              2 * (2 ** (4 + 1) - 1)
              + (n_b - 3) * 4
              + 2**4
              + (n_p - 2)
          )
      )
      cost += 8
      cost -= (2 * aa_steps + 1) * (
          3 * n_p**2 + 15 * n_p - 7 + 4 * n_m * (n_p + 1)
      )
      cost += (2 * aa_steps + 1) * ms_cost
  
      return int(np.ceil(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 13 for calling the FirstQuantization obj's underlying member method code with example usage: obj._unitary_cost_noncubic(n, eta, error, br, charge, vectors) and returns: int