o
    ?e:                    @   s  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 Ze
ddd Ze
ddd Ze
ddd Zdd ZdZdd Ze
dd d! Zd"d# Ze
d$d%d& Ze
d'd(d) Ze
d*d+d, Ze
d-d.d/ Z e
d0d1d2 Z!e
d3d4d5 Z"e
d6d7d8 Z#e
d9d:d; Z$e
d<d=d> Z%e
d?d@dA Z&e
dBdCdD Z'e
dEdFdG Z(dHdI Z)e
dJdKdL Z*e
dMdNdO Z+e
dPdQdR Z,		ddSdTZ-dUdV Z.e
dWdXdY Z/e
dZd[d\ Z0e
d]d^d_ Z1e
d`dadb Z2e
dcddde Z3e
dfdgdh Z4e
didjdk Z5e
dldmdn Z6e
dodpdq Z7e
drdsdt Z8e
dudvdw Z9e
dxdydz Z:e
d{d|d} Z;e
d~dd Z<e
ddd Z=e
ddd Z>e
ddd Z?e
ddd Z@e
ddd ZAe
ddd ZBe
ddd ZCe
ddd ZDe
ddd ZEe
ddd ZFe
ddd ZGe
ddd ZHe
ddd ZIe
ddd ZJe
ddd ZKe
ddd ZLe
ddd ZMe
ddd ZNe
ddd ZOe
ddd ZPe
ddd ZQe
ddd ZRe
dáddń ZSe
dơddȄ ZTe
dɡdd˄ ZUe
d̡dd΄ ZVe
dϡddф ZWe
dҡddԄ ZXe
dաddׄ ZYe
dءddڄ ZZe
dۡdd݄ Z[e
dޡdd Z\e
ddd Z]e
ddd Z^e
ddd Z_e
ddd Z`e
ddd Zae
ddd Zbe
ddd Zce
ddd Zde
ddd Zee
ddd Zfe
dd d Zge
ddd Zhe
ddd Zie
dd	d
 Zje
ddd Zke
ddd Zle
ddd Zme
ddd Zne
ddd Zoe
ddd Zpe
ddd Zqe
d d!d" Zrd#d$ Zse
d%e
d&d'd( Zte
d)d*d+ Zue
d,d-d. Zve
d/d0d1 Zwe
d2d3d4 Zxe
d5d6d7 Zye
d8d9d: Zze
d;d<d= Z{e
d>d?d@ Z|e
dAdBdC Z}e
dDdEdF Z~dGdH ZdIdJ Ze
dKdLdM Ze
dNdOdP Ze
dQdRdS Ze
dT e
dU e
dV e
dW e
dX e
dY e
dZ e
d[ e
d\ e
d] e
d^d_d` Ze
dadbdc Zddde Zdfdg Ze
dhdidj Ze
dkdldm Ze
dndodp Ze
dqdrds Ze
dtdudv Ze
dwdxdy Ze
dzd{d| Ze
d}e
d~dd Ze
d e
d e
ddd Ze
ddd Ze
ddd Ze
ddd Ze
ddd Ze
ddd Ze
ddd Ze
ddd Ze
ddd Ze
ddd Ze
ddd Ze
ddd ZdS (  z/Gradients for operators defined in math_ops.py.    N)compat)context)constant_op)dtypes)ops)tensor)tensor_util)	array_ops)gen_array_ops)gen_math_ops)math_ops)special_math_opsc                 C   s   | t |d S )z;Divides `x / y` assuming `x, y >= 0`, treating `0 / 0 = 0`.   )r   maximum)xy r   `/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/ops/math_grad.py_safe_shape_div    s   r   ZArgMaxc                 C      ~ ~d d gS Nr   opgradr   r   r   _ArgMaxGrad%      r   ZArgMinc                 C   r   r   r   r   r   r   r   _ArgMinGrad+   r   r   ZEuclideanNormc                 C   sd   | j d }| ds%tt| jd | jd }t||}t||}t| jd || dfS )zGradient for EuclideanNorm.r   	keep_dimsr   N)	outputsget_attrr   reduced_shaper	   shapeinputsreshapetruediv)r   r   outputoutput_shape_kept_dimsr   r   r   _EuclideanNormGrad1   s   

r'   c                 C   s  t  st| tjrt|tjrt|tjs2t| }t|}t||\}}||df||dffS | 	 }|	 }|	 }	|du sNd|v sN|du sNd|v rntj
| dd}tj
|dd}t||\}}||df||dffS ||	k}
||	k}t }z|j||f \}}|||
f|||ffW S  ty   t||\}}tt|}|dusJ tt|}|dusJ ||f|j||f< |||
f|||ff Y S w )a  Optimized version of `broadcast_gradient_args` that caches results.

  This implementation avoids creating `broadcast_gradient_args` ops in the case
  that the input shapes are fully defined, and provides hints to the calling
  code that can be used to avoid creating reduction and reshaping ops.

  Args:
    x: The left input tensor to a broadcasting binary op.
    y: The right input tensor to a broadcasting binary op.
    grad: The incoming gradient tensor for a broadcasting binary op.

  Returns:
    A pair of tuples, containing:
      * A 3-tuple of broadcast information for x, containing:
        * The shape of x (as a tuple or Tensor).
        * The reduction indices for x (as a tuple or Tensor).
        * A boolean, which if True, indicates that x's shape differs from grad's
          shape (and so x's gradient must be reduced and/or reshaped).
      * A 3-tuple of broadcast information for y, containing the respective
        details for y.
  TNF)optimize)r   executing_eagerly
isinstancer   Tensorr	   r!   r
   broadcast_gradient_args_shape_tupleZshape_internalr   get_default_graphZ_bcast_grad_args_cacheKeyErrortupler   try_evaluate_constant)r   r   r   sxsyrxryZx_shape_tupleZy_shape_tupleZgrad_shape_tupleZx_needs_reductionZy_needs_reductiongZrx_valueZry_valuer   r   r   SmartBroadcastGradientArgs@   sV   





r7   r   c                 C   s   |   tu S r   )r-   _empty_tuple)r   r   r   r   	_IsScalar   s   r9   ZSumc                 C   s  | j d  }|durt| j d }|durt|}t|t|rst	 rKt }|
 |}|du rJtjdg| tjd}|
 || ndg| }t||}d|vrctj|tjd}nt| j d }t||dgS d|vrt	 st }t|d}z|j||f \}	}
