
    AVhFN                     *   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	 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 ddlmZ ddlmZ ddlmZ  edg       ej.                  d               Zd Zd Zd Zd Zd Zd Zd Zd Z y)z4Python-style indexing and slicing for RaggedTensors.    )context)dtypes)ops)tensor)tensor_shape)tensor_util)	array_ops)	check_ops)cond)math_ops)ragged_gather_ops)ragged_math_ops)ragged_tensor)dispatch)	tf_exportz__operators__.ragged_getitem)v1c                 8   t        | t        j                        st        d      | gt	        t        |            z   }t        |t        t        f      rt	        |      }n|g}t        j                  dd|      5  t        | |      cddd       S # 1 sw Y   yxY w)ak
  Returns the specified piece of this RaggedTensor.

  Supports multidimensional indexing and slicing, with one restriction:
  indexing into a ragged inner dimension is not allowed.  This case is
  problematic because the indicated value may exist in some rows but not
  others.  In such cases, it's not obvious whether we should (1) report an
  IndexError; (2) use a default value; or (3) skip that value and return a
  tensor with fewer rows than we started with.  Following the guiding
  principles of Python ("In the face of ambiguity, refuse the temptation to
  guess"), we simply disallow this operation.

  Args:
    rt_input: The RaggedTensor to slice.
    key: Indicates which piece of the RaggedTensor to return, using standard
      Python semantics (e.g., negative values index from the end).  `key`
      may have any of the following types:

      * `int` constant
      * Scalar integer `Tensor`
      * `slice` containing integer constants and/or scalar integer
        `Tensor`s
      * `Ellipsis`
      * `tf.newaxis`
      * `tuple` containing any of the above (for multidimensional indexing)

  Returns:
    A `Tensor` or `RaggedTensor` object.  Values that include at least one
    ragged dimension are returned as `RaggedTensor`.  Values that include no
    ragged dimensions are returned as `Tensor`.  See above for examples of
    expressions that return `Tensor`s vs `RaggedTensor`s.

  Raises:
    ValueError: If `key` is out of bounds.
    ValueError: If `key` is not supported.
    TypeError: If the indices in `key` have an unsupported type.

  Examples:

  >>> # A 2-D ragged tensor with 1 ragged dimension.
  >>> rt = tf.ragged.constant([['a', 'b', 'c'], ['d', 'e'], ['f'], ['g']])
  >>> rt[0].numpy()                 # First row (1-D `Tensor`)
  array([b'a', b'b', b'c'], dtype=object)
  >>> rt[:3].to_list()              # First three rows (2-D RaggedTensor)
  [[b'a', b'b', b'c'], [b'd', b'e'], [b'f']]
  >>> rt[3, 0].numpy()              # 1st element of 4th row (scalar)
  b'g'

  >>> # A 3-D ragged tensor with 2 ragged dimensions.
  >>> rt = tf.ragged.constant([[[1, 2, 3], [4]],
  ...                          [[5], [], [6]],
  ...                          [[7]],
  ...                          [[8, 9], [10]]])
  >>> rt[1].to_list()               # Second row (2-D RaggedTensor)
  [[5], [], [6]]
  >>> rt[3, 0].numpy()              # First element of fourth row (1-D Tensor)
  array([8, 9], dtype=int32)
  >>> rt[:, 1:3].to_list()          # Items 1-3 of each row (3-D RaggedTensor)
  [[[4]], [[], [6]], [], [[10]]]
  >>> rt[:, -1:].to_list()          # Last item of each row (3-D RaggedTensor)
  [[[4]], [[6]], [[7]], [[10]]]
  z+Ragged __getitem__ expects a ragged_tensor.NRaggedGetItem)

isinstancer   RaggedTensor	TypeErrorlist_tensors_in_key_listtupler   
name_scope_ragged_getitem)rt_inputkeyscope_tensorss      [/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/ragged/ragged_getitem.pyragged_tensor_getitemr!   "   s    @ 
Hm88	9
A
BB*t$8$=>>-dE]#
s)C%C
~~dO]; *8S)* * *s   :BBc                 4   |s| S |d   }|dd }|t         u r,t        || j                  j                        }t	        | |      S |t
        j                  u rt	        | |      }t        j                  |j                  j                  d      }|j                  |j                  }n8t        j                  |j                  |j                  j                        d   }t        j                  j                  ||dz
  dd      S t        |t               rht#        | |      }| j$                  Dt        j                  j                  |j&                  | j$                  |j)                               }t+        ||      S | j                  dd }| j                  dd }	t-        j.                         r3	 t1        |      t3        |      k\  rt5        d	j7                  |            	 | j&                  ||   |	|    }
