
    AVh*,              	       (   d Z ddl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j                  ej                         	 	 	 ddej"                  dej$                  ej"                     dej$                  ej"                     fd       Z ej                  ej&                        	 	 	 ddej"                  dej$                  ej"                     dej$                  ej"                     fd       Zd Zd Zd Zd Zy)z"where operation for RaggedTensors.    N)ops)	array_ops)math_ops)ragged_concat_ops)ragged_functional_ops)ragged_gather_ops)ragged_tensor)ragged_tensor_shape)dispatch	conditionxyc                    |du |du k7  rt        d      t        j                  d|| ||g      5  t        j                  | d      } |t        |       cddd       S t        j                  |d      }t        j                  |d      }t        j                  | ||      \  } }}t        | ||      cddd       S # 1 sw Y   yxY w)a  Return the elements where `condition` is `True`.

  : If both `x` and `y` are None: Retrieve indices of true elements.

    Returns the coordinates of true elements of `condition`. The coordinates
    are returned in a 2-D tensor with shape
    `[num_true_values, dim_size(condition)]`, where `result[i]` is the
    coordinates of the `i`th true value (in row-major order).

  : If both `x` and `y` are non-`None`: Multiplex between `x` and `y`.

    Choose an output shape  from the shapes of `condition`, `x`, and `y` that
    all three shapes are broadcastable to; and then use the broadcasted
    `condition` tensor as a mask that chooses whether the corredsponding element
    in the output should be taken from `x` (if `condition` is true) or `y` (if
    `condition` is false).

  >>> # Example: retrieve indices of true elements
  >>> tf.where(tf.ragged.constant([[True, False], [True]]))
  <tf.Tensor: shape=(2, 2), dtype=int64, numpy= array([[0, 0], [1, 0]])>

  >>> # Example: multiplex between `x` and `y`
  >>> tf.where(tf.ragged.constant([[True, False], [True, False, True]]),
  ...          tf.ragged.constant([['A', 'B'], ['C', 'D', 'E']]),
  ...          tf.ragged.constant([['a', 'b'], ['c', 'd', 'e']]))
  <tf.RaggedTensor [[b'A', b'b'], [b'C', b'd', b'E']]>

  Args:
    condition: A potentially ragged tensor of type `bool`
    x: A potentially ragged tensor (optional).
    y: A potentially ragged tensor (optional).  Must be specified if `x` is
      specified.  Must have the same rank and type as `x`.
    name: A name of the operation (optional).

  Returns:
    : If both `x` and `y` are `None`:
      A `Tensor` with shape `(num_true, rank(condition))`.
    : Otherwise:
      A potentially ragged tensor with the same type as `x` and `y`, and whose
      shape is broadcast-compatible with `x`, `y`, and `condition`.

  Raises:
    ValueError: When exactly one of `x` or `y` is non-`None`; or when
      `condition`, `x`, and `y` have incompatible shapes.
  N1x and y must be either both None or both non-NoneRaggedWherer   namer   r   )
ValueErrorr   
name_scoper	   "convert_to_tensor_or_ragged_tensor_coordinate_wherematch_row_splits_dtypes_elementwise_where_v2r   r   r   r   s       \/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/ragged/ragged_where_op.pywhere_v2r      s    d 4iQ$Y
H
II
~~mTIq!+<= 	4@@%Iyy)		4 	4 
:
:13
Ga

:
:13
Ga%==iANoiA"9a3	4 	4 	4   $B<AB<<Cc                    |du |du k7  rt        d      t        j                  d|| ||g      5  t        j                  | d      } |t        |       cddd       S t        j                  |d      }t        j                  |d      }t        j                  | ||      \  } }}t        | ||      cddd       S # 1 sw Y   yxY w)a
  Return the elements, either from `x` or `y`, depending on the `condition`.

  : If both `x` and `y` are `None`:
    Returns the coordinates of true elements of `condition`. The coordinates
    are returned in a 2-D tensor with shape
    `[num_true_values, dim_size(condition)]`, where `result[i]` is the
    coordinates of the `i`th true value (in row-major order).

  : If both `x` and `y` are non-`None`:
    Returns a tensor formed by selecting values from `x` where condition is
    true, and from `y` when condition is false.  In particular:

    : If `condition`, `x`, and `y` all have the same shape:

      * `result[i1...iN] = x[i1...iN]` if `condition[i1...iN]` is true.
      * `result[i1...iN] = y[i1...iN]` if `condition[i1...iN]` is false.

    : Otherwise:

      * `condition` must be a vector.
      * `x` and `y` must have the same number of dimensions.
      * The outermost dimensions of `condition`, `x`, and `y` must all have the
        same size.
      * `result[i] = x[i]` if `condition[i]` is true.
      * `result[i] = y[i]` if `condition[i]` is false.

  Args:
    condition: A potentially ragged tensor of type `bool`
    x: A potentially ragged tensor (optional).
    y: A potentially ragged tensor (optional).  Must be specified if `x` is
      specified.  Must have the same rank and type as `x`.
    name: A name of the operation (optional)

  Returns:
    : If both `x` and `y` are `None`:
      A `Tensor` with shape `(num_true, dim_size(condition))`.
    : Otherwise:
      A potentially ragged tensor with the same type, rank, and outermost
      dimension size as `x` and `y`.
      `result.ragged_rank = max(x.ragged_rank, y.ragged_rank)`.

  Raises:
    ValueError: When exactly one of `x` or `y` is non-`None`; or when
      `condition`, `x`, and `y` have incompatible shapes.

  #### Examples:

  >>> # Coordinates where condition is true.
  >>> condition = tf.ragged.constant([[True, False, True], [False, True]])
  >>> print(where(condition))
  tf.Tensor( [[0 0] [0 2] [1 1]], shape=(3, 2), dtype=int64)

  >>> # Elementwise selection between x and y, based on condition.
  >>> condition = tf.ragged.constant([[True, False, True], [False, True]])
  >>> x = tf.ragged.constant([['A', 'B', 'C'], ['D', 'E']])
  >>> y = tf.ragged.constant([['a', 'b', 'c'], ['d', 'e']])
  >>> print(where(condition, x, y))
  <tf.RaggedTensor [[b'A', b'b', b'C'], [b'd', b'E']]>

  >>> # Row selection between x and y, based on condition.
  >>> condition = [True, False]
  >>> x = tf.ragged.constant([['A', 'B', 'C'], ['D', 'E']])
  >>> y = tf.ragged.constant([['a', 'b', 'c'], ['d', 'e']])
  >>> print(where(condition, x, y))
  <tf.RaggedTensor [[b'A', b'B', b'C'], [b'd', b'e']]>
  Nr   r   r   r   r   r   )r   r   r   r	   r   r   r   _elementwise_wherer   s       r   wherer    _   s    N 4iQ$Y