W n% ty   dd }|t||}	|t||	}
|	|
f|j||f< Y nw t||	}t||
dgS t| j d }| dst| t|| j d }	W d   n1 sw   Y  t||	}t||dgS )	zGradient for Sum.r   Nr   dtypec                 S   s4   t | rt | }|d usJ t|S | }t|S r   )r   Z
is_tf_typer1   r0   )tvaluer   r   r   EvaluateAsTuple   s   

z!_SumGrad.<locals>.EvaluateAsTupler   ) r"   r-   r   Zconstant_valuelennpZarray_equalZaranger   r)   Zones_rank_cachegetr   constantr   int32putr	   r#   r!   Ztiler   r.   r0   Z_reduced_shape_cacher/   r   r    r   r   Zcolocate_withbroadcast_to)r   r   Zinput_0_shapeaxesrankctxZ	new_shapeinput_shapegraphr&   Ztile_scalingr?   r   r   r   _SumGrad   s`   


rL   c                 C   s   t | jd }| jd }| ds(t|| jd }t ||}t ||}nt |}tt	|| jd |j
}t t|| jd |}t||| 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;   
reduce_sumdivide)r   r   rJ   r   r&   Z
indicatorsnum_selectedr   r   r   _MinOrMaxGrad   s   


rR   ZMaxc                 C   
   t | |S )zGradient for Max.rR   r   r   r   r   _MaxGrad      
rU   ZMinc                 C   rS   r   rT   r   r   r   r   _MinGrad   s   
rW   ZMeanc           
      C   s   t | |d }| jd  }| jd  }|dur?|dur?d|vr?d|vr?t|}t|}|t|d }tj||j	d}nt
| jd }t
|}| jd | | }	tt
||	}t|t||j	dfS )zGradient for Mean.r   Nr   r:   )rL   r"   r-   r   rA   prodmaxr   rC   r;   r	   r!   sizer   reduce_prodgatherr$   rM   )
r   r   Zsum_gradrJ   output_shapeZ
input_sizeZoutput_sizefactor
input_rankrG   r   r   r   	_MeanGrad   s"   


