class_docstr: The MPS template broadcasts an input circuit across many wires following the architecture of a Matrix Product State tensor network.
  The result is similar to the architecture in `arXiv:1803.11537 <https://arxiv.org/abs/1803.11537>`_.
  
  The keyword argument ``block`` is a user-defined quantum circuit that should accept two arguments: ``wires`` and ``weights``.
  The latter argument is optional in case the implementation of ``block`` doesn't require any weights. Any additional arguments
  should be provided using the ``kwargs``.
  
  Args:
      wires (Iterable): wires that the template acts on
      n_block_wires (int): number of wires per block
      block (Callable): quantum circuit that defines a block
      n_params_block (int): the number of parameters in a block; equal to the length of the ``weights`` argument in ``block``
      template_weights (Sequence): list containing the weights for all blocks
      offset (int): offset value for positioning the subsequent blocks relative to each other.
          If ``None``, it defaults to :math:`\text{offset} = \lfloor \text{n_block_wires}/2  \rfloor`,
          otherwise :math:`\text{offset} \in [1, \text{n_block_wires} - 1]`
      **kwargs: additional keyword arguments for implementing the ``block``
  
  .. note::
  
      The expected number of blocks can be obtained from ``qml.MPS.get_n_blocks(wires, n_block_wires, offset=0)``, and
      the length of ``template_weights`` argument should match the number of blocks. Whenever either ``n_block_wires``
      is odd or ``offset`` is not :math:`\lfloor \text{n_block_wires}/2  \rfloor`, the template deviates from the maximally
      unbalanced tree architecture described in `arXiv:1803.11537 <https://arxiv.org/abs/1803.11537>`_.
  
  .. details::
      :title: Usage Details
  
      This example demonstrates the use of ``MPS`` for a simple block.
  
      .. code-block:: python
  
          import pennylane as qml
          import numpy as np
  
          def block(weights, wires):
              qml.CNOT(wires=[wires[0],wires[1]])
              qml.RY(weights[0], wires=wires[0])
              qml.RY(weights[1], wires=wires[1])
  
          n_wires = 4
          n_block_wires = 2
          n_params_block = 2
          n_blocks = qml.MPS.get_n_blocks(range(n_wires),n_block_wires)
          template_weights = [[0.1, -0.3]] * n_blocks
  
          dev= qml.device('default.qubit',wires=range(n_wires))
          @qml.qnode(dev)
          def circuit(template_weights):
              qml.MPS(range(n_wires),n_block_wires,block, n_params_block, template_weights)
              return qml.expval(qml.PauliZ(wires=n_wires-1))
  
      >>> print(qml.draw(circuit, expansion_strategy='device')(template_weights))
      0: ─╭●──RY(0.10)──────────────────────────────┤
      1: ─╰X──RY(-0.30)─╭●──RY(0.10)────────────────┤
      2: ───────────────╰X──RY(-0.30)─╭●──RY(0.10)──┤
      3: ─────────────────────────────╰X──RY(-0.30)─┤  <Z>
  
      MPS can also be used with an ``offset`` argument that shifts the positioning the subsequent blocks from the default ``n_block_wires/2``.
  
      .. code-block:: python
  
          import pennylane as qml
          import numpy as np
  
          def block(wires):
              qml.MultiControlledX(wires=[wires[i] for i in range(len(wires))])
  
          n_wires = 8
          n_block_wires = 4
          n_params_block = 2
  
          dev= qml.device('default.qubit',wires=n_wires)
          @qml.qnode(dev)
          def circuit():
              qml.MPS(range(n_wires),n_block_wires, block, n_params_block, offset = 1)
              return qml.state()
  
      >>> print(qml.draw(circuit, expansion_strategy='device')())
      0: ─╭●─────────────┤  State
      1: ─├●─╭●──────────┤  State
      2: ─├●─├●─╭●───────┤  State
      3: ─╰X─├●─├●─╭●────┤  State
      4: ────╰X─├●─├●─╭●─┤  State
      5: ───────╰X─├●─├●─┤  State
      6: ──────────╰X─├●─┤  State
      7: ─────────────╰X─┤  State
docstr: Returns the expected number of blocks for a set of wires and number of wires per block.
  
  Args:
      wires (Sequence): number of wires the template acts on
      n_block_wires (int): number of wires per block
      offset (int): offset value for positioning the subsequent blocks relative to each other.
          If ``None``, it defaults to :math:`\text{offset} = \lfloor \text{n_block_wires}/2  \rfloor`,
          otherwise :math:`\text{offset} \in [1, \text{n_block_wires} - 1]`.
  
  Returns:
      n_blocks (int): number of blocks; expected length of the template_weights argument
docstr_tok: ["Returns","the","expected","number","of","blocks","for","a","set","of","wires","and","number","of","wires","per","block",".","Args",":","wires","(","Sequence",")",":","number","of","wires","the","template","acts","on","n_block_wires","(","int",")",":","number","of","wires","per","block","offset","(","int",")",":","offset","value","for","positioning","the","subsequent","blocks","relative","to","each","other",".","If","``","None","``",",","it","defaults","to",":","math",":","`","\\text","{","offset","}","=","\\lfloor","\\text","{","n_block_wires","}","\/2","\\rfloor","`",",","otherwise",":","math",":","`","\\text","{","offset","}","\\in","[","1",",","\\text","{","n_block_wires","}","-","1","]","`",".","Returns",":","n_blocks","(","int",")",":","number","of","blocks",";","expected","length","of","the","template_weights","argument"]
code: def get_n_blocks(wires, n_block_wires, offset=None):
      r"""Returns the expected number of blocks for a set of wires and number of wires per block.
  
      Args:
          wires (Sequence): number of wires the template acts on
          n_block_wires (int): number of wires per block
          offset (int): offset value for positioning the subsequent blocks relative to each other.
              If ``None``, it defaults to :math:`\text{offset} = \lfloor \text{n_block_wires}/2  \rfloor`,
              otherwise :math:`\text{offset} \in [1, \text{n_block_wires} - 1]`.
  
      Returns:
          n_blocks (int): number of blocks; expected length of the template_weights argument
      """
      n_wires = len(wires)
  
      if (
          offset is None
          and not n_block_wires % 2
          and n_wires % (n_block_wires // 2) > 0
      ):
          warnings.warn(
              f"The number of wires should be a multiple of {int(n_block_wires/2)}; got {n_wires}"
          )
  
      if n_block_wires > n_wires:
          raise ValueError(
              f"n_block_wires must be smaller than or equal to the number of wires; got n_block_wires = {n_block_wires} and number of wires = {n_wires}"
          )
  
      if offset is None:
          offset = n_block_wires // 2
  
      if offset < 1 or offset > n_block_wires - 1:
          raise ValueError(
              f"Provided offset is outside the expected range; the expected range for n_block_wires = {n_block_wires} is range{1, n_block_wires - 1}"
          )
  
      n_step = offset
      n_layers = n_wires - int(n_wires % (n_block_wires // 2)) - n_step
  
      return len(
          [
              idx
              for idx in range(0, n_layers, n_step)
              if not idx + n_block_wires > n_wires
          ]
      )
  
file_path: pennylane/pennylane/templates/tensornetworks/mps.py
imports: import warnings
  import pennylane
  from pennylane.operation import Operation, AnyWires
label_desc: Use image node_id 5 for calling the MPS obj's underlying member method code with example usage: obj.get_n_blocks(wires, n_block_wires, offset) and returns: len