
    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 ddlmZ ddlmZ ddlmZ ddlmZ  ej*                  d      dej,                  fd       Z ej*                  d      dej,                  fd       Z ej*                  d      dej,                  fd       Zd'dZd Zd Zd ZdZd Zd Z  ej*                  d      dej,                  fd       Z!dej,                  fd Z" ej*                  d!      dej,                  fd"       Z# ej*                  d#      dej,                  fd$       Z$ ej*                  d%      dej,                  fd&       Z% ej*                  d'      dej,                  fd(       Z& ej*                  d)      dej,                  fd*       Z' ej*                  d+      dej,                  fd,       Z(d'd-Z)d. Z* ej*                  d/      dej,                  fd0       Z+ ej*                  d1      dej,                  fd2       Z, ej*                  d3      dej,                  fd4       Z- ej*                  d5      dej,                  fd6       Z. ej*                  d7      dej,                  fd8       Z/ ej*                  d9      dej,                  fd:       Z0dej,                  fd;Z1 ej*                  d<      dej,                  fd=       Z2 ej*                  d>      dej,                  fd?       Z3 ej*                  d@      dej,                  fdA       Z4	 	 d(dBZ5dej,                  fdCZ6 ej*                  dD      dej,                  fdE       Z7 ej*                  dF      dej,                  fdG       Z8 ej*                  dH      dej,                  fdI       Z9 ej*                  dJ      dej,                  fdK       Z: ej*                  dL      dej,                  fdM       Z; ej*                  dN      dO        Z< ej*                  dP      dej,                  fdQ       Z= ej*                  dR      dej,                  fdS       Z> ej*                  dT      dej,                  fdU       Z? ej*                  dV      dej,                  fdW       Z@ ej*                  dX      dej,                  fdY       ZA ej*                  dZ      dej,                  fd[       ZB ej*                  d\      dej,                  fd]       ZC ej*                  d^      dej,                  fd_       ZD ej*                  d`      dej,                  fda       ZE ej*                  db      dej,                  fdc       ZF ej*                  dd      dej,                  fde       ZG ej*                  df      dej,                  fdg       ZH ej*                  dh      dej,                  fdi       ZI ej*                  dj      dej,                  fdk       ZJ ej*                  dl      dej,                  fdm       ZK ej*                  dn      dej,                  fdo       ZL ej*                  dp      dej,                  fdq       ZM ej*                  dr      dej,                  fds       ZN ej*                  dt      dej,                  fdu       ZO ej*                  dv      dej,                  fdw       ZP ej*                  dx      dej,                  fdy       ZQ ej*                  dz      dej,                  fd{       ZR ej*                  d|      dej,                  fd}       ZS ej*                  d~      dej,                  fd       ZT ej*                  d      dej,                  fd       ZU ej*                  d      dej,                  fd       ZV ej*                  d      dej,                  fd       ZW ej*                  d      dej,                  fd       ZX ej*                  d      dej,                  fd       ZY ej*                  d      dej,                  fd       ZZ ej*                  d      dej,                  fd       Z[ ej*                  d      dej,                  fd       Z\ ej*                  d      dej,                  fd       Z] ej*                  d      dej,                  fd       Z^ ej*                  d      dej,                  fd       Z_ ej*                  d      dej,                  fd       Z` ej*                  d      dej,                  fd       Za ej*                  d      dej,                  fd       Zb ej*                  d      dej,                  fd       Zc ej*                  d      dej,                  fd       Zd ej*                  d      dej,                  fd       Ze ej*                  d      dej,                  fd       Zf ej*                  d      dej,                  fd       Zg ej*                  d      dej,                  fd       Zh ej*                  d      dej,                  fd       Zi ej*                  d      dej,                  fd       Zj ej*                  d      dej,                  fd       Zk ej*                  d      dej,                  fd       Zl ej*                  d      dej,                  fd       Zm ej*                  d      dej,                  fd       Zn ej*                  d      dej,                  fd       Zo ej*                  d      dej,                  fd       Zp ej*                  d      dej,                  fd       Zq ej*                  d      dej,                  fd       Zr ej*                  d      dej,                  fd       Zs ej*                  d      dej,                  fd       Zt ej*                  d      dej,                  fd       Zu ej*                  d«      dej,                  fdÄ       Zv ej*                  dī      dej,                  fdń       Zw ej*                  dƫ      dej,                  fdǄ       Zx ej*                  dȫ      dej,                  fdɄ       Zy ej*                  dʫ      dej,                  fd˄       Zzd̄ Z{ ej*                  dͫ       ej*                  dΫ      dej,                  fdτ              Z| ej*                  dЫ      dej,                  fdф       Z} ej*                  dҫ      dej,                  fdӄ       Z~ ej*                  dԫ      dej,                  fdՄ       Z ej*                  d֫      dej,                  fdׄ       Z ej*                  dث      dل        Z ej*                  dګ      dej,                  fdۄ       Z ej*                  dܫ      d݄        Z ej*                  dޫ      dej,                  fd߄       Z ej*                  d      dej,                  fd       Z ej*                  d      dej,                  fd       Zdej,                  fdZdej,                  fdZ ej*                  d      dej,                  fd       Z ej*                  d      dej,                  fd       Z ej*                  d      dej,                  fd       Z ej                  d        ej                  d        ej                  d        ej                  d        ej                  d        ej                  d        ej                  d        ej                  d        ej                  d        ej                  d        ej*                  d      dej,                  fd       Z ej*                  d      dej,                  fd       Zdej,                  fdZdej,                  fdZ ej*                  d      dej,                  fd       Z ej*                  d      dej,                  fd       Z ej*                  d       d        Z ej*                  d      d        Z ej*                  d      d        Z ej*                  d      d        Z ej*                  d      dej,                  fd	       Z ej*                  d
       ej*                  d      dej,                  fd              Z ej                  d        ej                  d        ej*                  d      dej,                  fd       Z ej*                  d      d        Z ej*                  d      d        Z ej*                  d      dej,                  fd       Z ej*                  d      d        Z ej*                  d      dej,                  fd       Z ej*                  d      dej,                  fd       Z ej*                  d      dej,                  fd       Z ej*                  d      dej,                  fd        Z ej*                  d!      dej,                  fd"       Z ej*                  d#      dej,                  fd$       Z ej*                  d%      dej,                  fd&       Zy()  z/Gradients for operators defined in math_ops.py.    N)compat)context)constant_op)dtypes)indexed_slices)ops)tensor)tensor_util)	array_ops)gen_array_ops)gen_math_ops)math_ops)special_math_opsArgMaxopc                     ~ ~d d gS N r   grads     O/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/math_grad.py_ArgMaxGradr   !       $
    ArgMinc                     ~ ~d d gS r   r   r   s     r   _ArgMinGradr   '   r   r   EuclideanNormc                 p   | j                   d   }| j                  d      sot        j                  t	        j
                  | j                  d         | j                  d         }t	        j                  ||      }t	        j                  ||      }t        j                  | j                  d   ||z        dfS )zGradient for EuclideanNorm.r   	keep_dims   N)	outputsget_attrr   reduced_shaper   shapeinputsreshapetruediv)r   r   outputoutput_shape_kept_dimss       r   _EuclideanNormGradr+   -   s     ::a=&	[	!%33		!%ryy|5v'=>FT#9:D			"))A,	6	<<r   c                 V   ~t        j                  |       }t        j                  |      }t        j                         sXt	        | t
        j                        r>t	        |t
        j                        r$t        | j                  |j                        \  }}nd\  }}||t        j                  ||      \  }}d}d}nb|xs- | j                  j                  |j                  j                  k  }|xs- |j                  j                  | j                  j                  k  }|||f|||ffS )a  Version of `BroadcastGradientArgs` optimized for partially-known shapes.

  Args:
    x: The first argument of a broadcasting binary op.
    y: The second argument of a broadcasting binary op.
    grad: Deprecated.

  Returns:
    A pair of triples, one per argument with
      * Shape of the argument (tensor);
      * Reduction axes for the argument (list or tensor);
      * Boolean indicating whether the reduction must be applied.
  NNT)r   r%   r   executing_eagerly
isinstancer	   Tensor_InferGradientReductionAxesr   broadcast_gradient_argsrank)	xyr   x_shapey_shapex_axesy_axesx_must_reducey_must_reduces	            r   SmartBroadcastGradientArgsr<   <   s     OOA'OOA'

#
#
%FMM"FMM"0!''BNFFNFF^v~"::7GLNFFMM9aggllQWW\\9M9aggllQWW\\9M
6=	)GV]+K	KKr   c                    | j                   }|j                   }||y| j                         } |j                         }t        ||      }g }g }t        |      D ]j  }|||z
  k  rdn
| |||z
  z
     }|||z
  k  rdn
||||z
  z
     }	|dk(  r|	dk7  r|j	                  |       I|	dk(  r|dk7  r|j	                  |       e||	j y ||fS )z9Infers the sets of axes that might have been broadcasted.r-   r!   )r3   as_listmaxrangeappend)
r6   r7   x_ranky_rankb_rankr8   r9   axisx_dimy_dims
             r   r1   r1   a   s    <<&<<&^v~ OO'OO'vv&&&Fm d'AWTVf_5M-NE'AWTVf_5M-NEzeqjmmD	!
