class_docstr: Sparse matrix with DIAgonal storage
  
  This can be instantiated in several ways:
      dia_matrix(D)
          with a dense matrix
  
      dia_matrix(S)
          with another sparse matrix S (equivalent to S.todia())
  
      dia_matrix((M, N), [dtype])
          to construct an empty matrix with shape (M, N),
          dtype is optional, defaulting to dtype='d'.
  
      dia_matrix((data, offsets), shape=(M, N))
          where the ``data[k,:]`` stores the diagonal entries for
          diagonal ``offsets[k]`` (See example below)
  
  Attributes
  ----------
  dtype : dtype
      Data type of the matrix
  shape : 2-tuple
      Shape of the matrix
  ndim : int
      Number of dimensions (this is always 2)
  nnz
      Number of stored values, including explicit zeros
  data
      DIA format data array of the matrix
  offsets
      DIA format offset array of the matrix
  
  Notes
  -----
  
  Sparse matrices can be used in arithmetic operations: they support
  addition, subtraction, multiplication, division, and matrix power.
  
  Examples
  --------
  
  >>> import numpy as np
  >>> from scipy.sparse import dia_matrix
  >>> dia_matrix((3, 4), dtype=np.int8).toarray()
  array([[0, 0, 0, 0],
         [0, 0, 0, 0],
         [0, 0, 0, 0]], dtype=int8)
  
  >>> data = np.array([[1, 2, 3, 4]]).repeat(3, axis=0)
  >>> offsets = np.array([0, -1, 2])
  >>> dia_matrix((data, offsets), shape=(4, 4)).toarray()
  array([[1, 0, 3, 0],
         [1, 2, 0, 4],
         [0, 2, 3, 0],
         [0, 0, 3, 4]])
  
  >>> from scipy.sparse import dia_matrix
  >>> n = 10
  >>> ex = np.ones(n)
  >>> data = np.array([ex, 2 * ex, ex])
  >>> offsets = np.array([-1, 0, 1])
  >>> dia_matrix((data, offsets), shape=(n, n)).toarray()
  array([[2., 1., 0., ..., 0., 0., 0.],
         [1., 2., 1., ..., 0., 0., 0.],
         [0., 1., 2., ..., 0., 0., 0.],
         ...,
         [0., 0., 0., ..., 2., 1., 0.],
         [0., 0., 0., ..., 1., 2., 1.],
         [0., 0., 0., ..., 0., 1., 2.]])
code: def __init__(self, arg1, shape=None, dtype=None, copy=False):
      _data_matrix.__init__(self)
  
      if isspmatrix_dia(arg1):
          if copy:
              arg1 = arg1.copy()
          self.data = arg1.data
          self.offsets = arg1.offsets
          self._shape = check_shape(arg1.shape)
      elif isspmatrix(arg1):
          if isspmatrix_dia(arg1) and copy:
              A = arg1.copy()
          else:
              A = arg1.todia()
          self.data = A.data
          self.offsets = A.offsets
          self._shape = check_shape(A.shape)
      elif isinstance(arg1, tuple):
          if isshape(arg1):
              # It's a tuple of matrix dimensions (M, N)
              # create empty matrix
              self._shape = check_shape(arg1)
              self.data = np.zeros(
                  (0, 0), getdtype(dtype, default=float)
              )
              idx_dtype = get_index_dtype(maxval=max(self.shape))
              self.offsets = np.zeros((0), dtype=idx_dtype)
          else:
              try:
                  # Try interpreting it as (data, offsets)
                  data, offsets = arg1
              except Exception as e:
                  raise ValueError(
                      "unrecognized form for dia_matrix constructor"
                  ) from e
              else:
                  if shape is None:
                      raise ValueError("expected a shape argument")
                  self.data = np.atleast_2d(
                      np.array(arg1[0], dtype=dtype, copy=copy)
                  )
                  self.offsets = np.atleast_1d(
                      np.array(
                          arg1[1],
                          dtype=get_index_dtype(maxval=max(shape)),
                          copy=copy,
                      )
                  )
                  self._shape = check_shape(shape)
      else:
          # must be dense, convert to COO first, then to DIA
          try:
              arg1 = np.asarray(arg1)
          except Exception as e:
              raise ValueError(
                  "unrecognized form for"
                  " %s_matrix constructor" % self.format
              ) from e
          from .coo import coo_matrix
  
          A = coo_matrix(arg1, dtype=dtype, shape=shape).todia()
          self.data = A.data
          self.offsets = A.offsets
          self._shape = check_shape(A.shape)
  
      if dtype is not None:
          self.data = self.data.astype(dtype)
  
      # check format
      if self.offsets.ndim != 1:
          raise ValueError("offsets array must have rank 1")
  
      if self.data.ndim != 2:
          raise ValueError("data array must have rank 2")
  
      if self.data.shape[0] != len(self.offsets):
          raise ValueError(
              "number of diagonals (%d) "
              "does not match the number of offsets (%d)"
              % (self.data.shape[0], len(self.offsets))
          )
  
      if len(np.unique(self.offsets)) != len(self.offsets):
          raise ValueError("offset array contains duplicate values")
  
imports: import numpy
  from .base import isspmatrix, _formats, spmatrix
  from .data import _data_matrix
  from .sputils import isshape, upcast_char, getdtype, get_index_dtype, get_sum_dtype, validateaxis, check_shape, matrix
  from ._sparsetools import dia_matvec
label_desc: Use image node_id 1 to create a new dia_matrix object from inherited base classes: _data_matrix with example: obj = dia_matrix(arg1, shape, dtype, copy)