r`   ZProdc                 C   s  t | jd }t | jd dg}| ds&t|| jd }t ||}t ||}t	dG t 
| jd }|| | }t|tj}td|}t||tj\}}	t ||gd}
tt ||}tt ||}W d   n1 s{w   Y  t | jd |
}t |}t |||f}tj|ddd}tj|dddd	}t t|t| |}|t |t |
 }t ||dfS )
zGradient for Prod.r   r   r<   r   z/cpu:0NT)axis	exclusive)ra   rb   reverse)r	   r!   r"   r#   r   r   r    rF   r   ZdevicerH   rM   r   rD   ranger
   Z	list_diffconcatr[   r\   	transposecumprodconjZinvert_permutation)r   r   rJ   Zreduction_indicesr&   rH   Zreducedidxother_permZreduced_numZ	other_numZpermutedZpermuted_shapeZreshapedleftrightr   outr   r   r   	_ProdGrad
  s4   
	
rp   Z
SegmentSumc                 C   s   t || jd dfS )zGradient for SegmentSum.r   N)r	   r\   r"   r   r   r   r   _SegmentSumGrad;  s   rq   ZSegmentMeanc                 C   s   t | jd }t t | jd t jt |d dtjdgd}t j||j	d}t
|t
|| jd }t || jd dfS )zGradient for SegmentMean.r   r   r:   N)r	   rH   r"   re   r!   onesZexpand_dimsr   rD   r;   r   rP   segment_sumr\   )r   r   r_   Z
ones_shaperr   Zscaled_gradr   r   r   _SegmentMeanGradA  s   rt   ZSparseSegmentSumc                 C   sl   t | jd d }tdddr"t|| jd | jd |ddfS tt || jd | jd |ddfS )zGradient for SparseSegmentSum.r        
   r      N	r	   r!   r"   r   Zforward_compatibler   Zsparse_segment_sum_gradunsorted_segment_sumr\   r   r   Zdim0r   r   r   _SparseSegmentSumGradO  s   r|   ZSparseSegmentSumWithNumSegmentsc                 C   sp   t | jd d }tdddr#t|| jd | jd |dddfS tt || jd | jd |dddfS )z-Gradient for SparseSegmentSumWithNumSegments.r   ru   rv   rw   r   rx   Nry   r{   r   r   r   $_SparseSegmentSumWithNumSegmentsGrad[  s   r}   ZSparseSegmentMeanc                 C   6   t | jd d }t|| jd | jd |ddfS )zGradient for SparseSegmentMean.r   r   rx   Nr	   r!   r"   r   Zsparse_segment_mean_gradr{   r   r   r   _SparseSegmentMeanGradh     r   Z SparseSegmentMeanWithNumSegmentsc                 C   8   t | jd d }t|| jd | jd |dddfS )z.Gradient for SparseSegmentMeanWithNumSegments.r   r   rx   Nr   r{   r   r   r   %_SparseSegmentMeanWithNumSegmentsGradp     r   ZSparseSegmentSqrtNc                 C   r~   )z Gradient for SparseSegmentSqrtN.r   r   rx   Nr	   r!   r"   r   Zsparse_segment_sqrt_n_gradr{   r   r   r   _SparseSegmentSqrtNGradx  r   r   Z!SparseSegmentSqrtNWithNumSegmentsc                 C   r   )z/Gradient for SparseSegmentSqrtNWithNumSegments.r   r   rx   Nr   r{   r   r   r   &_SparseSegmentSqrtNWithNumSegmentsGrad  r   r   c                 C   s   t j| jd | jd jd}t | jd | jd }t| jd |}tt	||j| jd }t
||}t || jd }t |||dfS )z) Gradient for SegmentMin and SegmentMax. r   r:   r   N)r	   
zeros_liker"   r;   r\   r   r   rN   rs   rM   rP   where_v2)r   r   zerosgathered_outputsis_selectedrQ   weighted_gradsgathered_gradsr   r   r   _SegmentMinOrMaxGrad  s   r   Z
SegmentMinc                 C   rS   )zGradient for SegmentMin.r   r   r   r   r   _SegmentMinGrad  rV   r   Z
SegmentMaxc                 C   rS   )zGradient for SegmentMax.r   r   r   r   r   _SegmentMaxGrad  rV   r   ZSegmentProdc                 C   s   | j d }| j d }t|d}ttj|tjd|}t	t
|dt||}t	|t||}t||}t| jd |}t||}	|| }
t	||	|
}t||}|| 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   rN   r   rs   rM   r   rD   r	   r   greaterr   	ones_likeZsegment_prodr\   r   )r   r   dataZsegment_idsis_zero	num_zerosnon_zero_datanon_zero_prodgathered_prodgathered_non_zero_prodprod_divided_by_elpartial_derivativegathered_gradr   r   r   _SegmentProdGrad  s&   

r   c                 C   s   |du rt |t|}t| |}|du rJt |d}t|}tj|tjt	|t	| g|j
dgdd}t||}|tj|tjd@ }t|}t|||||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.
  Nr   r:   )ra   )r   r   r	   r   r\   greater_equalr!   re   rr   rH   r;   r#   r   r   boolr   )paramsZidszero_clipped_indicesis_positiveZgatheredZis_positive_shapeZbroadcastable_shapeZ
zero_slicer   r   r   _GatherDropNegatives  s2   

r   c                 C   s   t | jd | jd \}}}t| jd |}t||}tt||j| jd | jd }t	||}t |d||\}}	}	t
|}
t
|||
ddfS )z9 Gradient for UnsortedSegmentMin and UnsortedSegmentMax. r   r   rx   N)r   r   r"   r   rN   logical_andrz   rM   r;   rP   r	   r   r   )r   r   r   r   r   r   rQ   r   r   rk   r   r   r   r   _UnsortedSegmentMinOrMaxGrad  s   

r   ZUnsortedSegmentSumc                 C   s   t || jd d ddfS )z Gradient for UnsortedSegmentSum.r   r   N)r   r"   r   r   r   r   _UnsortedSegmentSumGrad   s   r   ZUnsortedSegmentMaxc                 C   rS   )z" Gradient for UnsortedSegmentMax. r   r   r   r   r   _UnsortedSegmentMaxGrad  rV   r   ZUnsortedSegmentMinc                 C   rS   )z" Gradient for UnsortedSegmentMin. r   r   r   r   r   _UnsortedSegmentMinGrad  rV   r   ZUnsortedSegmentProdc                 C   s
  t | jd d}tt j|tjd| jd | jd }t	t 
|dt||}t	|t| jd | jd }t|| jd | jd }t | jd t| jd }t| jd |}t||}|| jd  }	t	|||	}
t|| jd |d }||
 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   rx   N)r   rN   r"   r   rz   rM   r   rD   r	   r   r   r   r   Zunsorted_segment_prodr   r\   r   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   _UnsortedSegmentProdGrad  s8   r   ZAbsc                 C   s   | j d }|t| S Nr   )r"   r   signr   r   r   r   r   r   _AbsGradB  s   
r   ZNegc                 C   s   | S )zReturns -grad.r   rk   r   r   r   r   _NegGradH     r   ZInvc                 C      | j d }t||S zReturns -grad * (1 / x^2).r   r   r   reciprocal_gradr   r   r   r   r   r   _InvGradN     
r   Z
Reciprocalc                 C   r   r   r   r   r   r   r   _ReciprocalGradU  r   r   ZInvGradc                 C   p   | j d }t|g# t| j d }t|}|d | | t||fW  d    S 1 s1w   Y  d S Nr   r          r"   r   control_dependenciesr   rh   r   r   r   r   bcacgr   r   r   _InvGradGrad\     

$r   ZReciprocalGradc                 C   r   r   r   r   r   r   r   _ReciprocalGradGradf  r   r   ZSquarec                 C   sh   | j d }t|g t|}tjd|jd}t|t||W  d    S 1 s-w   Y  d S )Nr          @r:   )	r"   r   r   r   rh   r   rC   r;   multiplyr   r   r   r   r   r   r   _SquareGradp  s   

$r   ZSqrtc                 C   r   r   )r   r   Z	sqrt_gradr   r   r   r   	_SqrtGradz  s   
r   ZSqrtGradc                 C   sd   | j d }| jd }t|g || }t| | d| fW  d    S 1 s+w   Y  d S )Nr         ?)r"   r   r   r   r   rh   )r   r   ar   gar   r   r   _SqrtGradGrad  s   

$r   ZRsqrtc                 C   r   )z Returns -0.5 * grad * conj(y)^3.r   )r   r   
rsqrt_gradr   r   r   r   
_RsqrtGrad  r   r   Z	RsqrtGradc                 C   s   | j d }| j d }t|g' t|}t|}d| | t| }t||}||fW  d   S 1 s:w   Y  dS )z<Returns backprop gradient for f(a,b) = -0.5 * b * conj(a)^3.r   r   g      N)r"   r   r   r   rh   squarer   r   )r   r   r   r   r   r   grad_agrad_br   r   r   _RsqrtGradGrad  s   



$r   ZExpc                 C   sL   | j d }t|g t|}|| W  d   S 1 sw   Y  dS zReturns grad * exp(x).r   N)r   r   r   r   rh   r   r   r   r   _ExpGrad  
   

$r   ZExpm1c                 C   sV   | j d }t|g t|}t|}|| W  d   S 1 s$w   Y  dS r   )r"   r   r   r   rh   expr   r   r   r   
_Expm1Grad  s   


$r   ZLogc                 C   R   | j d }t|g t|}|t| W  d   S 1 s"w   Y  dS )zReturns grad * (1/x).r   Nr"   r   r   r   rh   
reciprocalr   r   r   r   _LogGrad  
   

$r   ZLog1pc                 C   sV   | j d }t|g t|}|td|  W  d   S 1 s$w   Y  dS )zReturns grad * (1/(1 + x)).r   r   Nr   r   r   r   r   
_Log1pGrad  s
   

$r   ZXlogyc              	   C   s   | j d }| j d }t|}t|}t||\}}t|g> tjt	|tjd|j
d|j
d}t||}	t||}
tt|	| ||tt|
| ||fW  d   S 1 scw   Y  dS )z8Returns gradient of xlogy(x, y) with respect to x and y.r   r           r:   N)r"   r	   r!   r
   r,   r   r   r   rM   	not_equalr;   r   xlogyxdivyr#   rO   r   r   r   r   r2   r3   r4   r5   Z
not_zero_x	partial_xZ	partial_yr   r   r   
_XLogyGrad  s   



$r   ZXlog1pyc              	   C   s   | j d }| j d }t|}t|}t||\}}t|g@ tjt	|tjd|j
d|j
d}t||}	t||d }
tt|	| ||tt|
| ||fW  d   S 1 sew   Y  dS )z:Returns gradient of xlog1py(x, y) with respect to x and y.r   r   r   r:         ?N)r"   r	   r!   r
   r,   r   r   r   rM   r   r;   r   xlog1pyr   r#   rO   r   r   r   r   _XLog1pyGrad  s   



$r   ZXdivyc              	   C   s   | j d }| j d }t|}t|}t||\}}t|gC tjt	|tjd|j
d|j
d}t||}	tt||d }
tt|	| ||tt|
| ||fW  d   S 1 shw   Y  dS )z8Returns gradient of xdivy(x, y) with respect to x and y.r   r   r   r:   rx   N)r"   r	   r!   r
   r,   r   r   r   rM   r   r;   r   r   negativer#   rO   r   r   r   r   
_XDivyGrad  s   



$r   ZSinhc                 C   r   )zReturns grad * cosh(x).r   N)r"   r   r   r   rh   coshr   r   r   r   	_SinhGrad  r   r   ZCoshc                 C   r   )zReturns grad * sinh(x).r   N)r"   r   r   r   rh   sinhr   r   r   r   	_CoshGrad  r   r   ZTanhc                 C   P   | j d }t|g t|}t||W  d   S 1 s!w   Y  dS )z'Returns grad * (1 - tanh(x) * tanh(x)).r   N)r   r   r   r   rh   r   	tanh_gradr   r   r   r   	_TanhGrad  
   


$r   ZAsinhc                 C   R   | j d }t|g t|}|t| W  d   S 1 s"w   Y  dS )zReturns grad * 1/cosh(y).r   N)r   r   r   r   rh   r   r   r   r   r   
_AsinhGrad  r   r   ZAcoshc                 C   r   )zReturns grad * 1/sinh(y).r   N)r   r   r   r   rh   r   r   r   r   r   
_AcoshGrad  r   r   ZAtanhc                 C   x   | j d }t|g' t|}t|}tjd|jd}t	t
||}|| W  d   S 1 s5w   Y  dS )zReturns grad * 1/ (1 - x^2).r   r   r:   N)r"   r   r   r   rh   r   r   rC   r;   r   subtractr   r   r   x2oneinvr   r   r   
_AtanhGrad"     


$r   ZTanhGradc                 C   sl   t |g& t| jd }t| jd }|d | | t||fW  d    S 1 s/w   Y  d S )Nr   r   r   )r   r   r   rh   r"   r   r   )r   r   r   r   r   r   r   _TanhGradGrad.  s
   $r  ZErfc                 C   z   | j d }tjdttj |jd}t|g t	
|}|| t	t	|  W  d   S 1 s6w   Y  dS )z'Returns grad * 2/sqrt(pi) * exp(-x**2).r   rx   r:   Nr"   r   rC   rA   sqrtpir;   r   r   r   rh   r   r   )r   r   r   Ztwo_over_root_pir   r   r   _ErfGrad6  s   

$r  ZErfcc                 C   r  )z(Returns -grad * 2/sqrt(pi) * exp(-x**2).r   r:   Nr  )r   r   r   Zminus_two_over_root_pir   r   r   	_ErfcGrad@  s   

$r  ZErfinvc                 C   sj   t jttjd |jd}t|g || t	t
| jd  W  d   S 1 s.w   Y  dS )z0Returns grad * sqrt(pi) / 2 * exp(erfinv(x)**2).rx   r:   r   Nr   rC   rA   r  r  r;   r   r   r   r   r   r   )r   r   Zroot_pi_over_twor   r   r   _ErfinvGradK  s   
$r
  ZNdtric                 C   sn   t jtdtj |jd}t|g || t	t
| jd d  W  d   S 1 s0w   Y  dS )z3Returns grad * sqrt(2 * pi) * exp(ndtri(x)**2 / 2).rx   r:   r   r   Nr	  )r   r   Zroot_two_pir   r   r   
_NdtriGradT  s   
$r  ZLgammac                 C   r   )zReturns grad * digamma(x).r   N)r"   r   r   r   rh   Zdigammar   r   r   r   _LgammaGrad]  r   r  ZDigammac                 C   sd   | j d }t|g t|}ttjd|jd|}|| W  d   S 1 s+w   Y  dS )zFCompute gradient of the digamma function with respect to its argument.r   r   r:   N)	r"   r   r   r   rh   	polygammar	   rC   r;   r   r   r   r   r   r   r   _DigammaGradf  s   

$r  ZDawsnc                 C   sX   | j d }| jd }t|g |dd| |   W  d   S 1 s%w   Y  dS )z:Compute gradient of dawsn(x) with respect to its argument.r   r   rx   N)r"   r   r   r   r   r   r   r   
_DawsnGradp  s
   

$r  ZExpintc                 C   sL   | j d }t|g |t| | W  d   S 1 sw   Y  dS )z;Compute gradient of expint(x) with respect to its argument.r   N)r"   r   r   r   r   r   r   r   r   _ExpintGrady  s   
$r  Z
FresnelCosc                 C   X   | j d }t|g |ttjd t|  W  d   S 1 s%w   Y  dS )z@Compute gradient of fresnel_cos(x) with respect to its argument.r   r   N)r"   r   r   r   cosrA   r  r   r   r   r   r   _FresnelCosGrad     
$r  Z
FresnelSinc                 C   r  )z@Compute gradient of fresnel_sin(x) with respect to its argument.r   r   N)r"   r   r   r   sinrA   r  r   r   r   r   r   _FresnelSinGrad  r  r  ZSpencec                 C   sr   | j d }t|g$ t|d|  }tt|dt| |}|| W  d   S 1 s2w   Y  dS )z;Compute gradient of spence(x) with respect to its argument.r   r   r   N)	r"   r   r   r   logr	   whererN   r   r  r   r   r   _SpenceGrad  s   
$r  ZBesselI0c                 C   sL   | j d }t|g t|}|| W  d   S 1 sw   Y  dS )z>Compute gradient of bessel_i0(x) with respect to its argument.r   N)r"   r   r   r   Z	bessel_i1r  r   r   r   _BesselI0Grad  r   r  Z	BesselI0ec                 C   sd   | j d }| jd }t|g t|t||  }|| W  d   S 1 s+w   Y  dS )z?Compute gradient of bessel_i0e(x) with respect to its argument.r   N)r"   r   r   r   r   Z
bessel_i1er   r   r   r   r   r   r   r   r   r   _BesselI0eGrad  s   

$r  ZBesselI1c              
   C   ~   | j d }| jd }t|g% tt|dtd|j	t
|t|| }|| W  d   S 1 s8w   Y  dS )z>Compute gradient of bessel_i1(x) with respect to its argument.r   r   r   N)r"   r   r   r   r	   r   r   rN   rM   r;   r   Z	bessel_i0divr   r   r   r   Zdy_dxr   r   r   _BesselI1Grad     

$r!  Z	BesselI1ec                 C   s   | j d }| jd }t|g+ tt|dtd|j	t
||t|t|   }|| W  d   S 1 s>w   Y  dS )z?Compute gradient of bessel_i1e(x) with respect to its argument.r   r   r   N)r"   r   r   r   r	   r   r   rN   rM   r;   r   Z
bessel_i0er   r   r   r   r   r   _BesselI1eGrad  s   


$r#  ZBesselK0c                 C   N   | j d }t|g t| }|| W  d   S 1 s w   Y  dS )z>Compute gradient of bessel_k0(x) with respect to its argument.r   N)r"   r   r   r   Z	bessel_k1r  r   r   r   _BesselK0Grad  
   
$r%  Z	BesselK0ec                 C   sZ   | j d }| jd }t|g |t| }|| W  d   S 1 s&w   Y  dS )z?Compute gradient of bessel_k0e(x) with respect to its argument.r   N)r"   r   r   r   r   Z
bessel_k1er  r   r   r   _BesselK0eGrad  s   

$r'  ZBesselK1c                 C   sd   | j d }| jd }t|g t| t|| }|| W  d   S 1 s+w   Y  dS )z>Compute gradient of bessel_k1(x) with respect to its argument.r   N)r"   r   r   r   r   Z	bessel_k0r   r  r  r   r   r   _BesselK1Grad  s   

$r(  Z	BesselK1ec                 C   sh   | j d }| jd }t|g |dt|  t| }|| W  d   S 1 s-w   Y  dS )z?Compute gradient of bessel_k1e(x) with respect to its argument.r   r   N)r"   r   r   r   r   r   r   Z
bessel_k0er  r   r   r   _BesselK1eGrad  s   

$r)  ZBesselJ0c                 C   r$  )z>Compute gradient of bessel_j0(x) with respect to its argument.r   N)r"   r   r   r   Z	bessel_j1r  r   r   r   _BesselJ0Grad  r&  r*  ZBesselJ1c              
   C   r  )z>Compute gradient of bessel_j1(x) with respect to its argument.r   r   r   N)r"   r   r   r   r	   r   r   rN   rM   r;   r   Z	bessel_j0r  r   r   r   r   _BesselJ1Grad  r"  r+  ZBesselY0c                 C   r$  )z>Compute gradient of bessel_y0(x) with respect to its argument.r   N)r"   r   r   r   Z	bessel_y1r  r   r   r   _BesselY0Grad  r&  r,  ZBesselY1c                 C   sb   | j d }| jd }t|g t|t|| }|| W  d   S 1 s*w   Y  dS )z>Compute gradient of bessel_y1(x) with respect to its argument.r   N)r"   r   r   r   r   Z	bessel_y0r   r  r  r   r   r   _BesselY1Grad!  s   

$r-  ZIgammac           
      C   s   | j d }| j d }t|}t|}t||\}}t|g: t||}t	
| |d t	|  t	| }	tt	|| ||tt	|	| ||fW  d   S 1 s_w   Y  dS )z9Returns gradient of igamma(a, x) with respect to a and x.r   r   N)r"   r	   r!   r
   r,   r   r   r   igamma_grad_ar   r   r  lgammar#   rO   )
r   r   r   r   sar2   rar4   Z	partial_ar   r   r   r   _IgammaGrad-  s   



$r2  ZIgammacc                 C   s   t | |\}}| | fS )zDReturns gradient of igammac(a, x) = 1 - igamma(a, x) w.r.t. a and x.)r2  )r   r   r.  Zigamma_grad_xr   r   r   _IgammacGrad@  s   r3  ZBetaincc                 C   s   | j \}}}t|}t|}t||\}}t|t| t||  }	tt	|d | t
|d | |	 }
ddtt|
| ||fS )z7Returns gradient of betainc(a, b, x) with respect to x.r   N)r"   r	   r!   r
   r,   r   r/  r   r   r   r   r#   rO   )r   r   r   r   r   r0  r2   rk   r4   Zlog_betar   r   r   r   _BetaincGradG  s"   

r4  Zetac           	      C   s   | j d }| j d }t|}t|}t||\}}t|g+ t|}t|}| t	|d | }dt
t|| ||fW  d   S 1 sPw   Y  dS )z7Returns gradient of zeta(x, q) with respect to x and q.r   r   N)r"   r	   r!   r
   r,   r   r   r   rh   zetar#   rO   )	r   r   r   qr2   sqZ	unused_rxZrqZ	partial_qr   r   r   	_ZetaGradc  s   





$r9  Z	Polygammac           	      C   s   | j d }| j d }t|}t|}t||\}}t|g( t|}t|}t	|d |}dt
t|| ||fW  d   S 1 sMw   Y  dS )z6Returns gradient of psi(n, x) with respect to n and x.r   r   N)r"   r	   r!   r
   r,   r   r   r   rh   r  r#   rO   )	r   r   nr   Zsnr2   Z	unused_rnr4   r   r   r   r   _PolygammaGradv  s   





$r;  ZSigmoidc                 C   r   )z-Returns grad * sigmoid(x) * (1 - sigmoid(x)).r   N)r   r   r   r   rh   r   sigmoid_gradr   r   r   r   _SigmoidGrad  r   r=  ZSigmoidGradc                 C   st   t |g* t| jd }t| jd }|| }|d| |  t||fW  d    S 1 s3w   Y  d S )Nr   r   r   )r   r   r   rh   r"   r   r<  )r   r   r   r   gbr   r   r   _SigmoidGradGrad  s   $r?  ZSignc                 C   s   | j d }t|S )z
Returns 0.r   )r"   r	   r   )r   rk   r   r   r   r   	_SignGrad  s   

r@  ZSinc                 C   r   )zReturns grad * cos(x).r   N)r"   r   r   r   rh   r  r   r   r   r   _SinGrad  r   rA  ZCosc                 C   sT   | j d }t|g t|}| t| W  d   S 1 s#w   Y  dS )zReturns grad * -sin(x).r   N)r"   r   r   r   rh   r  r   r   r   r   _CosGrad  s
   

$rB  ZTanc                 C   sf   | j d }t|g t|}tt|}t|}|| W  d   S 1 s,w   Y  dS )zReturns grad * 1/sec^2(x).r   N)r"   r   r   r   rh   r   r  r   )r   r   r   ZsecxZsecx2r   r   r   _TanGrad  s   


$rC  ZAsinc                 C   s   | j d }t|g, t|}t|}tjd|jd}t	t
||}t|}|| W  d   S 1 s:w   Y  dS )zReturns grad * 1/sqrt(1-x^2).r   r   r:   Nr"   r   r   r   rh   r   r   rC   r;   r  r   r   r   r   r   r   r   Zdenr   r   r   r   	_AsinGrad  s   



$rF  ZAcosc                 C   s   | j d }t|g- t|}t|}tjd|jd}t	t
||}t|}| | W  d   S 1 s;w   Y  dS )zReturns grad * -1/sqrt(1-x^2).r   r   r:   NrD  rE  r   r   r   	_AcosGrad  s   



$rG  ZAtanc                 C   r   )zReturns grad * 1/ (1 + x^2).r   r   r:   N)r"   r   r   r   rh   r   r   rC   r;   r   addr   r   r   r   	_AtanGrad  r   rI  ZAtan2c                 C   s   | j d }| j d }t|gG t|||\\}}}\}}}	|t|t|  }
| |
 }|r<tt|||}||
 }|	rLtt|||}||fW  d   S 1 sZw   Y  dS )z8Returns grad * x / (x^2 + y^2), grad * -y / (x^2 + y^2).r   r   N)	r"   r   r   r7   r   r   r	   r#   rO   )r   r   r   r   r2   r4   must_reduce_xr3   r5   must_reduce_yZgrad_invgxgyr   r   r   
_Atan2Grad  s   



$rN  ZAddNc                 C   s   |gt | j S )z"Copies the gradient to all inputs.)r@   r"   r   r   r   r   	_AddNGrad  s   rO  c                 C   s8   |   }|  }|  }||ko||ko|d uod |vS r   )r-   )r   r   r   x_shapey_shapeZ
grad_shaper   r   r   _ShapesFullySpecifiedAndEqual  s   rR  AddZAddV2c                 C   s  | j d }d}z| j}|durd|v rt|r|dfW S W n	 ty&   Y nw | j d }t|tjr<t|||r<||fS t|||\\}}}\}}	}
|durUd|v rUd}n|sZ|}n
t	
t|||}|durrd|v rrd}||fS |
sz|}||fS t	
t||	|}||fS )zGradient for Add.r   Nr   r"   skip_input_indicesr9   AttributeErrorr*   r   r+   rR  r7   r	   r#   r   rO   r   r   r   rU  r   r2   r4   rJ  r3   r5   rK  rL  rM  r   r   r   _AddGrad  s@   




rX  Subc                 C   s  | j d }d}z| j}|durd|v rt|r|dfW S W n	 ty&   Y nw | j d }t|tjr=t|||r=|| fS t|||\\}}}\}}	}
|durVd|v rVd}n|s[|}n
t	
t|||}|dursd|v rsd}||fS |
s|| }||fS t	
t| |	|}||fS )zGradient for Sub.r   Nr   rT  rW  r   r   r   _SubGrad/  s@   





rZ  ZMulc                 C   s  | j d }d}z| j}|dur#d|v r#t|r#t|t|dfW S W n	 ty-   Y nw | j d }t|t	j
rTt|||rT|jtjtjfv rTt||t||fS |jj|jjkseJ |jd|jft|||\\}}}\}}	}
t|}t|}|durd|v rd}n|st||}nttt||||}|durd|v rd}||fS |
st||}||fS ttt|||	|}||fS )z&The gradient of scalar multiplication.r   Nr    vs. )r"   rU  r9   r   mulr   rh   rV  r*   r   r+   rR  r;   r   rD   float32
base_dtyper7   r	   r#   rO   rW  r   r   r   _MulGradQ  sR   


"


r_  ZMulNoNanc              	   C   s   | j d }| j d }t|tjr"t|||r"t||t||fS |jj|jjks3J |jd|jft	
|}t	
|}t||\}}t	tt||||t	tt||||fS )z;The gradient of scalar multiplication with NaN-suppression.r   r   r[  )r"   r*   r   r+   rR  r   Z
mul_no_nanr;   r^  r	   r!   r
   r,   r#   r   rO   r   r   r   r   r2   r3   r4   r5   r   r   r   _MulNoNanGradz  s"   


"

ra  Divc                 C      | j d }| j d }t|}t|}t||\}}t|}t|}ttt	||||tt|t	t	| || ||fS )z"The gradient for the Div operator.r   r   )
r"   r	   r!   r
   r,   r   rh   r#   rO   rP   r`  r   r   r   _DivGrad  s   