mmD	%- 
r   c                 v    |\  }}}| 0|r.t        j                  | |d      } t        j                  | |      } | S )zFReduces gradients of one of the arguments of a broadcasting binary op.T)keepdims)r   
reduce_sumr   r'   )r   shape_axes_must_reducer%   axesmust_reduces        r   _ReduceGradientArgrN      sC    3%{	+ tTD9DT5)D	+r   c                 `    ||'t        | |      \  }}t        ||      }t        ||      }||fS )z@Reduces gradients of both arguments of a broadcasting binary op.)r<   rN   )r4   r5   gxgybxbys         r   _ReduceGradientArgsrT      s<    ^r~'1-FB	B	#B	B	#B	R-r   r   c                 .    | j                         t        u S r   )_shape_tuple_EMPTY_TUPLE)r4   s    r   	_IsScalarrX      s    	
	\	))r   c                 4    | t        j                  |d      z  S )z;Divides `x / y` assuming `x, y >= 0`, treating `0 / 0 = 0`.r!   )r   maximum)r4   r5   s     r   _SafeShapeDivr[      s    	
hq!$	$$r   Sumc                 2   | j                   d   j                         }|t        j                  | j                   d         }|t	        |      }t        j                  |t        j                  |            rt        j                         rt        j                         }|j                         j                  |      }|Pt        j                  dg|z  t        j                        }|j                         j!                  ||       ndg|z  }t#        j$                  ||      }d|vr&t        j                  |t        j                        }n"t#        j&                  | j                   d         }t#        j(                  ||      dgS d|vrt        j                         sqt+        j,                         }t/        |j%                  d            }	 |j0                  ||f   \  }	}
t#        j$                  ||	      }t#        j(                  ||
      dgS t#        j&                  | j                   d         }| j;                  d      sWt+        j<                  |      5  t5        j6                  || j                   d         }	ddd       t#        j$                  |	      }t#        j>                  ||      dgS # t2        $ rH d } |t5        j6                  ||            }	 |t9        ||	            }
|	|
f|j0                  ||f<   Y  w xY w# 1 sw Y   xY w)zGradient for Sum.r   Nr!   dtypec                 x    t        j                  |       rt        j                  |       }|J | }t        |      S r   )r
   
is_tf_typetry_evaluate_constanttuple)tvalues     r   EvaluateAsTuplez!_SumGrad.<locals>.EvaluateAsTuple   s;    %%a(!77:e&&&e<r   r    ) r&   rV   r
   constant_valuelennparray_equalaranger   r.   ones_rank_cachegetr   constantr   int32putr   r'   r%   tiler   get_default_graphrd   _reduced_shape_cacheKeyErrorr   r$   r[   r#   colocate_withbroadcast_to)r   r   input_0_shaperL   r3   ctx	new_shapeinput_shapegraphr*   tile_scalingrg   s               r   _SumGradr~      s   
 ))A,++--%%biil3Dd	biio	.$$&!#))+//5)#,,aS4Zv||LI!%%dI6cDj)  y1}$#,,]&,,O+!		!5+t[1488}$W-F-F-H %%' T\\"%&	4161K1Kd#2%
.
 ,(   '=>t\2D99		!-+	[	!			;	' D  (55k68iil DD
 T#9:D

 
 {
3T	::=  	4  $3$$]D9$;
 (M+ABD, %l?4%
$
$mT%:
;	40D Ds   J9 $L9AL
	L
Lc                 v   t        j                  | j                  d         }| j                  d   }| j	                  d      sPt        j                  || j                  d         }t        j                  ||      }t        j                  ||      }nt        j                  |      }t        j                  t        j                  || j                  d         |j                        }t        j                  t        j                  || j                  d         |      }t        j                  ||      |z  dgS )z@Gradient for Min or Max. Amazingly it's precisely the same code.r   r    r!   N)r   r%   r&   r"   r#   r   r$   r'   castequalr_   rJ   divide)r   r   r{   r5   r*   
indicatorsnum_selecteds          r   _MinOrMaxGradr      s    		!-+jjm!	[	!%33K1N!34AT#9:D&__Q/
 }}X^^Aryy|<djjI*""*biil35KM, //*l
3d
:D	AAr   Maxc                     t        | |      S )zGradient for Max.r   r   s     r   _MaxGradr      s     
r4	  r   Minc                     t        | |      S r   r   r   s     r   _MinGradr     s    	r4	  r   Meanc                    t        | |      d   }| j                  d   j                         }| j                  d   j                         }|e|cd|vr_d|vr[t	        j
                  |      }t	        j
                  |      }|t        |d      z  }t        j                  ||j                        }nt        j                  | j                  d         }t        j                  |      }t        j                  | j                  d   |j                        }	|	|z   |z  }	t        j                  t        j                   ||	            }t        j"                  |t        j                  ||j                              dfS )zGradient for Mean.r   Nr!   r^   )r~   r&   rV   r"   rj   prodr?   r   ro   r_   r   r%   sizer   r   reduce_prodgatherr(   )
r   r   sum_gradr{   output_shape
input_sizeoutput_sizefactor
input_rankrL   s
             r   	_MeanGradr     s3    b$"(		!))++A++-,,":
+$l":%J'','K3{A..F!!&?F//"))A,/K,J==1z'7'78D:+D!!)"2"2;"EFF			(HMM&(..$I	JD	PPr   Prodc                    t        j                  | j                  d         }t        j                  | j                  d   dg      }| j	                  d      s9t        j                  || j                  d         }t        j                  ||      }t        j                  ||      }t        j                  d      5  t        j                  | j                  d         }t        j                  ||j                        }||z   |z  }t        j                  d|      }t        j                  |||j                        \  }}	t        j                   ||gd      }
t        j"                  t        j$                  ||            }t        j"                  t        j$                  ||            }ddd       t        j&                  | j                  d   
      }t        j                  |      }t        j                  |f      }t        j(                  |dd      }t        j(                  |ddd	      }t        j                  t        j*                  |      t        j*                  |      z  |      }|t        j&                  |t        j,                  |
            z  }t        j                  ||      dfS # 1 sw Y   xY w)
