code: def parse_matrix(x, dtype=None):
      
  
      # Split input by spaces, convert each row into a vector and stack them vertically to get a matrix
      matrix = [parse_vector(x, dtype=float) for x in x.split()]
  
      # Get the size of each row vector and then remove duplicate sizes
      # There should be exactly one value in the matrix because all row sizes need to be the same
      if len(np.unique([len(x) for x in matrix])) != 1:
          raise NRRDError('Matrix should have same number of elements in each row')
  
      matrix = np.vstack(matrix)
  
      # If using automatic datatype detection, then start by converting to float and determining if the number is whole
      # Truncate to integer if dtype is int also
      if dtype is None:
          matrix_trunc = matrix.astype(int)
  
          if np.all((matrix - matrix_trunc) == 0):
              matrix = matrix_trunc
      elif dtype == int:
          matrix = matrix.astype(int)
      elif dtype != float:
          raise NRRDError('dtype should be None for automatic type detection, float or int')
  
      return matrix
docs: Parse NRRD matrix from string into (M,N) :class:`numpy.ndarray`.
  
      See :ref:`user-guide:int matrix` and :ref:`user-guide:double matrix` for more information on the format.
  
      Parameters
      ----------
      x : :class:`str`
          String containing NRRD matrix
      dtype : data-type, optional
          Datatype to use for the resulting Numpy array. Datatype can be :class:`float`, :class:`int` or :obj:`None`. If
          :obj:`dtype` is :obj:`None`, then it will be automatically determined by checking any of the elements
          for fractional numbers. If found, then the matrix will be converted to :class:`float`, otherwise :class:`int`.
          Default is to automatically determine datatype.
  
      Returns
      -------
      matrix : (M,N) :class:`numpy.ndarray`
          Matrix that is parsed from the :obj:`x` string