rd  FloorDivc                 C      dS )z'The gradient for the FloorDiv operator.NNr   rk   Zunused_gradr   r   r   _FloorDivGrad  s   ri  ZFloorModc                 C   s   t | jd }t | jd }t|}t|}t||\}}t ||}tt 	|||}	tt 	|t 
| ||}
|	|
fS )z Returns grad * (1, -floor(x/y)).r   r   )r   rh   r"   r	   r!   r
   r,   Z	floor_divr#   rO   r   )r   r   r   r   r2   r3   r4   r5   Zfloor_xyrL  rM  r   r   r   _FloorModGrad  s   

rj  ZTruncateDivc                 C   rf  )Nrg  r   rh  r   r   r   _TruncateDivGrad  s   rk  ZRealDivc                 C   rc  )zRealDiv op gradient.r   r   )
r"   r	   r!   r
   r,   r   rh   r#   rO   Zrealdivr`  r   r   r   _RealDivGrad  s"   





rl  ZDivNoNanc                 C   rc  )zDivNoNan op gradient.r   r   )
r"   r	   r!   r
   r,   r   rh   r#   rO   
div_no_nanr`  r   r   r   _DivNoNanGrad  s$   





rn  Powc                 C   s  | j d }| j d }d}z*| j}|dur5d|v r5t|r5t|}t|}|| t||d  dfW S W n	 ty?   Y nw t|||\\}}}\}}	}
t|}t|}|du s`d|vry|| t||d  }|rxt	t
|||}nd}|du sd|vrt| jd }|jjrt|d}n|dk}t||t|}t|t|t|}|| | }|
rt	t
||	|}||fS d}||fS )z%Returns grad * (y*x^(y-1), z*log(x)).r   r   N)r"   rU  r9   r   rh   powrV  r7   r	   r#   rO   r   r;   Z
is_complexr   r  r   r  r   )r   r   r   r   rU  r2   r4   rJ  r3   r5   rK  rL  zmaskZsafe_xZlog_xrM  r   r   r   _PowGrad  sL   