zGradient for Prod.r   r!   r`   r    z/cpu:0NT)rE   	exclusive)rE   r   reverse)r   r%   r&   r'   r#   r   r$   rw   r   devicer3   r   r_   r@   r   	list_diffconcatr   r   	transposecumprodconjinvert_permutation)r   r   r{   reduction_indicesr*   r3   reducedidxother_permreduced_num	other_numpermutedpermuted_shapereshapedleftrightr5   outs                       r   	_ProdGradr     s:    		!-+''		!rd; 
[	!%33K1NT#9:D			k	2$ zz( K>>"))A,'D &7D 4'4/G
..D
!C&&sGW]]CHE1We,a0D&&y'7'7W'MNK$$Y%5%5k5%IJIK   1t4(??8,.x+y)AB( 
		(d	;$


8!tT
J%mmDHMM%00.B!
 	y""1i&B&B4&HII#			3	,d	22/K Ks   <C/J77K
SegmentSumc                 L    t        j                  || j                  d         dfS )zGradient for SegmentSum.r!   N)r   r   r&   r   s     r   _SegmentSumGradr   N  s$     
		$		!	-t	33r   SegmentMeanc                 $   t        j                  | j                  d         }t        j                  | j                  d         }t        j                  t        j
                  |dz
  d      |j                        }t        j                  ||gd      }t        j                  ||j                        }t        j                  |t        j                  || j                  d               }t        j                  || j                  d         dfS )zGradient for SegmentMean.r   r!   r^   N)r   r3   r&   r%   onesexpand_dimsr_   r   r   r   segment_sumr   )r   r   	data_ranksegment_ids_shaperemaining_shape
ones_shaper   scaled_grads           r   _SegmentMeanGradr   T  s     nnRYYq\*)oobiil3NNIM1-5F5L5L/ !2O DaH*	
$**	5$h&:&:41&NO+			+ryy|	4d	::r   c                 j   ||dk(  s|dk(  sJ | j                   d   }| j                   d   }t        j                  | j                   d         }|d   }|dk(  rt        j                  }n&|dk(  rt        j
                  }nt        j                  } |||||      \  }}	t        j                  ||	|      S )zCSparse gradient for SparseSegment(Sum|Mean|SqrtN)[WithNumSegments].meansqrtnr!      r   )	r&   r   r%   r   sparse_segment_mean_grad_v2sparse_segment_sqrt_n_grad_v2sparse_segment_sum_grad_v2indexed_slices_libIndexedSlices)
r   r   normindicessegment_ids
data_shapedense_output_dim0grad_fngrad_valuessorted_unique_indicess
             r   _SparseSegmentReduceGradV2r   b  s    	47?:	:IIaL'		!+ryy|,* m	V^22Gw44G11G'.
G["3($+$ 
	)	)(*
 r   c                 D    	 | j                  |      S # t        $ r Y yw xY w)zbReturns the value of the attr of `op` with the given `name`, or None if no

  such attr exists.
  N)r#   
ValueError)r   names     r   _GetOpAttrOrNoner   w  s(    
;;t	 s    	SparseSegmentSumc                    t        | d      rt        | |      ddfS t        j                  | j                  d         d   }t        j                  ddd      r5t        j                  || j                  d   | j                  d   |      ddfS t        j                  t        j                  || j                  d         | j                  d   |      ddfS )	zGradient for SparseSegmentSum.sparse_gradientNr        
   r!   r   r   r   r   r%   r&   r   forward_compatibler   sparse_segment_sum_gradunsorted_segment_sumr   r   r   dim0s      r   _SparseSegmentSumGradr     s     b+,%b$/t;;	1	&q	)$tQ+,,T299Q<1-1348$@ @ ))ryy|,biilDBCGO Or   SparseSegmentSumWithNumSegmentsc                    t        | d      rt        | |      dddfS t        j                  | j                  d         d   }t        j                  ddd      r6t        j                  || j                  d   | j                  d   |      dddfS t        j                  t        j                  || j                  d         | j                  d   |      dddfS )	z-Gradient for SparseSegmentSumWithNumSegments.r   Nr   r   r   r   r!   r   r   r   s      r   $_SparseSegmentSumWithNumSegmentsGradr     s     b+,%b$/tTAA	1	&q	)$tQ+,,T299Q<1-1348$F F ))ryy|,biilT4! !r   SparseSegmentMeanc                     t        | d      rt        | |d      ddfS t        j                  | j                  d         d   }t        j                  || j                  d   | j                  d   |      ddfS )zGradient for SparseSegmentMean.r   r   Nr   r!   r   r   r   r   r%   r&   r   sparse_segment_mean_gradr   s      r   _SparseSegmentMeanGradr     sv     b+,%b$7tCC	1	&q	)$

+
+D"))A,		!,0237
? ?r    SparseSegmentMeanWithNumSegmentsc                     t        | d      rt        | |d      dddfS t        j                  | j                  d         d   }t        j                  || j                  d   | j                  d   |      dddfS )z.Gradient for SparseSegmentMeanWithNumSegments.r   r   Nr   r!   r   r   r   s      r   %_SparseSegmentMeanWithNumSegmentsGradr     s|     b+,%b$7tTII	1	&q	)$

+
+D"))A,		!,0237t
E Er   SparseSegmentSqrtNc                     t        | d      rt        | |d      ddfS t        j                  | j                  d         d   }t        j                  || j                  d   | j                  d   |      ddfS )z Gradient for SparseSegmentSqrtN.r   r   Nr   r!   r   r   r   r   r%   r&   r   sparse_segment_sqrt_n_gradr   s      r   _SparseSegmentSqrtNGradr     sx     b+,%b$8$DD	1	&q	)$

-
-dBIIaL"))A,.24594
A Ar   !SparseSegmentSqrtNWithNumSegmentsc                     t        | d      rt        | |d      dddfS t        j                  | j                  d         d   }t        j                  || j                  d   | j                  d   |      dddfS )z/Gradient for SparseSegmentSqrtNWithNumSegments.r   r   Nr   r!   r   r   r   s      r   &_SparseSegmentSqrtNWithNumSegmentsGradr     s|     b+,%b$8$dJJ	1	&q	)$

-
-dBIIaL"))A,.24594
G Gr   c                 D   t        j                  | j                  d   | j                  d   j                        }t        j                  | j
                  d   | j                  d         }t        j                  | j                  d   |      }t        j                  t        j                  ||j                        | j                  d         }t        j                  ||      }t        j                  || j                  d         }t        j                  |||      dfS )z) Gradient for SegmentMin and SegmentMax. r   r^   r!   N)r   
zeros_liker&   r_   r   r"   r   r   r   r   r   where_v2)r   r   zerosgathered_outputsis_selectedr   weighted_gradsgathered_gradss           r   _SegmentMinOrMaxGradr     s    


ryy|299Q<3E3E
F%%%bjjmRYYq\Bryy|-=>+%%mmK,biil<, ??46.##NBIIaLA.			K	?	EEr   
SegmentMinc                     t        | |      S )zGradient for SegmentMin.r   r   s     r   _SegmentMinGradr         
b$	''r   
SegmentMaxc                     t        | |      S )zGradient for SegmentMax.r  r   s     r   _SegmentMaxGradr    r  r   SegmentProdc                    | j                   d   }| j                   d   }t        j                  |d      }t        j                  t        j
                  |t        j                        |      }t        j                  t        j                  |d      t        j                  |      |      }t        j                  |t        j                  |      |      }t        j                  ||      }t        j                  | j                  d   |      }t        j                  ||      }	||z  }
t        j                  ||	|
      }t        j                  ||      }||z  dfS )a  Gradient for SegmentProd.

  The gradient can be expressed for each segment by dividing the segment's
  product by each element of the segment input tensor, but this approach can't
  deal with zeros in the input.
  Unlike reduce_prod we can't use cumsum here as individual segments may have
  a different number of elements. Therefore we consider three cases:
  1) A segment input contains no zeros and we can safely divide by the input
     tensor.
  2) A segment contains exactly one zero. Then the gradient of each input of
     the segment is zero except for the 0-input, there the gradient is
     the product of the remaining segment entries.
  3) A segment contains at least two zeros. The gradient is zero for all
     segment inputs.
  r   r!   r^   N)r&   r   r   r   r   r   r   rp   r   r   greaterr   	ones_likesegment_prodr   r"   )r   r   datar   is_zero	num_zerosnon_zero_datanon_zero_prodgathered_prodgathered_non_zero_prodprod_divided_by_elpartial_derivativegathered_grads                r   _SegmentProdGradr    s-   " 
1$		!+NN4#'&&mmG6<<0+?) 
		y!$i&:&:4&@$
H$ $$Wi.A.A$.GN-++M;G-""2::a=+>-$++M;G$}4 !))'3I*<>""45-	+	+T	11r   c           	      |   |)t        j                  |t        j                  |            }t        j                  | |      }|t        j
                  |d      }t        j                  |      }t        j                  |t        j                  t        j                  |      t        j                  |      z
  g|j                        gd      }t        j                  ||      }|t        j                  |t        j                        z  }t        j                  |      }t        j                  |||      ||fS )an   Helper function for unsorted segment ops.

  Gathers params for
      positive segment ids and gathers 0 for inputs with negative segment id.
      Also returns the clipped indices and a boolean mask with the same shape
      as ids where a positive id is masked as true. With this, the latter two
      can be passed as arguments to this function to reuse them.
  r   r^   )rE   )r   rZ   r   r   r   greater_equalr%   r   r   r3   r_   r'   r  r   boolr   )paramsidszero_clipped_indicesis_positivegatheredis_positive_shapebroadcastable_shape
zero_slices           r   _GatherDropNegativesr$    s    !#++C1E1Ec1JKf&:;(((a0K "4#**NN)INN;,GGH'--	
 	 ##K1DEK	 3 3HFKK PPK##H-*h
;
 r   c                    t        | j                  d   | j                  d         \  }}}t        j                  | j                  d   |      }t        j
                  ||      }t        j                  t        j                  ||j                        | j                  d   | j                  d         }t        j                  ||      }t        |d||      \  }}	}	t        j                  |      }
t        j                  |||
      ddfS )z7Gradient for UnsortedSegmentMin and UnsortedSegmentMax.r   r!   r   N)r$  r"   r&   r   r   logical_andr   r   r_   r   r   r   r   )r   r   r   r  r  r   r   r   r   r   r   s              r   _UnsortedSegmentMinOrMaxGradr'  4  s     9MjjmRYYq\95(+ ryy|-=>+$$[+>+..mmK,biilBIIaL,
 ??46.-d0+.!Q 

~
.%			K	?t	KKr   UnsortedSegmentSumc                 @    t        || j                  d         d   ddfS )z Gradient for UnsortedSegmentSum.r!   r   N)r$  r&   r   s     r   _UnsortedSegmentSumGradr*  I  s%     
dBIIaL	1!	4dD	@@r   UnsortedSegmentMaxc                     t        | |      S )z" Gradient for UnsortedSegmentMax. r'  r   s     r   _UnsortedSegmentMaxGradr.  O       
&b$	//r   UnsortedSegmentMinc                     t        | |      S )z" Gradient for UnsortedSegmentMin. r-  r   s     r   _UnsortedSegmentMinGradr2  U  r/  r   UnsortedSegmentProdc                    t        j                  | j                  d   d      }t        j                  t        j
                  |t        j                        | j                  d   | j                  d         }t        j                  t        j                  |d      t        j                  |      |      }t        j                  |t        j                  | j                  d         | j                  d         }t        j                  || j                  d   | j                  d         }t        j                  | j                  d   t        j                  | j                  d               }t        j                  | j                   d   |      }t        j                  ||      }|| j                  d   z  }	t        j                  |||	      }
t#        || j                  d   |      d   }||
z  ddfS )a   Gradient for UnsortedSegmentProd.

  The gradient can be expressed for each segment by dividing the segment's
  product by each element of the segment input tensor, but this approach can't
  deal with zeros in the input.
  Unlike reduce_prod we can't use cumsum here as individual segments may have
  a different number of elements. Therefore we consider three cases:
  1) A segment input contains no zeros and we can safely divide by the input
     tensor.
  2) A segment contains exactly one zero. Then the gradient of each input of
     the segment is zero except for the 0-input, there the gradient is
     the product of the remaining segment entries.
  3) A segment contains at least two zeros. The gradient is zero for all
     segment inputs.
  r   r^   r!   r   N)r   r   r&   r   r   r   r   rp   r   r   r  r   r  unsorted_segment_prodrZ   r   r"   r$  )r   r   r  r  r  r  r  r  r  r  r  r  s               r   _UnsortedSegmentProdGradr6  [  s   & NN299Q<+'//mmG6<<0"))A,		!N) 
		y!$i&:&:4&@$
H$ $$Wi.A.A"))A,.O%'YYq\3-44]57YYq\299Q<Q- "))"))A,*3*>*>ryy|*LN""2::a=2FG-$++M;OP$ryy|3
 !))'3I*<>&tRYYq\';==>@-	+	+T4	77r   Absc                 P    | j                   d   }|t        j                  |      z  S Nr   )r&   r   signr   r   r4   s      r   _AbsGradr<    s#    iil!	a 	  r   Negc                     | S )zReturns -grad.r   r   r   s     r   _NegGradr@    s     ,r   Invc                 L    | j                   d   }t        j                  ||      S zReturns -grad * (1 / x^2).r   r"   r   reciprocal_gradr   r   r5   s      r   _InvGradrG    $     	jjm!		%	%a	..r   
Reciprocalc                 L    | j                   d   }t        j                  ||      S rC  rD  rF  s      r   _ReciprocalGradrK    rH  r   InvGradc                 (   | j                   d   }t        j                  |g      5  t        j                  | j                   d         }t        j                  |      }|dz  |z  |z  t        j                  ||      fcd d d        S # 1 sw Y   y xY wNr!   r          r&   r   control_dependenciesr   r   r   rE  r   r   bcacgs        r   _InvGradGradrV    ~    iil!
' F	ryy|	$B	t	B9q=2|;;BEEF F F   ABBReciprocalGradc                 (   | j                   d   }t        j                  |g      5  t        j                  | j                   d         }t        j                  |      }|dz  |z  |z  t        j                  ||      fcd d d        S # 1 sw Y   y xY wrN  rP  rR  s        r   _ReciprocalGradGradr[    rW  rX  Squarec                 8   | j                   d   }t        j                  |g      5  t        j                  |      }t        j                  d|j                        }t        j                  |t        j                  ||            cd d d        S # 1 sw Y   y xY w)Nr          @r^   )	r&   r   rQ  r   r   r   ro   r_   multiplyr   r   r4   r5   s       r   _SquareGradra    su    iil!
' <aAS0AT8#4#4Q#:;< < <s   A BBSqrtc                 L    | j                   d   }t        j                  ||      S r9  )r"   r   	sqrt_gradrF  s      r   	_SqrtGradre    s"    jjm!			4	((r   SqrtGradc                     | j                   d   }| j                  d   }t        j                  |g      5  ||z  }t	        j
                  |       |z  d|z  fcd d d        S # 1 sw Y   y xY w)Nr         ?)r&   r"   r   rQ  r   r   )r   r   ar5   gas        r   _SqrtGradGradrk    sg    iil!jjm!
' ,	BMM"!38+, , ,s   #A""A+Rsqrtc                 L    | j                   d   }t        j                  ||      S )z Returns -0.5 * grad * conj(y)^3.r   )r"   r   
rsqrt_gradrF  s      r   
_RsqrtGradro    s$     	jjm!		 	 D	))r   	RsqrtGradc                 Z   | j                   d   }| j                   d   }t        j                  |g      5  t        j                  |      }t        j                  |      }d|z  |z  t        j
                  |      z  }t        j                  ||      }||fcddd       S # 1 sw Y   yxY w)z<Returns backprop gradient for f(a,b) = -0.5 * b * conj(a)^3.r   r!   g      N)r&   r   rQ  r   r   squarer   rn  )r   r   ri  rS  rT  rU  grad_agrad_bs           r   _RsqrtGradGradru    s     	iil!iil!
' 	q	B	t	BBY]X__R00F$$R.F6>  s   A"B!!B*Expc                     | j                   d   }t        j                  |g      5  t        j                  |      }||z  cddd       S # 1 sw Y   yxY wzReturns grad * exp(x).r   N)r"   r   rQ  r   r   rF  s      r   _ExpGradry    sK     	jjm!
' aA!8     A

AExpm1c                     | j                   d   }t        j                  |g      5  t        j                  |      }t        j
                  |      }||z  cddd       S # 1 sw Y   yxY wrx  )r&   r   rQ  r   r   expr`  s       r   
