code: def log1p(
      data: Union[AnnData, np.ndarray, spmatrix],
      copy: bool = False,
      chunked: bool = False,
      chunk_size: Optional[int] = None,
  ) -> Optional[AnnData]:
      
      if copy:
          if not isinstance(data, AnnData):
              data = data.astype(np.floating)
          else:
              data = data.copy()
      elif not isinstance(data, AnnData) and np.issubdtype(data.dtype, np.integer):
          raise TypeError("Cannot perform inplace log1p on integer array")
  
      def _log1p(X):
          if issparse(X):
              np.log1p(X.data, out=X.data)
          else:
              np.log1p(X, out=X)
          return X
  
      if isinstance(data, AnnData):
          if not np.issubdtype(data.X.dtype, np.floating):
              data.X = data.X.astype(np.float32)
          if chunked:
              for chunk, start, end in data.chunked_X(chunk_size):
                   data.X[start:end] = _log1p(chunk)
          else:
              _log1p(data.X)
      else:
          _log1p(data)
  
      return data if copy else None
docs: Logarithmize the data matrix.
  
      Computes :math:`X = \\log(X + 1)`, where :math:`log` denotes the natural logarithm.
  
      Parameters
      ----------
      data
          The (annotated) data matrix of shape ``n_obs`` × ``n_vars``.
          Rows correspond to cells and columns to genes.
      copy
          If an :class:`~anndata.AnnData` is passed, determines whether a copy
          is returned.
      chunked
          Process the data matrix in chunks, which will save memory.
          Applies only to :class:`~anndata.AnnData`.
      chunk_size
          ``n_obs`` of the chunks to process the data in.
  
      Returns
      -------
      Returns or updates ``data``, depending on ``copy``.