rs  c           	      C   sB   | j d }| j d }t|}|||}t|||}d }||fS Nr   r   )r"   r	   r   r   )	r   r   selector_opr   r   r   xmaskxgradygradr   r   r   _MaximumMinimumGradInputOnly  s   



ry  c                 C   s  | j d }d}z| j}|durd|v rt|rt| ||W S W n	 ty(   Y nw | j d }t|}t|}t|}|||}	t	||\}
}|durUd|v rUd}nt
|	||}tt||
|}|durtd|v rtd}||fS t
|	||}tt|||}||fS )z;Factor out the code for the gradient of Maximum or Minimum.r   Nr   )r"   rU  r9   ry  rV  r	   r!   r   r
   r,   r   r#   r   rO   )r   r   ru  r   rU  r   r2   r3   r   rv  r4   r5   rL  rw  rM  rx  r   r   r   _MaximumMinimumGrad  s8   





rz  ZMaximumc                 C      t | |tjS )z/Returns grad*(x >= y, x < y) with type of grad.)rz  r   r   r   r   r   r   _MaximumGrad@     r|  ZMinimumc                 C   r{  )z/Returns grad*(x <= y, x > y) with type of grad.)rz  r   Z
less_equalr   r   r   r   _MinimumGradF  r}  r~  ZSquaredDifferencec                 C   s4  | j d }| j d }d}z| j}W n	 ty   Y nw t|g td|||  }W d   n1 s6w   Y  t|tj	rLt
|||rL|| fS t|||\\}}}\}	}
}|dured|v red}n|rrtt|||}n|}|durd|v rd}||fS |rtt||
|	 }||fS | }||fS )z!Returns the gradient for (x-y)^2.r   r   Nr   )r"   rU  rV  r   r   r   Z
scalar_mulr*   r   r+   rR  r7   r	   r#   rO   )r   r   r   r   rU  Zx_gradr2   r4   rJ  r3   r5   rK  rL  rM  r   r   r   _SquaredDifferenceGradL  s<   