_Expm1Gradr~    sX     	iil!
' aAQA!8  s   /AA(Logc                     | j                   d   }t        j                  |g      5  t        j                  |      }|t        j
                  |      z  cddd       S # 1 sw Y   yxY w)zReturns grad * (1/x).r   Nr&   r   rQ  r   r   
reciprocalr;  s      r   _LogGradr    sW     	iil!
' )aA(%%a(() ) )   -AA&Log1pc                     | j                   d   }t        j                  |g      5  t        j                  |      }|t        j
                  d|z         z  cddd       S # 1 sw Y   yxY w)zReturns grad * (1/(1 + x)).r   r!   Nr  r;  s      r   
_Log1pGradr    s[     	iil!
' -aA(%%a!e,,- - -s   0A  A)Xlogyc           
         | j                   d   }| j                   d   }t        j                  |      }t        j                  |      }t        j                  ||      \  }}t        j                  |g      5  t        j                  t        j                  |t        j                  d|j                              |j                        }t        j                  ||      }	t        j                  ||      }
t        j                  t        j                  |	|z  |      |      t        j                  t        j                  |
|z  |      |      fcddd       S # 1 sw Y   yxY w)z8Returns gradient of xlogy(x, y) with respect to x and y.r   r!           r^   N)r&   r   r%   r   r2   r   rQ  r   r   	not_equalr_   r   xlogyxdivyr'   rJ   r   r   r4   r5   sxsyrxry
not_zero_x	partial_x	partial_ys              r   
_XLogyGradr    s    	iil!iil!q"q"00R8&"b
' N1hmmBagg>?qwwPJ"":q1I""1a(Ih11)d2BBGLh11)d2BBGLNN N Ns   8CEE%Xlog1pyc           
         | j                   d   }| j                   d   }t        j                  |      }t        j                  |      }t        j                  ||      \  }}t        j                  |g      5  t        j                  t        j                  |t        j                  d|j                              |j                        }t        j                  ||      }	t        j                  ||dz         }
t        j                  t        j                  |	|z  |      |      t        j                  t        j                  |
|z  |      |      fcddd       S # 1 sw Y   yxY w)z:Returns gradient of xlog1py(x, y) with respect to x and y.r   r!   r  r^         ?N)r&   r   r%   r   r2   r   rQ  r   r   r  r_   r   xlog1pyr  r'   rJ   r  s              r   _XLog1pyGradr    s    	iil!iil!q"q"00R8&"b
' N1hmmBagg>?qwwPJ$$Z3I""1a"f-Ih11)d2BBGLh11)d2BBGLNN N Ns   8CEE(Xdivyc           
         | j                   d   }| j                   d   }t        j                  |      }t        j                  |      }t        j                  ||      \  }}t        j                  |g      5  t        j                  t        j                  |t        j                  d|j                              |j                        }t        j                  ||      }	t        j                  t        j                  |      |dz        }
t        j                  t        j                  |	|z  |      |      t        j                  t        j                  |
|z  |      |      fcddd       S # 1 sw Y   yxY w)z8Returns gradient of xdivy(x, y) with respect to x and y.r   r!   r  r^   r   N)r&   r   r%   r   r2   r   rQ  r   r   r  r_   r   r  negativer'   rJ   r  s              r   
_XDivyGradr  -  s*    	iil!iil!q"q"00R8&"b
' N1hmmBagg>?qwwPJ"":q1I""8#4#4Q#7A>Ih11)d2BBGLh11)d2BBGLNN N Ns   8C0E22E;Sinhc                     | j                   d   }t        j                  |g      5  t        j                  |      }|t        j
                  |      z  cddd       S # 1 sw Y   yxY w)zReturns grad * cosh(x).r   N)r&   r   rQ  r   r   coshr;  s      r   	_SinhGradr  >  U     	iil!
' #aA(--""# # #r  Coshc                     | j                   d   }t        j                  |g      5  t        j                  |      }|t        j
                  |      z  cddd       S # 1 sw Y   yxY w)zReturns grad * sinh(x).r   N)r&   r   rQ  r   r   sinhr;  s      r   	_CoshGradr  G  r  r  Tanhc                     | j                   d   }t        j                  |g      5  t        j                  |      }t        j                  ||      cddd       S # 1 sw Y   yxY w)z'Returns grad * (1 - tanh(x) * tanh(x)).r   N)r"   r   rQ  r   r   r   	tanh_gradrF  s      r   	_TanhGradr  P  sT     	jjm!
' +aA!!!T*+ + +   +AA$Asinhc                     | j                   d   }t        j                  |g      5  t        j                  |      }|t        j
                  |      z  cddd       S # 1 sw Y   yxY w)zReturns grad * 1/cosh(y).r   N)r"   r   rQ  r   r   r  rF  s      r   
_AsinhGradr  Y  U     	jjm!
' #aA(--""# # #r  Acoshc                     | j                   d   }t        j                  |g      5  t        j                  |      }|t        j
                  |      z  cddd       S # 1 sw Y   yxY w)zReturns grad * 1/sinh(y).r   N)r"   r   rQ  r   r   r  rF  s      r   
_AcoshGradr  b  r  r  Atanhc                 j   | j                   d   }t        j                  |g      5  t        j                  |      }t        j
                  |      }t        j                  d|j                        }t        j                  t        j                  ||            }||z  cddd       S # 1 sw Y   yxY w)zReturns grad * 1/ (1 - x^2).r   r!   r^   N)r&   r   rQ  r   r   rr  r   ro   r_   r  subtractr   r   r4   x2oneinvs         r   
_AtanhGradr  k  s     	iil!
' aA		B


q


3C


h//R8
9C#:     A9B))B2TanhGradc                 $   t        j                  |g      5  t        j                  | j                  d         }t        j                  | j                  d         }|dz  |z  |z  t        j                  ||      fcd d d        S # 1 sw Y   y xY w)Nr   r!   rO  )r   rQ  r   r   r&   r   r  )r   r   ri  rS  s       r   _TanhGradGradr  w  sy    
' @biil#Abiil#A$;?Q 6 6q$ ??@ @ @s   A%BBErfc                    | j                   d   }t        j                  dt        j                  t        j
                        z  |j                        }t        j                  |g      5  t        j                  |      }||z  t        j                  t        j                  |             z  cddd       S # 1 sw Y   yxY w)z'Returns grad * 2/sqrt(pi) * exp(-x**2).r   r   r^   Nr&   r   ro   rj   sqrtpir_   r   rQ  r   r   r}  rr  )r   r   r4   two_over_root_pis       r   _ErfGradr    s     	iil! ))!bggbeen*<DJJO
' GaA""X\\8??13E2E%FFG G G   +AB99CErfcc                    | j                   d   }t        j                  dt        j                  t        j
                        z  |j                        }t        j                  |g      5  t        j                  |      }||z  t        j                  t        j                  |             z  cddd       S # 1 sw Y   yxY w)z(Returns -grad * 2/sqrt(pi) * exp(-x**2).r   r^   Nr  )r   r   r4   minus_two_over_root_pis       r   	_ErfcGradr    s     	iil!&//277255>-
' MaA((8<<9K8K+LLM M Mr  Erfinvc                 Z   t        j                  t        j                  t        j                        dz  |j
                        }t        j                  |g      5  ||z  t        j                  t        j                  | j                  d               z  cddd       S # 1 sw Y   yxY w)z0Returns grad * sqrt(pi) / 2 * exp(erfinv(x)**2).r   r^   r   Nr   ro   rj   r  r  r_   r   rQ  r   r}  rr  r"   )r   r   root_pi_over_twos      r   _ErfinvGradr    s~     !))"''"%%.1*<DJJO
' (""X\\

