input: 
  def decode_libsvm(input: tf.Tensor, num_features: int, dtype: tf.DType = tf.float32, label_dtype: tf.DType = tf.int64, name: Optional[str] = None) -> Tuple[tf.Tensor, tf.Tensor, tf.Tensor, tf.Tensor]:
      """Convert LibSVM input to tensors. The output consists of a label and a feature tensor.
      
      >>> decode_libsvm(tf.constant(["1 1:0.5"]), 2)
      (<tf.Tensor: shape=(1,), dtype=int64, numpy=array([1])>, <tf.Tensor: shape=(1, 2), dtype=int64, numpy=array([[0, 1]])>, <tf.Tensor: shape=(1,), dtype=float32, numpy=array([0.5], dtype=float32)>, <tf.Tensor: shape=(1,), dtype=int64, numpy=array([2])>)
      >>> decode_libsvm(tf.constant(["0 2:1.0"]), 3, dtype=tf.int32)
      (<tf.Tensor: shape=(1,), dtype=int64, numpy=array([0])>, <tf.Tensor: shape=(1, 2), dtype=int64, numpy=array([[0, 2]])>, <tf.Tensor: shape=(1,), dtype=int32, numpy=array([1], dtype=int32)>, <tf.Tensor: shape=(1,), dtype=int64, numpy=array([3])>)
      """
  
output:     
      def parse_line(line):
          parts = line.decode('utf-8').split()
          label = int(parts[0])
          indices = []
          values = []
          for part in parts[1:]:
              index, value = part.split(':')
              indices.append(int(index))
              values.append(float(value))
          return label, indices, values
  
      labels, indices, values = tf.map_fn(
          parse_line,
          input,
          dtype=(label_dtype, tf.int64, dtype),
          name=name
      )
  
      max_indices = tf.reduce_max(tf.concat(indices, axis=0)) + 1
      num_features = tf.cast(num_features, tf.int64)
      max_indices = tf.minimum(max_indices, num_features)
  
      return labels, indices, values, max_indices
  