
    AVh!                         d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
  e
d      ej                  d	               Zd
 Zd Zy)zSupport for ragged tensors.    )dtypes)tensor_shape)ragged_config)ragged_tensor)dispatch)	tf_exportzragged.map_flat_valuesc           
         g }g }t        |||      }t        |||      }|s | |i |S |r8t        |      }t        |      dk7  rt        d|z        |j	                         }nd}t        d |D              }t        |      dkD  r[t        j                         st        d      |D 	cg c]/  }|D 	cg c]!  }	|	j                  t        j                        # c}	1 }}}	 | |i |}
|;|
j                  dd j                  |g      st        d|
j                  d|d      t        j                  j                  |
t        |      d	
      S c c}	w c c}	}w )a	  Applies `op` to the `flat_values` of one or more RaggedTensors.

  Replaces any `RaggedTensor` in `args` or `kwargs` with its `flat_values`
  tensor (which collapses all ragged dimensions), and then calls `op`.  Returns
  a `RaggedTensor` that is constructed from the input `RaggedTensor`s'
  `nested_row_splits` and the value returned by the `op`.

  If the input arguments contain multiple `RaggedTensor`s, then they must have
  identical `nested_row_splits`.

  This operation is generally used to apply elementwise operations to each value
  in a `RaggedTensor`.

  Warning: `tf.ragged.map_flat_values` does *not* apply `op` to each row of a
  ragged tensor.  This difference is important for non-elementwise operations,
  such as `tf.reduce_sum`.  If you wish to apply a non-elementwise operation to
  each row of a ragged tensor, use `tf.map_fn` instead.  (You may need to
  specify an `output_signature` when using `tf.map_fn` with ragged tensors.)

  Examples:

  >>> rt = tf.ragged.constant([[1, 2, 3], [], [4, 5], [6]])
  >>> tf.ragged.map_flat_values(tf.ones_like, rt)
  <tf.RaggedTensor [[1, 1, 1], [], [1, 1], [1]]>
  >>> tf.ragged.map_flat_values(tf.multiply, rt, rt)
  <tf.RaggedTensor [[1, 4, 9], [], [16, 25], [36]]>
  >>> tf.ragged.map_flat_values(tf.add, rt, 5)
  <tf.RaggedTensor [[6, 7, 8], [], [9, 10], [11]]>

  Example with a non-elementwise operation (note that `map_flat_values` and
  `map_fn` return different results):

  >>> rt = tf.ragged.constant([[1.0, 3.0], [], [3.0, 6.0, 3.0]])
  >>> def normalized(x):
  ...   return x / tf.reduce_sum(x)
  >>> tf.ragged.map_flat_values(normalized, rt)
  <tf.RaggedTensor [[0.0625, 0.1875], [], [0.1875, 0.375, 0.1875]]>
  >>> tf.map_fn(normalized, rt)
  <tf.RaggedTensor [[0.25, 0.75], [], [0.25, 0.5, 0.25]]>

  Args:
    op: The operation that should be applied to the RaggedTensor `flat_values`.
      `op` is typically an element-wise operation (such as math_ops.add), but
      any operation that preserves the size of the outermost dimension can be
      used.  I.e., `shape[0]` of the value returned by `op` must match
      `shape[0]` of the `RaggedTensor`s' `flat_values` tensors.
    *args: Arguments for `op`.
    **kwargs: Keyword arguments for `op`.

  Returns:
    A `RaggedTensor` whose `ragged_rank` matches the `ragged_rank` of all
    input `RaggedTensor`s.
  Raises:
    ValueError: If args contains no `RaggedTensors`, or if the `nested_splits`
      of the input `RaggedTensor`s are not identical.
     z\Input RaggedTensors' flat_values must all have the same outer-dimension size.  Got sizes: %sNc              3   :   K   | ]  }|d    j                     yw)r   N)dtype).0ps     b/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/ragged/ragged_functional_ops.py	<genexpr>z"map_flat_values.<locals>.<genexpr>m   s     =1=s   zInput RaggedTensors have mismatched row partition dtypes; use RaggedTensor.with_row_splits_dtype() to convert them to compatible dtypes.ztf.ragged.map_flat_values requires that the output of `op` have the same outer-dimension size as flat_values of any ragged inputs. (output shape: z!; expected outer dimension size: )F)validate) _replace_ragged_with_flat_valuessetlen