1&&( (( ( (s   ;B!!B*Ndtric                 `   t        j                  t        j                  dt        j                  z        |j
                        }t        j                  |g      5  ||z  t        j                  t        j                  | j                  d         dz        z  cddd       S # 1 sw Y   yxY w)z3Returns grad * sqrt(2 * pi) * exp(ndtri(x)**2 / 2).r   r^   r   r^  Nr  )r   r   root_two_pis      r   
_NdtriGradr    s     $$RWWQY%7tzzJ+
' -+

1&+!- -- - -s   >B$$B-Lgammac                     | j                   d   }t        j                  |g      5  t        j                  |      }|t        j
                  |      z  cddd       S # 1 sw Y   yxY w)zReturns grad * digamma(x).r   N)r&   r   rQ  r   r   digammar;  s      r   _LgammaGradr    sW     	iil!
' &aA(""1%%& & &r  Digammac                    | j                   d   }t        j                  |g      5  t        j                  |      }t        j
                  t        j                  d|j                        |      }||z  cddd       S # 1 sw Y   yxY w)zFCompute gradient of the digamma function with respect to its argument.r   r!   r^   N)	r&   r   rQ  r   r   	polygammar   ro   r_   r   r   r4   r  s       r   _DigammaGradr    so     	iil!
' aA""9#5#5aqww#GKI)  s   AA??BDawsnc                     | j                   d   }| j                  d   }t        j                  |g      5  |dd|z  |z  z
  z  cddd       S # 1 sw Y   yxY w)z:Compute gradient of dawsn(x) with respect to its argument.r   r  r   N)r&   r"   r   rQ  r`  s       r   
_DawsnGradr    sW     	iil!jjm!
' #2A	>"# # #s   AAExpintc                     | j                   d   }t        j                  |g      5  |t        j                  |      z  |z  cddd       S # 1 sw Y   yxY w)z;Compute gradient of expint(x) with respect to its argument.r   N)r&   r   rQ  r   r}  r;  s      r   _ExpintGradr    sK     	iil!
' &(,,q/!A%& & &   AA
FresnelCosc                     | j                   d   }t        j                  |g      5  |t        j                  t
        j                  dz  t        j                  |      z        z  cddd       S # 1 sw Y   yxY w)z@Compute gradient of fresnel_cos(x) with respect to its argument.r   r^  N)r&   r   rQ  r   cosrj   r  rr  r;  s      r   _FresnelCosGradr    a     	iil!
' C(,,xq/AABBC C C   ?A//A8
FresnelSinc                     | j                   d   }t        j                  |g      5  |t        j                  t
        j                  dz  t        j                  |      z        z  cddd       S # 1 sw Y   yxY w)z@Compute gradient of fresnel_sin(x) with respect to its argument.r   r^  N)r&   r   rQ  r   sinrj   r  rr  r;  s      r   _FresnelSinGradr    r  r  Spencec                 6   | j                   d   }t        j                  |g      5  t        j                  |      d|z
  z  }t        j                  t        j                  |d      t        j                  |       |      }||z  cddd       S # 1 sw Y   yxY w)z;Compute gradient of spence(x) with respect to its argument.r   r!   r  N)	r&   r   rQ  r   logr   wherer   r  r  s       r   _SpenceGradr    s     	iil!
' Q1q5)Iq"	 3 3A 66	CI)	  s   ABBBesselI0c                     | j                   d   }t        j                  |g      5  t        j                  |      }||z  cddd       S # 1 sw Y   yxY w)z>Compute gradient of bessel_i0(x) with respect to its argument.r   N)r&   r   rQ  r   	bessel_i1r  s       r   _BesselI0Gradr    sN     	iil!
'  **1-I)  rz  	BesselI0ec                     | j                   d   }| j                  d   }t        j                  |g      5  t	        j
                  |      t        j                  |      |z  z
  }||z  cddd       S # 1 sw Y   yxY w)z?Compute gradient of bessel_i0e(x) with respect to its argument.r   N)r&   r"   r   rQ  r   
bessel_i1er   r:  r   r   r4   r5   r  s        r   _BesselI0eGradr    sn     	iil!jjm!
' !,,Q/(--2BQ2FFI)  s   3A22A;BesselI1c           
         | j                   d   }| j                  d   }t        j                  |g      5  t	        j
                  t        j                  |d      t        j                  d|j                        t        j                  |      t        j                  ||      z
        }||z  cddd       S # 1 sw Y   yxY w)z>Compute gradient of bessel_i1(x) with respect to its argument.r   r  r  N)r&   r"   r   rQ  r   r   r   r   r   r_   r   	bessel_i0divr   r   r4   r5   dy_dxs        r   _BesselI1Gradr    s     	iil!jjm!
' 	 q"x}}R9""1%Q(::<E %<	 	 	   A8B77C 	BesselI1ec                    | j                   d   }| j                  d   }t        j                  |g      5  t	        j
                  t        j                  |d      t        j                  d|j                        t        j                  |      |t        j                  |      t        j                  |      z   z  z
        }||z  cddd       S # 1 sw Y   yxY w)z?Compute gradient of bessel_i1e(x) with respect to its argument.r   r  rh  N)r&   r"   r   rQ  r   r   r   r   r   r_   r   
bessel_i0er:  r  r  s        r   _BesselI1eGradr
  	  s     	iil!jjm!
' 
 q"x}}S!'':##A&	q	H//2	2*4 	45E %<
 
 
s   BCCBesselK0c                     | j                   d   }t        j                  |g      5  t        j                  |       }||z  cddd       S # 1 sw Y   yxY w)z>Compute gradient of bessel_k0(x) with respect to its argument.r   N)r&   r   rQ  r   	bessel_k1r  s       r   _BesselK0Gradr    Q     	iil!
' !++A..I)  r  	BesselK0ec                     | j                   d   }| j                  d   }t        j                  |g      5  |t	        j
                  |      z
  }||z  cddd       S # 1 sw Y   yxY w)z?Compute gradient of bessel_k0e(x) with respect to its argument.r   N)r&   r"   r   rQ  r   
bessel_k1er  s        r   _BesselK0eGradr  $  sa     	iil!jjm!
' %0033I)  s   AA%BesselK1c                     | j                   d   }| j                  d   }t        j                  |g      5  t	        j
                  |       t        j                  ||      z
  }||z  cddd       S # 1 sw Y   yxY w)z>Compute gradient of bessel_k1(x) with respect to its argument.r   N)r&   r"   r   rQ  r   	bessel_k0r   r  r  s        r   _BesselK1Gradr  .  sp     	iil!jjm!
'  "++A..a1CCI)	  s   2A11A:	BesselK1ec                    | j                   d   }| j                  d   }t        j                  |g      5  |dt	        j
                  |      z
  z  t        j                  |      z
  }||z  cddd       S # 1 sw Y   yxY w)z?Compute gradient of bessel_k1e(x) with respect to its argument.r   r  N)r&   r"   r   rQ  r   r  r   
bessel_k0er  s        r   _BesselK1eGradr  :  s{     	iil!jjm!
'  	
R(%%a((),<,G,G,JJ )  s   6A55A>BesselJ0c                     | j                   d   }t        j                  |g      5  t        j                  |       }||z  cddd       S # 1 sw Y   yxY w)z>Compute gradient of bessel_j0(x) with respect to its argument.r   N)r&   r   rQ  r   	bessel_j1r  s       r   _BesselJ0Gradr  G  r  r  BesselJ1c           
         | j                   d   }| j                  d   }t        j                  |g      5  t	        j
                  t        j                  |d      t        j                  d|j                        t        j                  |      t        j                  ||      z
        }||z  cddd       S # 1 sw Y   yxY w)z>Compute gradient of bessel_j1(x) with respect to its argument.r   r  rh  N)r&   r"   r   rQ  r   r   r   r   r   r_   r   	bessel_j0r  r  s        r   _BesselJ1Gradr#  P  s     	iil!jjm!
' 	 q"x}}S!'':""1%Q(::<E %<	 	 	r  BesselY0c                     | j                   d   }t        j                  |g      5  t        j                  |       }||z  cddd       S # 1 sw Y   yxY w)z>Compute gradient of bessel_y0(x) with respect to its argument.r   N)r&   r   rQ  r   	bessel_y1r  s       r   _BesselY0Gradr'  a  r  r  BesselY1c                     | j                   d   }| j                  d   }t        j                  |g      5  t	        j
                  |      t        j                  ||      z
  }||z  cddd       S # 1 sw Y   yxY w)z>Compute gradient of bessel_y1(x) with respect to its argument.r   N)r&   r"   r   rQ  r   	bessel_y0r   r  r  s        r   _BesselY1Gradr+  j  sm     	iil!jjm!
'  !**1-Q0BBI)	  s   1A00A9Igammac                    | j                   d   }| j                   d   }t        j                  |      }t        j                  |      }t        j                  ||      \  }}t        j                  |g      5  t        j                  ||      }t        j                  | |dz
  t        j                  |      z  z   t        j                  |      z
        }	t        j                  t        j                  ||z  |      |      t        j                  t        j                  |	|z  |      |      fcddd       S # 1 sw Y   yxY w)z9Returns gradient of igamma(a, x) with respect to a and x.r   r!   N)r&   r   r%   r   r2   r   rQ  r   igamma_grad_ar   r}  r  lgammar'   rJ   )
r   r   ri  r4   sar  rar  	partial_ar  s
             r   _IgammaGradr3  v  s    	iil!iil!q"q"00R8&"b
' N**1a0I aR1q5HLLO";;%__Q/0 1Ih11)d2BBGLh11)d2BBGLNN N Ns   8B8D::EIgammacc                 ,    t        | |      \  }}| | fS )zDReturns gradient of igammac(a, x) = 1 - igamma(a, x) w.r.t. a and x.)r3  )r   r   r.  igamma_grad_xs       r   _IgammacGradr7    s$     "-R!6-.=.	))r   Betaincc                 $   | j                   \  }}}t        j                  |      }t        j                  |      }t        j                  ||      \  }}t        j                  |      t        j                  |      z   t        j                  ||z         z
  }	t        j                  t        j                  |dz
  |       t        j                  |dz
  |      z   |	z
        }
ddt        j                  t        j                  |
|z  |      |      fS )z7Returns gradient of betainc(a, b, x) with respect to x.r!   N)r&   r   r%   r   r2   r   r/  r   r}  r  r  r'   rJ   )r   r   ri  rS  r4   r0  r  r   r  log_betar  s              r   _BetaincGradr;    s     II'!Q q"q"

/
/B
7%!R
 !|22155!a% ! 
 ll8++AEA26#>>!a%346>? @) 