r  ZLessZ	LessEqualZGreaterZGreaterEqualZEqualZApproximateEqualZNotEqualZ
LogicalAndZ	LogicalOrZ
LogicalNotZSelectc                 C   s<   | j d }| j d }t|}d t|||t|||fS rt  )r"   r	   r   r  )r   r   cr   r   r   r   r   _SelectGrad  s   


r  ZSelectV2c                 C   s   | j d }| j d }| j d }tjg |jjd}t|||}t|}t| jd }t	||\}	}
t
j|d|	d}t||}t|||}t|}t	||\}}
t
j|d|d}t||}d ||fS )Nr   r   rx   r:   T)Zkeepdimsra   )r"   r	   r   r;   r^  r   r!   r   r
   r,   r   rO   r#   )r   r   r  r   r   r   rL  rP  r]   Zreduce_xrk   rM  rQ  Zreduce_yr   r   r   _SelectGradV2  s    





r  c                 C   s   |  d}|  d}t| jd }|s"|s"tj||dd}|dfS |s0|r0t||}|dfS |r@|s@tj||dd}|dfS |rM|rMtj||ddd}|dfS )z.Gradient for MatMul, only for the first input.transpose_atranspose_br   Tr  r  r  Nr   r   rh   r"   r   mat_mul)r   r   t_at_br   r   r   r   r   _MatMulGradAgainstFirstOnly  s   

