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 1-norm of a first-quantized Hamiltonian in the plane-wave basis
  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:
      float: 1-norm of a first-quantized Hamiltonian in the plane-wave basis
docstr_tok: ["Return","the","1-norm","of","a","first-quantized","Hamiltonian","in","the","plane-wave","basis","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",":","float",":","1-norm","of","a","first-quantized","Hamiltonian","in","the","plane-wave","basis"]
code: def _norm_noncubic(
      n,
      eta,
      error,
      br,
      charge,
      vectors,
  ):
      r"""Return the 1-norm of a first-quantized Hamiltonian in the plane-wave basis
      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:
          float: 1-norm of a first-quantized Hamiltonian in the plane-wave basis
      """
      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)]
              ]
          )
      )
  
      bbt = np.matrix(recip_vectors) @ np.matrix(recip_vectors).T
  
      orthogonal = (
          np.linalg.norm(
              bbt
              - np.array([np.max(b**2) for b in recip_vectors])
              * np.identity(3)
          )
          < 1e-6
      )
  
      l_z = eta + charge
  
      alpha = 0.0248759298  # optimal value for lower resource estimates
      p_th = 0.95  # optimal value for lower resource estimates
  
      error_uv = alpha * error
  
      # taken from Eq. (22) of PRX Quantum 2, 040332 (2021)
      n_p = int(np.ceil(np.log2(n ** (1 / 3) + 1)))
  
      n0 = n ** (1 / 3)
  
      # defined in Eq. (F3) of arXiv:2302.07981v1 (2023)
      bmin = np.min(np.linalg.svd(recip_vectors)[1])
  
      n_m = int(
          np.ceil(
              np.log2(  # taken from Eq. (132) of PRX Quantum 2, 040332 (2021) with
                  # modifications taken from arXiv:2302.07981v1 (2023)
                  (8 * np.pi * eta)
                  / (error_uv * omega * bmin**2)
                  * (eta - 1 + 2 * l_z)
                  * (
                      7 * 2 ** (n_p + 1)
                      - 9 * n_p
                      - 11
                      - 3 * 2 ** (-1 * n_p)
                  )
              )
          )
      )
  
      lambda_nu = (  # expression is taken from Eq. (F6) of PRX 8, 011044 (2018)
          # bmin**2 is needed for non-cubic systems, from Eq. (F3) of arXiv:2302.07981v1 (2023)
          4 * np.pi * (np.sqrt(3) * n ** (1 / 3) / 2 - 1)
          + 3
          - 3 / n ** (1 / 3)
          + 3
          * integrate.nquad(
              lambda x, y: 1 / (x**2 + y**2), [[1, n0], [1, n0]]
          )[0]
      ) / bmin**2
  
      # computed using error term derived in Eq. (113) of PRX Quantum 2, 040332 (2021)
      # bmin**2 is needed for non-cubic systems, from Eq. (F3) of arXiv:2302.07981v1 (2023)
      lambda_nu_1 = lambda_nu + 4 / (2**n_m * bmin**2) * (
          7 * 2 ** (n_p + 1) - 9 * n_p - 11 - 3 * 2 ** (-1 * n_p)
      )
  
      # taken from Eq. (I7) of arXiv:2302.07981v1 (2023)
      p_nu = lambda_nu_1 * bmin**2 / 2 ** (n_p + 6)
  
      # amplitude amplification steps, taken from Eq. (117) of PRX Quantum 2, 040332 (2021)
      p_nu_amp = 0
      aa_steps = 0
      n_steps = 30  # maximum number of amplitude amplification steps
      for i in reversed(range(n_steps)):
          probability = (
              np.sin((2 * i + 1) * np.arcsin(np.sqrt(p_nu)))
          ) ** 2
          if probability > p_th:
              aa_steps = i
              p_nu_amp = probability
  
      # lambda_u and lambda_v are taken from Eq. (25) of PRX Quantum 2, 040332 (2021) with
      # modifications taken from arXiv:2302.07981v1 (2023)
      lambda_u = 4 * np.pi * eta * l_z * lambda_nu / omega
      lambda_v = 2 * np.pi * eta * (eta - 1) * lambda_nu / omega
  
      # lambda_u_1 and lambda_v_1 are taken from Eq. (124) of PRX Quantum 2, 040332 (2021)
      lambda_u_1 = lambda_u * lambda_nu_1 / lambda_nu
      lambda_v_1 = lambda_v * lambda_nu_1 / lambda_nu
  
      b_mat = np.matrix(recip_vectors)
      abs_sum = np.abs(b_mat @ b_mat.T).flatten().sum()
  
      # taken from Appendix I.1 of arXiv:2302.07981v1 (2023)
      if orthogonal:
          lambda_t_p = abs_sum * eta * 2 ** (2 * n_p - 2) / 4
      else:
          lambda_t_p = abs_sum * eta * 2 ** (2 * n_p - 2) / 2
  
      # taken from Eq. (63) of PRX Quantum 2, 040332 (2021) with
      # modifications taken from arXiv:2302.07981v1 (2023)
      p_eq = (
          FirstQuantization.success_prob(3 * eta + 2 * charge, br)
          * FirstQuantization.success_prob(eta, br) ** 2
      )
  
      # final lambda value is computed from case checking derived in Section E and Appendix D of
      # PRX Quantum 2, 040332 (2021)
      if p_nu * lambda_t_p >= (1 - p_nu) * (lambda_u_1 + lambda_v_1):
          raise ValueError(
              "The computed 1-norm is zero."
          )  # return 0.0, 0.0
      if p_nu_amp * lambda_t_p >= (1 - p_nu_amp) * (
          lambda_u_1 + lambda_v_1
      ):
          return (lambda_t_p + lambda_u_1 + lambda_v_1) / p_eq, aa_steps
      return (
          (lambda_u_1 + lambda_v_1 / (1 - 1 / eta)) / p_nu_amp
      ) / p_eq, aa_steps
  
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 11 for calling the FirstQuantization obj's underlying member method code with example usage: obj._norm_noncubic(n, eta, error, br, charge, vectors) and returns: unknown,  aa_steps, unknown,  aa_steps