++I,<bA2F
H Hr   Zetac                    | j                   d   }| j                   d   }t        j                  |      }t        j                  |      }t        j                  ||      \  }}t        j                  |g      5  t        j                  |      }t        j                  |      }| t        j                  |dz   |      z  }dt        j                  t        j                  ||z  |      |      fcddd       S # 1 sw Y   yxY w)z7Returns gradient of zeta(x, q) with respect to x and q.r   r!   N)r&   r   r%   r   r2   r   rQ  r   r   zetar'   rJ   )	r   r   r4   qr  sq	unused_rxrq	partial_qs	            r   	_ZetaGradrD    s     	iil!iil!q"q"77B?-)R
' NaAaAX]]1q5!,,Ih11)d2BBGLN	N N Ns   8A6C88D	Polygammac                     | j                   d   }| j                   d   }t        j                  |      }t        j                  |      }t        j                  ||      \  }}t        j                  |g      5  t        j                  |      }t        j                  |      }t        j                  |dz   |      }dt        j                  t        j                  ||z  |      |      fcddd       S # 1 sw Y   yxY w)z6Returns gradient of psi(n, x) with respect to n and x.r   r!   N)r&   r   r%   r   r2   r   rQ  r   r   r  r'   rJ   )	r   r   nr4   snr  	unused_rnr  r  s	            r   _PolygammaGradrJ    s     	iil!iil!q"q"77B?-)R
' NaAaA""1q5!,Ih11)d2BBGLN	N N Ns   8A2C44C=Sigmoidc                     | j                   d   }t        j                  |g      5  t        j                  |      }t        j                  ||      cddd       S # 1 sw Y   yxY w)z-Returns grad * sigmoid(x) * (1 - sigmoid(x)).r   N)r"   r   rQ  r   r   r   sigmoid_gradrF  s      r   _SigmoidGradrN    sT     	jjm!
' .aA$$Q-. . .r  SigmoidGradc                 .   t        j                  |g      5  t        j                  | j                  d         }t        j                  | j                  d         }||z  }|d|z  |z  z
  t        j                  ||      fcd d d        S # 1 sw Y   y xY w)Nr   r!   r^  )r   rQ  r   r   r&   r   rM  )r   r   ri  rS  gbs        r   _SigmoidGradGradrR    s    
' Abiil#Abiil#A	Bb1l774@@	A A As   A*BBSignc                 J    | j                   d   }t        j                  |      S )z
Returns 0.r   )r&   r   r   )r   r   r4   s      r   	_SignGradrU    s"     	iil!			a	  r   Sinc                     | j                   d   }t        j                  |g      5  t        j                  |      }|t        j
                  |      z  cddd       S # 1 sw Y   yxY w)zReturns grad * cos(x).r   N)r&   r   rQ  r   r   r  r;  s      r   _SinGradrX    sT     	iil!
' "aA(,,q/!" " "r  Cosc                     | j                   d   }t        j                  |g      5  t        j                  |      }| t        j
                  |      z  cddd       S # 1 sw Y   yxY w)zReturns grad * -sin(x).r   N)r&   r   rQ  r   r   r  r;  s      r   _CosGradr[    sV     	iil!
' #aA58<<?"# # #s   .AA'Tanc                 &   | j                   d   }t        j                  |g      5  t        j                  |      }t        j
                  t        j                  |            }t        j                  |      }||z  cddd       S # 1 sw Y   yxY w)zReturns grad * 1/sec^2(x).r   N)r&   r   rQ  r   r   r  r  rr  )r   r   r4   secxsecx2s        r   _TanGradr`    sq     	iil!
' aAx||A/DOOD!E4<	  s   ABBAsinc                    | j                   d   }t        j                  |g      5  t        j                  |      }t        j
                  |      }t        j                  d|j                        }t        j                  t        j                  ||            }t        j                  |      }||z  cddd       S # 1 sw Y   yxY w)zReturns grad * 1/sqrt(1-x^2).r   r!   r^   Nr&   r   rQ  r   r   rr  r   ro   r_   r  r  r  r   r   r4   r  r  denr  s          r   	_AsinGradrf    s     	iil!
' aA		B


q


3C
--))#r2
3C


c
"C#:  s   BB>>CAcosc                    | j                   d   }t        j                  |g      5  t        j                  |      }t        j
                  |      }t        j                  d|j                        }t        j                  t        j                  ||            }t        j                  |      }| |z  cddd       S # 1 sw Y   yxY w)zReturns grad * -1/sqrt(1-x^2).r   r!   r^   Nrc  rd  s          r   	_AcosGradri    s     	iil!
' aA		B


q


3C
--))#r2
3C


c
"C53;  s   BB??CAtanc                 j   | j                   d   }t        j                  |g      5  t        j                  |      }t        j
                  |      }t        j                  d|j                        }t        j                  t        j                  ||            }||z  cddd       S # 1 sw Y   yxY w)zReturns grad * 1/ (1 + x^2).r   r!   r^   N)r&   r   rQ  r   r   rr  r   ro   r_   r  addr  s         r   	_AtanGradrm  "  s     	iil!
' aA		B


q


3C


hll33
4C#:  r  Atan2c                 $   | j                   d   }| j                   d   }t        j                  |g      5  |t        j                  |      t        j                  |      z   z  }||z  }| |z  }t        ||||      cddd       S # 1 sw Y   yxY w)z8Returns grad * x / (y^2 + x^2), grad * -y / (y^2 + x^2).r   r!   N)r&   r   rQ  r   rr  rT   )r   r   r5   r4   grad_invrQ   rP   s          r   
_Atan2Gradrq  .  s     	iil!iil!
' -xq)HOOA,>>?H	
XB
hBq!R,- - -s   ABBAddNc                 4    |gt        | j                        z  S )z"Copies the gradient to all inputs.)ri   r&   r   s     r   	_AddNGradrt  <  s     #bii.	  r   c                     | j                         }|j                         }|j                         }||k(  xr ||k(  xr
 |d uxr d |vS r   )rV   )r4   r5   r   r6   r7   
grad_shapes         r   _ShapesFullySpecifiedAndEqualrw  C  s[    NN'NN'  "*
W
 6J!6 6

6"&g"57r   AddAddV2c                 :   | j                   d   }	 | j                  xs d}d|v rt        |      r|dfS | j                   d   }t	        |t
        j                        rt        |||      r||fS d|v rdn|}d|v rdn|}t        ||||      S # t        $ r d}Y ew xY w)zGradient for Add.r!   r   Nr   	r&   skip_input_indicesrX   AttributeErrorr/   r	   r0   rw  rT   r   r   r5   r|  r4   rP   rQ   s          r   _AddGradr  M  s     	iil!..4"9Q<4Z
 	iil!fmm$)FD* :&&tD"&&tD"	Q2r	** 
 s   "B BBSubc                 >   | j                   d   }	 | j                  xs d}d|v rt        |      r|dfS | j                   d   }t	        |t
        j                        rt        |||      r|| fS d|v rdn|}d|v rdn| }t        ||||      S # t        $ r d}Y gw xY w)zGradient for Sub.r!   r   Nr   r{  r~  s          r   _SubGradr  e  s     	iil!..4"9Q<4Z
 	iil!fmm$)FD* $;&&tD"&&tTE"	Q2r	** 
 s   "B BBMulc                 h   | j                   d   }	 | j                  xs d}d|v r6t        |      r+t        j                  |t        j                  |            dfS | j                   d   }t        |t        j                        ret        |||      rX|j                  t        j                  t        j                  fv r,t        j                  ||      t        j                  ||      fS |j                  j                   |j                  j                   k(  sJ |j                  d|j                  f       d|v rd}n)t        j                  |t        j                  |            }d|v rd}n)t        j                  t        j                  |      |      }t#        ||||      S # t        $ r d}Y Uw xY w)z&The gradient of scalar multiplication.r!   r   Nr    vs. )r&   r|  rX   r   mulr   r   r}  r/   r	   r0   rw  r_   r   rp   float32
base_dtyperT   r~  s          r   _MulGradr  |  sn    	iil!..4"9Q<dHMM!$45t;;
 	iil!v}}%
'1d
3
**v~~6
6D!$l&6&6tQ&???	
		qww11	1NAGGWagg3NN	1
	B			$a 0	1B
	B			(--*D	1B	Q2r	**/ 
 s   A	F" "F10F1MulNoNanc                    | j                   d   }| j                   d   }t        |t        j                        r9t	        |||      r,t        j                  ||      t        j                  ||      fS |j                  j                  |j                  j                  k(  sJ |j                  d|j                  f       t        j                  ||      }t        j                  ||      }t        ||||      S )z;The gradient of scalar multiplication with NaN-suppression.r   r!   r  )
r&   r/   r	   r0   rw  r   
mul_no_nanr_   r  rT   r   r   r4   r5   rP   rQ   s         r   _MulNoNanGradr    s     	iil!iil!fmm$)FD* ""4+\-D-DQ-MMM	
		qww11	1NAGGWagg3NN	1tQ'"q$'"	Q2r	**r   Divc                 6   | j                   d   }| j                   d   }t        j                  |      }t        j                  |      }t        j                  ||      }|t        j                  t        j                  | |      |      z  }t	        ||||      S )z"The gradient for the Div operator.r   r!   )r&   r   r   r   rT   r   r   r4   r5   cxcyrP   rQ   s           r   _DivGradr    s}     	iil!iil!}}Q"}}Q"tR "hoohoorc26;;"	Q2r	**r   FloorDivc                      y)z'The gradient for the FloorDiv operator.r-   r   r   unused_grads     r   _FloorDivGradr    s     
r   FloorModc                    t        j                  | j                  d         }t        j                  | j                  d         }t        j                  ||      }|}|t        j                  |      z  }t        ||||      S )z Returns grad * (1, -floor(x/y)).r   r!   )r   r   r&   	floor_divr  rT   )r   r   r4   r5   floor_xyrP   rQ   s          r   _FloorModGradr    sm     mmBIIaL!!mmBIIaL!!1%("h))"	Q2r	**r   TruncateDivc                      y)Nr-   r   r  s     r   _TruncateDivGradr    s    	r   RealDivc                 j   | j                   d   }| j                   d   }t        j                  | j                   d         }t        j                  | j                   d         }t        j                  ||      }|t        j                  t        j                  | |      |      z  }t	        ||||      S )zRealDiv op gradient.r   r!   )r&   r   r   realdivrT   r  s           r   _RealDivGradr    s     	iil!iil!}}RYYq\""}}RYYq\""b!"hx//R8"=="	Q2r	**r   DivNoNanc                 .   t        j                  | j                  d         }t        j                  | j                  d         }t        j                  ||      }|t        j                  t        j                  | |      |      z  }t	        ||||      S )zDivNoNan op gradient.r   r!   )r   r   r&   
div_no_nanrT   r  s         r   _DivNoNanGradr    sy     mmBIIaL!!mmBIIaL!!4#"h!!("5"5qb!"<a@@"	Q2r	**r   Powc                 0   | j                   d   }| j                   d   }t        j                  |      }t        j                  |      }	 | j                  xs d}d|v r,t	        |      r!||z  t        j
                  ||dz
        z  dfS d|v rd}n||z  t        j
                  ||dz
        z  }d|v rd}n|j                  j                  rt        j                  |d      }	n|dkD  }	t        j                  |	|t        j                  |            }