H
II
~~mTIq!+<= 	1@@%Iyy)		1 	1 
:
:13
Ga

:
:13
Ga%==iANoiA	1a0	1 	1 	1r   c                    t        | t        j                        }t        |t        j                        }t        |t        j                        }|s|s|st        j                  | ||      S |r*|r(|r&t        j                  t        j                  | ||      S |s| j                  j                  d       t        j                  ||gd      }t        ||j                  j                        }t        ||j                  j                        }t        j                  | t        j                  |      |t        j                  |      z         }	t!        j"                  ||	      S t%        d      )z,Ragged version of tf.where(condition, x, y).   r   axisout_typezInput shapes do not match.)
isinstancer	   RaggedTensorr   r    r   map_flat_valuesshapeassert_has_rankr   concat_nrows
row_splitsdtyper   ranger   gatherr   )
r   r   r   condition_is_raggedx_is_raggedy_is_raggedx_and_yx_nrowsy_nrowsindicess
             r   r   r      s#   "9m.H.HI1m889+1m889+
??9a++{{ 00)Q124 4OO##A&&&1vA6GQ!3!3!9!9:GQ!3!3!9!9:Gooi)@%w(??AG##GW55 1
22    c                    | j                   j                         rf|j                   j                         rL|j                   j                         r2|j                   |j                   k(  r| j                   |j                   k(  st        j                  j	                  |       }t        j                  j	                  |      }t        j                  j	                  |      }t        j
                  |t        j
                  ||            }t        j                  | |      } t        j                  ||      }t        j                  ||      }t        | t        j                        }t        |t        j                        }t        |t        j                        }	|s|s|	st        j                  | ||      S t        j                  t        j                  | ||      S )z/Ragged version of tf.where_v2(condition, x, y).)r*   is_fully_definedr
   RaggedTensorDynamicShapefrom_tensorbroadcast_dynamic_shapebroadcast_tor'   r	   r(   r   r   r   r)   )
r   r   r   shape_cshape_xshape_yr*   r2   r3   r4   s
             r   r   r      sf    //
*
*
,1I1I1K
''
"
"
$AGG);
//QWW
$!::FFG!::FFqIG!::FFqIG77$<<WgNPE#00EBI((E2A((E2A"9m.H.HI1m889+1m889+
iA..		.	.y/A/A9a/0
2 2r9   c                    t        | t        j                        st        j                  |       S t        | j                        }| j                  |j                        } |dddf   }t        j                  | j                         |      }t        j                  | j                  |      }||z
  }t        j                  t        j                  |d      t        j                  |d      |ddddf   gd      S )z&Ragged version of tf.where(condition).Nr   r"   r#   )r'   r	   r(   r   r    r   valueswith_row_splits_dtyper/   r1   value_rowidsr.   r,   expand_dims)r   selected_coordsfirst_indexselected_rowsselected_row_startsselected_colss         r   r   r      s    	I}99	:??9%% &i&6&67/ --o.C.CD)1%+""9#9#9#;[I-!(()=)=}M 33- 
		M1-M1-q!"u/E  !	
" "r9   c                     t        | t        j                        r| j                  |      S t	        j
                  | |      d   S )Nr%   r   )r'   r	   r(   nrowsr   r*   )rt_inputr&   s     r   r-   r-      s9    -445>>8>,,??8h7::r9   )NNN)__doc__typingtensorflow.python.frameworkr   tensorflow.python.opsr   r   tensorflow.python.ops.raggedr   r   r   r	   r
   tensorflow.python.utilr   dispatch_for_apir   RaggedOrDenseOptionalr    r   r   r   r-    r9   r   <module>rZ      s   )  + + * : > : 6 < + 9--.?C?C=433 =4 ; ;<=4 ; ;<=4 /=4@ 9??+<@<@Q1]00 Q1__]889Q1__]889Q1 ,Q1h3424".;r9   