|
j=                  |      S # t8        t:        f$ r Y 7w xY w)
a0  Helper for indexing and slicing ragged tensors with __getitem__().

  Extracts the specified piece of the `rt_input`.  See
  `RaggedTensor.__getitem__` for examples and restrictions.

  Args:
    rt_input: The `RaggedTensor` from which a piece should be returned.
    key_list: The list of keys specifying which piece to return. Each key
      corresponds with a separate dimension.

  Returns:
    The indicated piece of rt_input.

  Raises:
    ValueError: If `key_list` is not supported.
    TypeError: If any keys in `key_list` have an unsupported type.
  r      Nout_typeFnrowsvalidate)r'   zRow key {} out of bounds)Ellipsis_expand_ellipsisshapendimsr   r	   newaxisr   dimension_at_index
row_splitsvaluedtyper   r   from_uniform_row_lengthr   slice_slice_ragged_row_dimensionuniform_row_lengthvaluesr'    _ragged_getitem_inner_dimensionsr   executing_eagerlyintlen
IndexErrorformatr   
ValueError__getitem__)r   key_listrow_key
inner_keysexpanded_key_listinner_rtnsplitssliced_rt_inputstartslimitsrows              r    r   r   m   s   $ 
OQK'|*(8>>3G3GH8%677 	!!!x4H--h.A.A.G.GKG}} g 3 3)1)<)<)B)BDDEGg%%=='A+Q > 8 8
 1(GDO"".
 &22JJ

 
 ("="=%%' K )o ,OZHH
   "%F  $F  " w<3v;&5<<WEF
F ' //&/&/
:C??:&& $ s   -1H HHc                 0   |j                   |j                  |j                  | S | j                  dd |   }| j                  dd |   }t	        j
                  dg| j                  j                        }|j                  |j                  dk(  rot	        j                  |t	        j                  |      d |dd |gd      }|d   }|d   }t        j                  j                  | j                  || ||z
  d      S t        ||d| j                        S )a  Slice the outer dimension of `rt_input` according to the given `slice`.

  Args:
    rt_input: The `RaggedTensor` to slice.
    row_key: The `slice` object that should be used to slice `rt_input`.

  Returns:
    A `RaggedTensor` containing the indicated slice of `rt_input`.
  Nr)   r#   r   )axisF)r(   )startstopstepr0   r	   zerosr2   concatsizer   r   from_row_splitsr7   &_build_ragged_tensor_from_value_ranges)r   rA   
new_starts
new_limitszero_pad
new_splitsvalues_startvalues_limits           r    r5   r5      s(    ]]w||38LO ""3B'0*""12&w/*__aS("5"5";";<( \\W\\Q. !!	)..,-	.
2A
KJ a=Lb>L%%55\2J4M 6   2*j!2://C C    c                 	   |s| S t        | t        j                        s | j                  t	        ddd      g|z         S |d   t
        u r6t        || j                  j                  j                        }t        | |      S t        j                  u rt        | |dd       }t        j                  |j                  j                  d      }|j                   |j                   }n8t        j                  |j                  |j                  j"                        d   }t        j                  j%                  |d|dz
  d      S t        t              rj&                  @j(                  4j*                  (| j-                  t        | j                  |dd             S t        j&                  t.        j0                  t2        t5        d      f      r4t        j(                  t.        j0                  t2        t5        d      f      st7        d      | j                  dd | j                  dd j*                  dnj*                  }t9        |fd	fd
      t9        |fdfd      j&                  t9        |fdfd      }nKt;        j<                  j&                  j"                        t9        j&                  fdfd      }j(                  t9        |fdfd      }nKt;        j<                  j(                  j"                        t9        j(                  fdfd      }t?        ||j*                  | j                        }| j@                  OtC        | j@                        }t        j                  j%                  |j                  || jE                               }|j-                  t        |j                  |dd             S | j@                  tG        d      | j@                  t;        j<                  j"                        d}	tI        jJ                   |	      tI        jL                  |	      g}