t        j                  |	t        j                  |
      t        j                  |            }|t        j                  | j                  d         z  |z  }t!        ||||      S # t        $ r d}Y 
w xY w)z%Returns grad * (y*x^(y-1), z*log(x)).r   r!   r   N)r&   r   r   r|  rX   powr}  r_   
is_complexr  r   r  r  r  r   r"   rT   )r   r   r4   r5   r  r  r|  rP   rQ   masksafe_xlog_xs               r   _PowGradr    st    	iil!iil!}}Q"}}Q"..4"9Q<BYb"q&11477
 
	B	X\\"b1f-	-B
	B 	wwA&d !Vd__T2y':':1'=>FOOD(,,v"6	8L8LQ8OPE	bjjm,	,u	4B	Q2r	**/ 
 s   
?F FFc                     | j                   d   }| j                   d   }t        j                  |      } |||      }t        j                  |||      }d }||fS Nr   r!   )r&   r   r   r   )	r   r   selector_opr4   r5   r   xmaskxgradygrads	            r   _MaximumMinimumGradInputOnlyr    s[    iil!iil!


t
$%
a
%


UD%
0%
%
r   c                    | j                   d   }	 | j                  xs d}d|v rt        |      rt        | ||      S | j                   d   }t        j                  |      } |||      }d|v rd}nt        j                  |||      }d|v rd}	nt        j                  |||      }	t        ||||	      S # t        $ r d}Y w xY w)z;Factor out the code for the gradient of Maximum or Minimum.r!   r   r   N)	r&   r|  rX   r  r}  r   r   r   rT   )
r   r   r  r5   r|  r4   r   r  rP   rQ   s
             r   _MaximumMinimumGradr    s    iil!..4"9Q< *"dK@@ 	iil!


t
$%
a
%
	B			E4	/B
	B			E5$	/B	Q2r	** 
 s   +B4 4CCMaximumc                 8    t        | |t        j                        S )z/Returns grad*(x >= y, x < y) with type of grad.)r  r   r  r   s     r   _MaximumGradr  /  s     
Rx'='=	>>r   Minimumc                 8    t        | |t        j                        S )z/Returns grad*(x <= y, x > y) with type of grad.)r  r   
less_equalr   s     r   _MinimumGradr  5  s     
Rx':':	;;r   SquaredDifferencec                    | j                   d   }| j                   d   }	 | j                  xs d}t        j                  |g      5  t        j                  d|      ||z
  z  }ddd       t        |t        j                        rt        |||      r| fS d|v rdn}d|v rdn }t        ||||      S # t        $ r d}Y w xY w# 1 sw Y   exY w)z!Returns the gradient for (x-y)^2.r   r!   r   r^  N)r&   r|  r}  r   rQ  r   
scalar_mulr/   r	   r0   rw  rT   )r   r   r4   r5   r|  x_gradrP   rQ   s           r   _SquaredDifferenceGradr  ;  s     	iil!iil!..4"
 ' 6   d+q1u5F6
 fmm$)FD* F7?&&tF"&&tVG"	Q2r	**! 
 6 6s   B6 C6CCCLess	LessEqualGreaterGreaterEqualEqualApproximateEqualNotEqual
LogicalAnd	LogicalOr
LogicalNotSelectc                     | j                   d   }| j                   d   }t        j                  |      }d t        j                  |||      t        j                  |||      fS r  )r&   r   r   r  )r   r   cr4   r   s        r   _SelectGradr  b  sY    iil!iil!


q
!%
ooau%ooa%
 r   SelectV2c                 z   | j                   d   }| j                   d   }| j                   d   }| j                  d   }t        j                  g |j                  j
                        }t        j                  |||      }t        j                  |||      }t        |||d       \  }}	t        |||d       \  }}	d ||fS )Nr   r!   r   r^   )r&   r"   r   r   r_   r  r   rT   )
r   r   r  r4   r5   zr   rP   rQ   r   s
             r   _SelectGradV2r  n  s    iil!iil!iil!jjm!
//"DJJ$9$9
:%!T5)"!UD)"
aB
-%"a
aB
-%"a	r2r   c                    | j                  d      }| j                  d      }t        j                  | j                  d         }|s|st	        j
                  ||dd      }|dfS |s|rt	        j
                  ||d      }|dfS |r|st	        j
                  ||dd      }|dfS |r|rt	        j
                  ||ddd      }dfS )	z.Gradient for MatMul, only for the first input.transpose_atranspose_br!   Tr  rs  rs  r  r  rs  Nr#   r   r   r&   r   mat_mul)r   r   t_at_brS  rs  s         r   _MatMulGradAgainstFirstOnlyr  |  s    
M"#
M"#mmBIIaL!!	S!!$tDIF 
 3!!$$7F 
 3!!!TtDIF
 
	 s!!	4TtDF 
r   c                    | j                  d      }| j                  d      }t        j                  | j                  d         }|s|st	        j
                  ||dd      }d|fS |s|rt	        j
                  ||dd      }d|fS |r|st	        j
                  ||d      }d|fS |r|rt	        j
                  ||ddd      }dfS )	z/Gradient for MatMul, only for the second input.r  r  r   Tr  rt  rt  r  r  rt  Nr  )r   r   r  r  ri  rt  s         r   _MatMulGradAgainstSecondOnlyr    s    
M"#
M"#mmBIIaL!!	S!!!TtDIF 
v 3!!$tDIF 
v 3!!!T$7F
 
v	 s!!aTtDF 
vr   MatMulc                    	 | j                   }| d|v rt        | |      S d|v rt        | |      S | j	                  d      }| j	                  d      }t        j                  | j                  d         }t        j                  | j                  d         }|s8|s6t        j                  ||dd      }t        j                  ||dd      }||fS |s7|r5t        j                  ||d      }t        j                  ||dd      }||fS |r7|s5t        j                  ||dd      }t        j                  ||d	      }||fS |r6|r4t        j                  ||ddd
      }t        j                  ||ddd      }fS # t        $ r Y Zw xY w)zGradient for MatMul.r!   r   r  r  Tr  r  r  r  r  r  )
r|  r  r  r}  r#   r   r   r&   r   r  )	r   r   r|  r  r  ri  rS  rs  rt  s	            r   _MatMulGradr    s   		..%	
 	 *2t44""+B55
 	M"#
M"#mmBIIaL!!mmBIIaL!!	S!!$tDIF!!!TtDIF 
 3!!$$7F!!$tDIF 
 3!!!TtDIF!!!T$7F 
 s!!	4TtDF !!aTtDF 
1 
 		s   E> E> >	F
FSparseMatMulc                    | j                  d      }| j                  d      }i | j                  d      | j                  d   j                         <   | j                  d      | j                  d   j                         <   t        j                          xr |j
                  j                  dk(  |j                         <   dfd	}| j                  d   j                  }| j                  d   j                  }|s4|s2 ||| j                  d   |d	
       || j                  d   ||d	      fS |s2|r0 ||| j                  d   |       ||| j                  d   |d	      fS |r2|s0 || j                  d   ||d	
       || j                  d   ||      fS |r7|r4 || j                  d   ||d	d	       ||| j                  d   |d	d	      fS yy)zGradient for SparseMatMul.r  r  a_is_sparser   b_is_sparser!   ReluGradc                 R   | j                         v r|j                         v sJ | j                            }|j                            }|rt        j                  |      }d}t        j                  | |||||      }|j
                  |k7  rt        j                  ||      }|S )z*Helper function to create SparseMatMul op.F)r  r  r  r  )refr   r   r   matmulr_   r   )	t1t2	out_dtyper  r  	t1_sparse	t2_sparser   	is_sparses	           r   _SparseMatMulz(_SparseMatMulGrad.<locals>._SparseMatMul  s     668y RVVX%:::"&&(#I"&&(#Ir"bk??

D zzY]]4+dKr   T)r  )r  )r  r  N)FF)r#   r&   r  r   r.   r   typer_   )r   r   r  r  r  dtype_adtype_br  s          @r   _SparseMatMulGradr    s    	M"#
M"#)"$++m"<)BIIaL"$++m"<)BIIaL%7799 "
ggllj  DHHJ( IIaL'IIaL'	S$		!g4H"))A,g4HJ J3$		!g6$		!g4HJ J
3"))A,g4H"))A,g68 8
s
		!dG4IbiilG "# # sr   Floorc                     d gS r   r   r  s     r   
_FloorGradr    	    
-r   Ceilc                     d gS r   r   r  s     r   	_CeilGradr    r  r   Roundc                     d gS r   r   r  s     r   
_RoundGradr    r  r   Rintc                     d gS r   r   r  s     r   	_RintGradr    s     -r   BatchMatMulc                 >   | j                   d   }| j                   d   }| j                  d      }| j                  d      }|sn|s6t        j                  ||dd      }t        j                  ||dd      }||fS t        j                  ||dd      }t        j                  ||dd      }||fS |s6t        j                  ||dd      }t        j                  ||dd      }||fS t        j                  ||dd      }t        j                  ||dd      }||fS )<Returns the gradient of x and y given the gradient of x * y.r   r!   adj_xadj_yFT)	adjoint_a	adjoint_b)r&   r#   r   r  )r   r   r4   r5   r  r  grad_xgrad_ys           r   _BatchMatMulr    s    	iil!iil!
++g
%
++g
%	tQ%4Hfq$$%Hf 
 tQ%5IftQ$%Hf 
 q$%4Hfq$%5If
 
 q$$$GftQ$$Gf	r   BatchMatMulV2BatchMatMulV3c                    | j                   d   }| j                   d   }| j                  d      }| j                  d      }|sl|s5t        j                  ||ddd      }t        j                  ||ddd      }nt        j                  ||ddd      }t        j                  ||ddd      }nk|s5t        j                  ||ddd      }t        j                  ||ddd      }n4t        j                  ||ddd      }t        j                  ||ddd      }|j	                         }|j	                         }	|j
                  d	u xs |j
                  d