ValueErrorpopr   auto_cast_partition_dtype
with_dtyper   int64shapeis_compatible_withr   RaggedTensor_from_nested_row_partitions_merge_partition_lists)opargskwargspartition_listsflat_values_nrows
inner_argsinner_kwargspartition_dtypespartition_listr   	op_outputs              r   map_flat_valuesr*      s   z //o0AC*1&/2CE,	tv -.
" C() * * *--/=_==	Q224 < = = .  !	" 
fll	# 	"O  *--)"??2A113D2EF ??-/0 0 
	#	#	?	?_- 
@ 
 !	"s   )	E2&EEEc                 J   t        j                  |       rt        j                  |       } j                  | j                         t        j                  | j                  j                  d      j                  }|j                  |       | j                  S fdt        | t              r| D cg c]
  } |       c}S t        | t              rt        fd| D              S t        | t              r"t        fd| j                         D              S | S c c}w )a  Replace RaggedTensors with their flat_values, and record their partitions.

  Returns a copy of `value`, with any nested `RaggedTensor`s replaced by their
  `flat_values` tensor.  Looks inside lists, tuples, and dicts.

  Appends each `RaggedTensor`'s `RowPartition`s to `partition_lists`.

  Args:
    value: The value that should be transformed by replacing `RaggedTensors`.
    partition_lists: An output parameter used to record the row partitions
      for any `RaggedTensors` that were replaced.
    flat_values_nrows: An output parameter used to record the outer dimension
      size for each replacement `flat_values` (when known).  Contains a list of
      int.

  Returns:
    A copy of `value` with nested `RaggedTensors` replaced by their `values`.
  r   c                     t        |       S N)r   )vr$   r#   s    r   recursez1_replace_ragged_with_flat_values.<locals>.recurse   s    +A,=? ?    c              3   .   K   | ]  } |        y wr-    )r   r.   r/   s     r   r   z3_replace_ragged_with_flat_values.<locals>.<genexpr>   s     ++s   c              3   8   K   | ]  \  }}| |      f  y wr-   r2   )r   kr.   r/   s      r   r   z3_replace_ragged_with_flat_values.<locals>.<genexpr>   s     <FQGAJ<s   )r   	is_ragged"convert_to_tensor_or_ragged_tensorappend_nested_row_partitionsr   dimension_at_indexflat_valuesr   value
isinstancelisttupledictitems)r;   r#   r$   nrowsr.   r/   s    ``  @r   r   r      s    ( U#<<UCE5778++E,=,=,C,CQGMMEu%? t %&1GAJ&&%+U+++%<ekkm<<<L 's   6D c                     t        | d         }| dd D ]W  }t        |      t        |      k7  rt        d      t        t        |            D ]  }||   j	                  ||         ||<    Y |S )a"  Merges the given list of lists of RowPartitions.

  Args:
    partition_lists: A list of lists of RowPartition.

  Returns:
    A list of RowPartitions, where `result[i]` is formed by merging
    `partition_lists[j][i]` for all `j`, using
    `RowPartition._merge_precomputed_encodings`.
  r   r
   Nz1All ragged inputs must have the same ragged_rank.)r=   r   r   range_merge_precomputed_encodings)r#   dstsrcis       r   r   r      s     	_Q #QR  ;c
3x3s8JKK3s8_ ;1v223q6:c!f;; 
*r0   N)__doc__tensorflow.python.frameworkr   r   tensorflow.python.ops.raggedr   r   tensorflow.python.utilr    tensorflow.python.util.tf_exportr   add_dispatch_supportr*   r   r   r2   r0   r   <module>rN      sR    " . 4 6 6 + 6 #$	m  %m`(Vr0   