tO        jP                  |
      5  t9        fdfd      }| j                  |d   }t        ||dd       cddd       S # 1 sw Y   yxY w)aH  Retrieve inner dimensions, keeping outermost dimension unchanged.

  Args:
    rt_input: The `RaggedTensor` or `Tensor` from which a piece should be
      extracted.
    key_list: The __getitem__ keys for slicing the inner dimensions.

  Returns:
    A `RaggedTensor`.

  Raises:
    ValueError: If key_list is not supported.
  Nr   r#   r$   Fr&   z&slice offsets must be integers or Noner)   c                       S N rG   s   r    <lambda>z2_ragged_getitem_inner_dimensions.<locals>.<lambda>&      f rZ   c                       dz
  S Nr#   r^   r_   s   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>&      fqj rZ   c                       S r]   r^   rH   s   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>'  ra   rZ   c                       dz
  S rc   r^   rf   s   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>'  rd   rZ   c                       S r]   r^   r_   s   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>*      F rZ   c                       dz
  S rc   r^   rf   s   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>*      FQJ rZ   c                  6    t        j                   z         S r]   r   minimum)start_offsetrG   upper_bounds   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>/      H$$Vl%:KH rZ   c                  6    t        j                   z         S r]   r   maximum)rH   lower_boundro   s   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>0  rq   rZ   c                       S r]   r^   rf   s   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>3  ri   rZ   c                       dz
  S rc   r^   r_   s   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>3  rk   rZ   c                  6    t        j                   z         S r]   rm   )rG   stop_offsetrp   s   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>8      H$$Vk%9;G rZ   c                  6    t        j                   z         S r]   rs   )rH   ru   ry   s   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>9  rz   rZ   z,Cannot index into an inner ragged dimension.z6Index out of bounds when indexing into a ragged tensor)messagec                       S r]   r^   )