kD  xs |	j
                  d	u xs |	j
                  d
kD  }
|d	d j                         xr  |	d	d j                         xr |d	d |	d	d k(  }|
r|r||fS t        j                  |      }t        j                  |      }t        j                  |d	d |d	d       \  }}t        j                  t        j                  ||      |      }t        j                  t        j                  ||      |      }||fS )r  r   r!   r  r  FT)r  r  rs  )r  r  rt  Nr   r  )r&   r#   r   r  	get_shaper3   is_fully_definedr   r%   r   r2   r'   rJ   )r   r   r4   r5   r  r  r  r  shape_x_staticshape_y_static%output_may_have_non_empty_batch_shapebatch_shapes_matchr  r  r  r  s                   r   _BatchMatMulV2r  (  s\    	iil!iil!
++g
%
++g
%	
Ud4f 
TTU4f 
UeDf 
TU4f 
TUd4f 
TUeDf 
TTT$f 
TT$f ;;=.;;=.d"=n&9&9A&= ?d"=n&9&9A&= ( Sb**, 1Sb**,1Sb^CR00  04F6>q"q"00CR"Sb'B&"bX00<bA&X00<bA&	r   RangeLinSpaceComplexc                     | j                   d   }| j                   d   }t        j                  |      }t        j                  |      }t	        ||||      S )zBReturns the real and imaginary components of 'grad', respectively.r   r!   )r&   r   realimagrT   r  s         r   _ComplexGradr&  j  sK     	iil!iil!}}T"}}T"	Q2r	**r   Realc                 p    t        j                  d|j                        }t        j                  ||      S )z=Returns 'grad' as the real part and set the imaginary part 0.r   r^   r   ro   r_   r   complexr   r   zeros      r   	_RealGradr-  t  -     
		atzz	2$			$	%%r   Imagc                 p    t        j                  d|j                        }t        j                  ||      S )z=Returns 'grad' as the imaginary part and set the real part 0.r   r^   r)  r+  s      r   	_ImagGradr1  {  r.  r   Anglec                    | j                   d   }t        j                  |g      5  t        j                  |      }t        j
                  |      }t        j                  t        j                  ||            }t        j                  d|j                        }t        j                  ||      }| |z  cddd       S # 1 sw Y   yxY w)z$Returns `-grad / (Im(x) + i Re(x))`.r   r^   N)r&   r   rQ  r   r$  r%  r  r*  r   ro   r_   )r   r   r4   reimr  r,  complex_grads           r   
_AngleGradr7    s     	iil!
' 	q	B	q	BH,,R45A4D##D$/L=1  s   BC  C	Conjc                 ,    t        j                  |      S )z&Returns the complex conjugate of grad.)r   r   r?  s     r   	_ConjGradr:    s     
t	r   
ComplexAbsc           
         t        j                  t        j                  |t        j                  |            | j
                  d   z  t        j                  | j                  d   t        j                  | j                  d                     S )z#Returns the gradient of ComplexAbs.r   )r   r  r*  r   r   r&   r"   r   s     r   _ComplexAbsGradr=    ss     
		
	$$T*,.0iil;
**Q---bjjm<>
? ?r   Castc                 j   t         j                  t         j                  t         j                  t         j                  t         j
                  t         j                  g}| j                  d   j                  j                  }|j                  j                  }||v r||v rt        j                  ||      S y r9  )r   float16r  float64bfloat16	complex64
complex128r&   r_   r  r   r   )r   r   re   src_typedst_types        r   	_CastGradrG    s     nnfnnfnnfoo))! YYq\**(ZZ""(]x1}==x((r   Crossc                     | j                   d   }| j                   d   }t        j                  ||      t        j                  ||      fS r  )r&   r   cross)r   r   uvs       r   
_CrossGradrM    s=    iil!iil!
..D
!8>>$#:	;;r   Cumsumc                     | j                   d   }| j                  d      }| j                  d      }t        j                  ||||       d gS )Nr!   r   r   r   r   )r&   r#   r   cumsum)r   r   rE   r   r   s        r   _CumsumGradrR    sL    	1$kk+&)KK	"'oodDI7{K

 r   Cumprodc                    | j                   d   }| j                   d   }| j                  d      }| j                  d      }t        j                  ||||      }t        j                  ||z  |||       }t        j
                  ||      d gS )Nr   r!   r   r   rP  )r&   r#   r   r   rQ  r  )r   r   r4   rE   r   r   r   r   s           r   _CumprodGradrU    s    iil!	1$kk+&)KK	"'			!TY	H$
Tk49'k	# 

c1
%t	,,r   CumulativeLogsumexpc                    | j                   d   }| j                   d   }| j                  d   }| j                  d      }| j                  d      }t        j                  t        j                  |d      t        j                  |      |j                  j                        }t        j                  t        j                  |d      t        j                  |       |j                  j                        }t        j                  t        j                  ||z
  || |      |z         }	t        j                  t        j                  ||z
  || |      |z         }
|	|
z
  d gS )Nr   r!   r   r   )rE   r   r   )r&   r"   r#   r   r   r   r  r  r_   minlessr}  cumulative_logsumexp)r   r   r4   rE   rZ  r   r   log_grad_positivelog_grad_negative
output_pos
output_negs              r   _CumulativeLogsumexpGradr_    s@   iil!	1$Akk+&)KK	"'  ((tQll4
jjnn
  ((mmD!llD5
jjnn
 ||##
2
2[I?ABCD*
 ||##
2
2[I?ABCD*
 z
!4	((r   	NextAfterc                 T   | j                   d   }| j                   d   }t        j                  |      }t        j                  |      }t        j                  ||      \  }}t        j                  |g      5  t        j                  ||j                        }t        j                  ||j                        }	t        j                  t        j                  ||z  |      |      t        j                  t        j                  |	|z  |      |      fcddd       S # 1 sw Y   yxY w)z@Returns gradient of nextafter(x1, x2) with respect to x1 and x2.r   r!   r^   N)r&   r   r%   r   r2   r   rQ  r   r_   r   r'   r   rJ   )
r   r   x1r  s_x1s_x2r_x1r_x2
partial_x1
partial_x2s
             r   _NextAfterGradri    s     
yy|"	yy|"		$		$44T4@*$
' EBHH5JRXX6JJ-t4d<##J$5t<dDEE E Es   8BDD'r   r-   )__doc__numpyrj   tensorflow.python.compatr   tensorflow.python.eagerr   tensorflow.python.frameworkr   r   r   r   r   r	   r
   tensorflow.python.opsr   r   r   r   r   RegisterGradient	Operationr   r   r+   r<   r1   rN   rT   rW   rX   r[   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r$  r'  r*  r.  r2  r6  r<  r@  rG  rK  rV  r[  ra  re  rk  ro  ru  ry  r~  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r
  r  r  r  r  r  r#  r'  r+  r3  r7  r;  rD  rJ  rN  rR  rU  rX  r[  r`  rf  ri  rm  rq  rt  rw  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  NotDifferentiabler  r  r  r  r  r  r  r  r  r  r  r  r&  r-  r1  r7  r:  r=  rG  rM  rR  rU  r_  ri  r   r   r   <module>rs     s   6  + + 3 . L + . 3 + / . * 2 hCMM   
 hCMM   
 o&=3== = '="LJ<	 *%
 eD; D; D;NBcmm B* e! ! !
 e! ! ! fQ#-- Q Q( f-3#-- -3 -3` l#4 4 $4
 m$
; 
; %
;* ()
Ocmm 
O *
O 78!S]] ! 9! )*?s}} ? +? 89Ecmm E :E *+A A ,A 9:Gs}} G ;GFS]] F l#( ( $(
 l#( ( $( m$$2 $2 %$2R /3%)&RLS]] L* *+A A ,A
 *+0 0 ,0
 *+0 0 ,0
 +,,8 ,8 -,8^ e! ! !
 e 
 e/ / / l#/ / $/ i FS]] F !F &'FCMM F (F h<CMM <  < f)#-- ) )
 j!,cmm , ", g*3== * * k"	s}} 	 #	 e   g3==   e) ) ) g-3== - - gN3== N N  i NS]] N !N  gN3== N N  f##-- # # f##-- # # f+#-- + + g#3== # # g#3== # # g3==   j!@cmm @ "@ eG G G fM#-- M M h(CMM (  ( g-3== - - h&CMM &  & i S]]  ! g#3== # # h&CMM &  & l#C C $C l#C C $C hCMM    j!cmm  " k"s}}  # j!cmm  "  k"s}}  #" j!cmm  " k"s}}  # j!cmm  " k"	s}} 	 #	 j!cmm  " j!cmm  "  j!cmm  " j!cmm  " hNCMM N  N$ i *S]] * !* i HS]] H !H6 fN#-- N N$ k"Ns}} N #N$ i .S]] . !. m$A A %A f!#-- ! ! e" " " e# # # e   f	#-- 	 	 f	#-- 	 	 f#--   g	-3== 	- 	- f!#-- ! !7 eg+ +  +, e+ + +, e+ + +B j!+cmm + "+ e+ + + j! "
 j!+cmm + "+ m$ % i +S]] + !+ j!+cmm + "+ e!+ !+ !+HS]] +CMM +4 i ?S]] ? !?
 i <S]] < !<
 )*+s}} + ++4   f    k "   i     n %   g    ( )   j !   l #   k "   l # hCMM    j!
cmm 
 "
CMM $S]] $ h!CMM !  !H n%0##-- 0# &0#f g  f  g  f 
 m$S]]  %2 o&o&9s}} 9 ' '9x   g    j ! i +S]] + !+ f& & f& & g	3== 	 	 f 
 l#? ? $? f
#-- 
 
 g<3== < < hCMM    i 
-S]] 
- !
- +,) ) -)B k"Es}} E #Er   