r  c                 C   s   |  d}|  d}t| jd }|s"|s"tj||dd}d|fS |s2|r2tj||dd}d|fS |r@|s@t||}d|fS |rM|rMtj||ddd}d|fS )z/Gradient for MatMul, only for the second input.r  r  r   Tr  r  Nr  )r   r   r  r  r   r   r   r   r   _MatMulGradAgainstSecondOnly  s   

r  ZMatMulc           	      C   s>  z| j }|durd|v rt| |W S d|v rt| |W S W n	 ty&   Y nw | d}| d}t| jd }t| jd }|sY|sYtj	||dd}tj	||dd}||fS |so|rot	||}tj	||dd}||fS |r|stj	||dd}t	||}||fS |r|rtj	||ddd	}tj	||ddd	}||fS )
zGradient for MatMul.Nr   r   r  r  Tr  r  r  )
rU  r  r  rV  r   r   rh   r"   r   r  )	r   r   rU  r  r  r   r   r   r   r   r   r   _MatMulGrad  s>   


r  ZSparseMatMulc                    s`  |  d}|  d}i  |  d | jd  < |  d | jd  < t  o.|jjdk | < d fd	d
	}| jd j}| jd j}|s`|s`||| jd |dd|| jd ||ddfS |sx|rx||| jd |||| jd |ddfS |r|s|| jd ||dd|| jd ||fS |r|r|| jd ||ddd||| jd |dddfS dS dS )zGradient for SparseMatMul.r  r  a_is_sparser   b_is_sparser   ZReluGradFc                    sv   |    v r|   v sJ  |    } |   }|r#t|}d}tj| |||||d}|j|kr9t||}|S )z*Helper function to create SparseMatMul op.F)r  r  r  r  )refr	   rf   r   matmulr;   rM   )t1t2Z	out_dtyper  r  Z	t1_sparseZ	t2_sparserX   Z	is_sparser   r   _SparseMatMul  s"   

z(_SparseMatMulGrad.<locals>._SparseMatMulTr  r  r  N)FF)r   r"   r  r   r)   r   typer;   )r   r   r  r  r  Zdtype_aZdtype_br   r  r   _SparseMatMulGrad  sB   




r  ZFloorc                 C      d gS r   r   rh  r   r   r   
_FloorGrad     r  ZCeilc                 C   r  r   r   rh  r   r   r   	_CeilGrad  r  r  ZRoundc                 C   r  r   r   rh  r   r   r   
_RoundGrad!  r  r  ZRintc                 C   r  r   r   rh  r   r   r   	_RintGrad&  r   r  ZBatchMatMulc                 C   s   | j d }| j d }| d}| d}|sD|s.tj||ddd}tj||ddd}||fS tj||ddd}tj||ddd}||fS |s\tj||ddd}tj||ddd}||fS tj||ddd}tj||ddd}||fS )<Returns the gradient of x and y given the gradient of x * y.r   r   adj_xadj_yFTZ	adjoint_aZ	adjoint_b)r"   r   r   r  )r   r   r   r   r  r  grad_xgrad_yr   r   r   _BatchMatMul,  s&   



	r  ZBatchMatMulV2ZBatchMatMulV3c                 C   s  | j d }| j d }| d}| d}|s>|s+tj||ddd}tj||ddd}qetj||ddd}tj||ddd}n'|sStj||ddd}tj||ddd}ntj||ddd}tj||ddd}| }| }	|jdu p|jd	kp|	jdu p|	jd	k}
|dd
  o|	dd
  o|dd
 |	dd
 k}|
r|r||fS t|}t|}t	
|dd
 |dd
 \}}tt|||}tt|||}||fS )r  r   r   r  r  FTr  Nrx   r  )r"   r   r   r  	get_shaperH   Zis_fully_definedr	   r!   r
   r,   r#   rO   )r   r   r   r   r  r  r  r  Zshape_x_staticZshape_y_staticZ%output_may_have_non_empty_batch_shapeZbatch_shapes_matchr2   r3   r4   r5   r   r   r   _BatchMatMulV2F  sB   





 r  RangeZLinSpaceComplexc                 C   sl   | j d }| j d }t|}t|}t||\}}ttt|||ttt	|||fS )zBReturns the real and imaginary components of 'grad', respectively.r   r   )
r"   r	   r!   r
   r,   r#   r   rO   realimagr`  r   r   r   _ComplexGradx  s   