column_keys   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>W  s    Z rZ   c                       z   S r]   r^   )r~   
row_lengths   r    r`   z2_ragged_getitem_inner_dimensions.<locals>.<lambda>X  s    j!8 rZ   ))r   r   r   r?   r4   r*   r+   r7   r,   r-   r8   r	   r.   r   r/   r0   r1   r2   r3   rL   rM   rN   with_values
tensor_libTensorr:   typer   _if_ge_zeror   castrS   r6   _slice_lengthr'   r>   r
   assert_greater_equalassert_lessr   control_dependencies)r   r@   rC   rD   rE   rN   inner_rt_startsinner_rt_limitsnew_row_lengthoob_err_msg
oob_checksoffset	sliced_rtr~   rH   ru   r   ro   rG   ry   rp   s                @@@@@@@@r    r8   r8      s    
O	Hm88	9tT4!8 9H DEE{*8(8??3H3H3N3NO+H6GHH
 9$$$/(12,GH--h.A.A.G.GKG}} g


(;(;(A(A	g %%==!7Q; > 8 8 
E" Z__%<!!
*8??HQRL
IK K Z%%
(9(93T
'K
L:+<+<c4:*NO@AA ""3B'f""12&f//)Qzdn6HIkn6HIk				!%dN<NO}}Z%5%5v||D%HHJ
 
	 %dN<NOmmJOOV\\B%OOGGI 8
?JOOX__Nh 
	$	$	0&x'B'BJO --EEOO^X^^-=?!!
*8??HQRL
IK K   (
C
DD
 ***}}Z)9)9:*H+$$
zk;8J
KH*
 
+ E%78:F 2
 23I+Ix|D	E E Es    5R??Sc                     t        j                  | t        j                        }t        j                  ||   | j
                        S )aj  Computes the number of elements in a slice of a value with a given length.

  Returns the equivalent of: `len(range(value_length)[slice_key])`

  Args:
    value_length: Scalar int `Tensor`: the length of the value being sliced.
    slice_key: A `slice` object used to slice elements from the value.

  Returns:
    The number of elements in the sliced value.
  )r2   r$   )r	   rO   r   boolrQ   r2   )value_length	slice_keyrO   s      r    r   r   ]  s4    " //,fkk
:%	i(<3E3E	FFrZ   c                     |t        d      t        d | D              }||dz   kD  rt        d      ||dz   k(  r| dd S t        ddd      g| z   S )aH  Expands the ellipsis at the start of `key_list`.

  Assumes that the first element of `key_list` is Ellipsis.  This will either
  remove the Ellipsis (if it corresponds to zero indices) or prepend a new
  `slice(None, None, None)` (if it corresponds to more than zero indices).

  Args:
    key_list: The arguments to `__getitem__()`.
    num_remaining_dims: The number of dimensions remaining.

  Returns:
    A copy of `key_list` with he ellipsis expanded.
  Raises:
    ValueError: If ragged_rank.shape.ndims is None
    IndexError: If there are too many elements in `key_list`.
  Nz6Ellipsis not supported for unknown shape RaggedTensorsc              3   F   K   | ]  }|t         j                  usd   yw)r#   N)r	   r.   ).0idxs     r    	<genexpr>z#_expand_ellipsis.<locals>.<genexpr>  s     J#S	8I8I-IAJs   !!r#   z!Too many indices for RaggedTensor)r>   sumr<   r4   )r@   num_remaining_dimsnum_indicess      r    r+   r+   r  sq    " 
M
NNJJJ+%))
8
99(1,,AB<$d#$x//rZ   c              #     K   t        | t        j                        r|  t        | t        t        f      r| D ]  }t        |      D ]  }|   t        | t              r[t        | j                        D ]  }|  t        | j                        D ]  }|  t        | j                        D ]  }|  yyw)z.Generates all Tensors in the given slice spec.N)
r   r   r   r   r   r   r4   rL   rM   rN   )r@   vr   s      r    r   r     s     *++,
N4-( (+ & % &x~~6 l&x}}5 l&x}}5 l !s   B<B>c                    |d}t        j                  |d      }|j                  j                  r!t	        j
                  || j                        }nt        d      t        j                  | ||| j                        }t        |t        j                        r"t        j                  ||j                        }n!t        j                  ||j                        }|j!                  |      S )a  Returns a `RaggedTensor` containing the specified sequences of values.

  Returns a RaggedTensor `output` where:

  ```python
  output.shape[0] = starts.shape[0]
  output[i] = values[starts[i]:limits[i]:step]
  ```

  Requires that `starts.shape == limits.shape` and
  `0 <= starts[i] <= limits[i] <= values.shape[0]`.

  Args:
    starts: 1D integer Tensor specifying the start indices for the sequences of
      values to include.
    limits: 1D integer Tensor specifying the limit indices for the sequences of
      values to include.
    step: Integer value specifying the step size for strided slices.
    values: The set of values to select from.

  Returns:
    A `RaggedTensor`.

  Raises:
    ValueError: Until the prerequisite ops are checked in.
  r#   rN   )namez&slice strides must be integers or None)row_splits_dtype)paramsindices)r   convert_to_tensorr2   
is_integerr   r   r   r   ranger   r   r   r   gatherr7   r	   r   )rG   rH   rN   r7   value_indicesgathered_valuess         r    rS   rS     s    8 
\D			t&	1$	ZZ==v||,D
<
==!''9?G- 223'..}335O  &&}335O 
	"	"?	33rZ   c                     t        | t        j                        r3t        j                  |       }|t        j
                  | dk\  ||      S |} | dk\  r |       S  |       S )z2Returns `true_fn() if value >= 0 else false_fn()`.r   )r   r   r   r   constant_valuer   )r1   true_fnfalse_fnconst_values       r    r   r     s]     z((),,U3KYYuz7H55e
aZ9:rZ   N)!__doc__tensorflow.python.eagerr   tensorflow.python.frameworkr   r   r   r   r   r   tensorflow.python.opsr	   r
   r   r   tensorflow.python.ops.raggedr   r   r   tensorflow.python.utilr    tensorflow.python.util.tf_exportr   add_dispatch_supportr!   r   r5   r8   r   r+   r   rS   r   r^   rZ   r    <module>r      s    ; + . + < 4 3 + + & * : 8 6 + 6 )b1	F*  2F*RQ'h%CPqEhG*08"/4drZ   