r  Realc                 C   s   t jd|jd}t||S )z=Returns 'grad' as the real part and set the imaginary part 0.r   r:   r   rC   r;   r   complexrk   r   zeror   r   r   	_RealGrad     r  ZImagc                 C   s   t jd|jd}t||S )z=Returns 'grad' as the imaginary part and set the real part 0.r   r:   r  r  r   r   r   	_ImagGrad  r  r  ZAnglec                 C   s   | j d }t|g. t|}t|}tt||}tj	d|j
d}t||}| | W  d   S 1 s<w   Y  dS )z Returns -grad / (Im(x) + iRe(x))r   r:   N)r"   r   r   r   r  r  r   r  r   rC   r;   )r   r   r   reZimrq  r  Zcomplex_gradr   r   r   
_AngleGrad  s   


$r  ZConjc                 C   s
   t |S )z&Returns the complex conjugate of grad.)r   rh   r   r   r   r   	_ConjGrad  rV   r  Z
ComplexAbsc              
   C   s>   t t |t|| jd  t | jd t| jd S )z#Returns the gradient of ComplexAbs.r   )r   rm  r  r	   r   r"   r   r   r   r   r   _ComplexAbsGrad  s   
r  ZCastc                 C   sR   t jt jt jt jt jt jg}| jd jj	}|jj	}||v r'||v r't
||S d S r   )r   Zfloat16r]  Zfloat64Zbfloat16Z	complex64Z
complex128r"   r;   r^  r   rM   )r   r   r=   Zsrc_typeZdst_typer   r   r   	_CastGrad  s   r  ZCrossc                 C   s,   | j d }| j d }t||t||fS rt  )r"   r   cross)r   r   uvr   r   r   
_CrossGrad  s   

r  ZCumsumc                 C   s6   | j d }| d}| d}tj|||| dd gS )Nr   rb   rc   rb   rc   )r"   r   r   cumsum)r   r   ra   rb   rc   r   r   r   _CumsumGrad  s   


r  ZCumprodc                 C   sb   | j d }| j d }| d}| d}tj||||d}tj|| ||| d}t||d gS )Nr   r   rb   rc   r  )r"   r   r   rg   r  rm  )r   r   r   ra   rb   rc   rX   ro   r   r   r   _CumprodGrad  s   



r  ZCumulativeLogsumexpc                 C   s   | j d }| j d }| jd }| d}| d}tt|dt||jj	}tt
|dt| |jj	}ttj|| || |d| }	ttj|| || |d| }
|	|
 d gS )Nr   r   rb   rc   )ra   rc   rb   )r"   r   r   r	   r   r   r   r  r;   minlessr   cumulative_logsumexp)r   r   r   ra   r  rb   rc   Zlog_grad_positiveZlog_grad_negativeZ
output_posZ
output_negr   r   r   _CumulativeLogsumexpGrad  s@   







r  Z	NextAfterc           
      C   s   | j d }| j d }t|}t|}t||\}}t|g0 tj||jd}tj	||jd}	t
t|| ||t
t|	| ||fW  d   S 1 sUw   Y  dS )z@Returns gradient of nextafter(x1, x2) with respect to x1 and x2.r   r   r:   N)r"   r	   r!   r
   r,   r   r   rr   r;   r   r#   r   rO   )
r   r   x1r   Zs_x1Zs_x2Zr_x1Zr_x2Z
partial_x1Z
partial_x2r   r   r   _NextAfterGrad  s    



$r  rg  )__doc__numpyrA   Ztensorflow.python.compatr   Ztensorflow.python.eagerr   Ztensorflow.python.frameworkr   r   r   r   r   Ztensorflow.python.opsr	   r
   r   r   r   r   ZRegisterGradientr   r   r'   r7   r8   r9   rL   rR   rU   rW   r`   rp   rq   rt   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   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-  r2  r3  r4  r9  r;  r=  r?  r@  rA  rB  rC  rF  rG  rI  rN  rO  rR  rX  rZ  r_  ra  rd  ri  rj  rk  rl  rn  rs  ry  rz  r|  r~  r  ZNotDifferentiabler  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   <module>   sB  


G
G



0










)#



/




	
	
	





	












	





	







	



	

























!
!
(






4

#

(



 
3





,






	





!