o
    Ô2úh° ã                   @   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lmZ e d¡dejfdd„ƒZe d¡dejfdd„ƒZe d¡dejfdd„ƒZd³dd„Zdd„ Zdd„ Zd d!„ Zd"Zd#d$„ Zd%d&„ Z e d'¡dejfd(d)„ƒZ!dejfd*d+„Z"e d,¡dejfd-d.„ƒZ#e d/¡dejfd0d1„ƒZ$e d2¡dejfd3d4„ƒZ%e d5¡dejfd6d7„ƒZ&e d8¡dejfd9d:„ƒZ'e d;¡dejfd<d=„ƒZ(d³d>d?„Z)d@dA„ Z*e dB¡dejfdCdD„ƒZ+e dE¡dejfdFdG„ƒZ,e dH¡dejfdIdJ„ƒZ-e dK¡dejfdLdM„ƒZ.e dN¡dejfdOdP„ƒZ/e dQ¡dejfdRdS„ƒZ0dejfdTdU„Z1e dV¡dejfdWdX„ƒZ2e dY¡dejfdZd[„ƒZ3e d\¡dejfd]d^„ƒZ4		d´d_d`„Z5dejfdadb„Z6e dc¡dejfddde„ƒZ7e df¡dejfdgdh„ƒZ8e di¡dejfdjdk„ƒZ9e dl¡dejfdmdn„ƒZ:e do¡dejfdpdq„ƒZ;e dr¡dsdt„ ƒZ<e du¡dejfdvdw„ƒZ=e dx¡dejfdydz„ƒZ>e d{¡dejfd|d}„ƒZ?e d~¡dejfdd€„ƒZ@e d¡dejfd‚dƒ„ƒZAe d„¡dejfd…d†„ƒZBe d‡¡dejfdˆd‰„ƒZCe dŠ¡dejfd‹dŒ„ƒZDe d¡dejfdŽd„ƒZEe d¡dejfd‘d’„ƒZFe d“¡dejfd”d•„ƒZGe d–¡dejfd—d˜„ƒZHe d™¡dejfdšd›„ƒZIe dœ¡dejfddž„ƒZJe dŸ¡dejfd d¡„ƒZKe d¢¡dejfd£d¤„ƒZLe d¥¡dejfd¦d§„ƒZMe d¨¡dejfd©dª„ƒZNe d«¡dejfd¬d­„ƒZOe d®¡dejfd¯d°„ƒZPe d±¡dejfd²d³„ƒZQe d´¡dejfdµd¶„ƒZRe d·¡dejfd¸d¹„ƒZSe dº¡dejfd»d¼„ƒZTe d½¡dejfd¾d¿„ƒZUe dÀ¡dejfdÁdÂ„ƒZVe dÃ¡dejfdÄdÅ„ƒZWe dÆ¡dejfdÇdÈ„ƒZXe dÉ¡dejfdÊdË„ƒZYe dÌ¡dejfdÍdÎ„ƒZZe dÏ¡dejfdÐdÑ„ƒZ[e dÒ¡dejfdÓdÔ„ƒZ\e dÕ¡dejfdÖd×„ƒZ]e dØ¡dejfdÙdÚ„ƒZ^e dÛ¡dejfdÜdÝ„ƒZ_e dÞ¡dejfdßdà„ƒZ`e dá¡dejfdâdã„ƒZae dä¡dejfdådæ„ƒZbe dç¡dejfdèdé„ƒZce dê¡dejfdëdì„ƒZde dí¡dejfdîdï„ƒZee dð¡dejfdñdò„ƒZfe dó¡dejfdôdõ„ƒZge dö¡dejfd÷dø„ƒZhe dù¡dejfdúdû„ƒZie dü¡dejfdýdþ„ƒZje dÿ¡dejfd d„ƒZke d¡dejfdd„ƒZle d¡dejfdd„ƒZme d¡dejfd	d
„ƒZne d¡dejfdd„ƒZoe d¡dejfdd„ƒZpe d¡dejfdd„ƒZqe d¡dejfdd„ƒZre d¡dejfdd„ƒZse d¡dejfdd„ƒZte d¡dejfdd„ƒZue d ¡dejfd!d"„ƒZve d#¡dejfd$d%„ƒZwe d&¡dejfd'd(„ƒZxe d)¡dejfd*d+„ƒZye d,¡dejfd-d.„ƒZzd/d0„ Z{e d1¡e d2¡dejfd3d4„ƒƒZ|e d5¡dejfd6d7„ƒZ}e d8¡dejfd9d:„ƒZ~e d;¡dejfd<d=„ƒZe d>¡dejfd?d@„ƒZ€e dA¡dBdC„ ƒZe dD¡dejfdEdF„ƒZ‚e dG¡dHdI„ ƒZƒe dJ¡dejfdKdL„ƒZ„e dM¡dejfdNdO„ƒZ…e dP¡dejfdQdR„ƒZ†dejfdSdT„Z‡dejfdUdV„Zˆe dW¡dejfdXdY„ƒZ‰e dZ¡dejfd[d\„ƒZŠe d]¡dejfd^d_„ƒZ‹e Œd`¡ e Œda¡ e Œdb¡ e Œdc¡ e Œdd¡ e Œde¡ e Œdf¡ e Œdg¡ e Œdh¡ e Œdi¡ e dj¡dejfdkdl„ƒZe dm¡dejfdndo„ƒZŽdejfdpdq„Zdejfdrds„Ze dt¡dejfdudv„ƒZ‘e dw¡dejfdxdy„ƒZ’e dz¡d{d|„ ƒZ“e d}¡d~d„ ƒZ”e d€¡dd‚„ ƒZ•e dƒ¡d„d…„ ƒZ–e d†¡dejfd‡dˆ„ƒZ—e d‰¡e dŠ¡dejfd‹dŒ„ƒƒZ˜e Œd¡ e ŒdŽ¡ e d¡dejfdd‘„ƒZ™e d’¡d“d”„ ƒZše d•¡d–d—„ ƒZ›e d˜¡dejfd™dš„ƒZœe d›¡dœd„ ƒZe dž¡dejfdŸd „ƒZže d¡¡dejfd¢d£„ƒZŸe d¤¡dejfd¥d¦„ƒZ e d§¡dejfd¨d©„ƒZ¡e dª¡dejfd«d¬„ƒZ¢e d­¡dejfd®d¯„ƒZ£e d°¡dejfd±d²„ƒZ¤dS (µ  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                 C   ó   ~ ~d d gS ©N© ©r   Úgradr   r   úZ/var/www/html/chatgem/venv/lib/python3.10/site-packages/tensorflow/python/ops/math_grad.pyÚ_ArgMaxGrad!   ó   r   ÚArgMinc                 C   r   r   r   r   r   r   r   Ú_ArgMinGrad'   r   r   Ú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_dimsé   N)	ÚoutputsÚget_attrr   Úreduced_shaper
   ÚshapeÚinputsÚreshapeÚtruediv)r   r   ÚoutputÚoutput_shape_kept_dimsr   r   r   Ú_EuclideanNormGrad-   s   

ÿr'   c           	      C   s¸   ~t  | ¡}t  |¡}t ¡ s%t| tjƒr%t|tjƒr%t| j|jƒ\}}nd\}}|du s1|du r>t 	||¡\}}d}d}n|pG| jj
|jj
k }|pQ|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.
  ©NNNT)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_reducer   r   r   ÚSmartBroadcastGradientArgs<   s"   


ÿ
þr7   c           
      C   sæ   | j }|j }|du s|du rdS |  ¡ } | ¡ }t||ƒ}g }g }t|ƒD ]I}||| k r/dn| |||   }||| k r?dn||||   }	|dkrU|	dkrU| |¡ q%|	dkrc|dkrc| |¡ q%|du sk|	du rn dS q%||fS )z9Infers the sets of axes that might have been broadcasted.Nr(   r   )r.   Úas_listÚmaxÚrangeÚappend)
r1   r2   Úx_rankÚy_rankÚb_rankr3   r4   ÚaxisÚx_dimÚy_dimr   r   r   r,   a   s(   
  þr,   c                 C   s6   |\}}}| dur|rt j| |dd} t | |¡} | S )zFReduces gradients of one of the arguments of a broadcasting binary op.NT)Úkeepdims)r   Ú
reduce_sumr
   r#   )r   Úshape_axes_must_reducer!   ÚaxesÚmust_reducer   r   r   Ú_ReduceGradientArg   s
   
rG   c                 C   s:   |dus|durt | |ƒ\}}t||ƒ}t||ƒ}||fS )z@Reduces gradients of both arguments of a broadcasting binary op.N)r7   rG   )r/   r0   ÚgxÚgyÚbxÚbyr   r   r   Ú_ReduceGradientArgs‹   s
   

rL   r   c                 C   s   |   ¡ tu S r   )Ú_shape_tupleÚ_EMPTY_TUPLE)r/   r   r   r   Ú	_IsScalar—   s   rO   c                 C   s   | t  |d¡ S )z;Divides `x / y` assuming `x, y >= 0`, treating `0 / 0 = 0`.r   )r   Úmaximum)r/   r0   r   r   r   Ú_SafeShapeDiv›   s   rQ   ÚSumc                 C   sü  | j d  ¡ }|durÅt | j d ¡}|durÅt|ƒ}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rÅt 	¡ sÅt ¡ }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¡söt |¡ t || j d ¡}	W d  ƒ n1 sëw   Y  t ||	¡}t ||¡dgS )	zGradient for Sum.r   Nr   ©Údtypeéÿÿÿÿc                 S   s4   t  | ¡rt  | ¡}|d usJ ‚t|ƒS | }t|ƒS r   )r	   Ú
is_tf_typeÚtry_evaluate_constantÚtuple)ÚtÚvaluer   r   r   ÚEvaluateAsTupleÊ   s   

ÿz!_SumGrad.<locals>.EvaluateAsTupler   ) r"   rM   r	   Úconstant_valueÚlenÚnpÚarray_equalÚaranger   r)   Úones_rank_cacheÚgetr   Úconstantr   Úint32Úputr
   r#   r!   Útiler   Úget_default_graphrX   Ú_reduced_shape_cacheÚKeyErrorr   r    rQ   r   Úcolocate_withÚbroadcast_to)r   r   Úinput_0_shaperE   r.   ÚctxÚ	new_shapeÚinput_shapeÚgraphr&   Útile_scalingr[   r   r   r   Ú_SumGrad    s`   €
ÿ
ÿÿÿñ
ÿýrr   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ÚequalrT   rC   Údivide)r   r   ro   r0   r&   Ú
indicatorsÚnum_selectedr   r   r   Ú_MinOrMaxGradè   s   


ÿrx   ÚMaxc                 C   ó
   t | |ƒS )zGradient for Max.©rx   r   r   r   r   Ú_MaxGradý   ó   
r|   ÚMinc                 C   rz   r   r{   r   r   r   r   Ú_MinGrad  s   
r   Ú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
 |¡}t | jd |j	¡}	|	| | }	t t
 ||	¡¡}t |t ||j	¡¡dfS )zGradient for Mean.r   Nr   rS   )rr   r"   rM   r   r^   Úprodr9   r   rc   rT   r
   r!   Úsizer   rs   Úreduce_prodÚgatherr$   )
r   r   Úsum_gradro   Úoutput_shapeÚ
input_sizeÚoutput_sizeÚfactorÚ
input_rankrE   r   r   r   Ú	_MeanGrad  s   


r‹   Ú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 ||j¡}|| | }t d|¡}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   rU   r   z/cpu:0NT)r?   Ú	exclusive)r?   r   Úreverse)r
   r!   r"   r#   r   r   r    rk   r   Údevicer.   rs   rT   r:   r   Ú	list_diffÚconcatrƒ   r„   Ú	transposeÚcumprodÚconjÚinvert_permutation)r   r   ro   Úreduction_indicesr&   r.   ÚreducedÚidxÚotherÚ_ÚpermÚreduced_numÚ	other_numÚpermutedÚpermuted_shapeÚreshapedÚleftÚrightr0   Úoutr   r   r   Ú	_ProdGrad  s4   
ø	
ÿr¤   Ú
SegmentSumc                 C   s   t  || jd ¡dfS )zGradient for SegmentSum.r   N)r
   r„   r"   r   r   r   r   Ú_SegmentSumGradN  s   r¦   ÚSegmentMeanc                 C   sŒ   t  | jd ¡}t  | jd ¡}t jt  |d d¡|jd}t  ||gd¡}t j||jd}t 	|t 
|| jd ¡¡}t  || jd ¡dfS )zGradient for SegmentMean.r   r   rS   N)r
   r.   r"   r!   ÚonesÚexpand_dimsrT   r‘   r   ru   Úsegment_sumr„   )r   r   Ú	data_rankÚsegment_ids_shapeÚremaining_shapeÚ
ones_shaper¨   Úscaled_gradr   r   r   Ú_SegmentMeanGradT  s   ÿr°   c           
      C   sŽ   |du s|dks|dksJ ‚| j d }| j d }t | j d ¡}|d }|dkr,tj}n|dkr4tj}ntj}|||||ƒ\}}	t ||	|¡S )zCSparse gradient for SparseSegment(Sum|Mean|SqrtN)[WithNumSegments].NÚ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_indicesr   r   r   Ú_SparseSegmentReduceGradV2b  s    

ÿÿrÁ   c                 C   s"   z|   |¡W S  ty   Y dS w )zbReturns the value of the attr of `op` with the given `name`, or None if no

  such attr exists.
  N)r   Ú
ValueError)r   Únamer   r   r   Ú_GetOpAttrOrNonew  s
   ÿrÄ   ÚSparseSegmentSumc                 C   s†   t | dƒrt| |ƒddfS 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.Úsparse_gradientNr   éå  é   é
   r   r³   ©rÄ   rÁ   r
   r!   r"   r   Úforward_compatibler   Úsparse_segment_sum_gradÚunsorted_segment_sumr„   ©r   r   Údim0r   r   r   Ú_SparseSegmentSumGrad‚  s   
ÿÿÿÿrÐ   ÚSparseSegmentSumWithNumSegmentsc                 C   sŒ   t | dƒrt| |ƒdddfS t | jd ¡d }t ddd¡r1t || 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Æ   Nr   rÇ   rÈ   rÉ   r   r³   rÊ   rÎ   r   r   r   Ú$_SparseSegmentSumWithNumSegmentsGrad  s   
ÿÿþþrÒ   ÚSparseSegmentMeanc                 C   óR   t | dƒrt| |dƒddfS t | jd ¡d }t || 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Î   r   r   r   Ú_SparseSegmentMeanGradŸ  ó   
ÿÿr×   Ú SparseSegmentMeanWithNumSegmentsc                 C   óV   t | dƒrt| |dƒdddfS t | jd ¡d }t || jd | jd |¡dddfS )z.Gradient for SparseSegmentMeanWithNumSegments.rÆ   r±   Nr   r   r³   rÕ   rÎ   r   r   r   Ú%_SparseSegmentMeanWithNumSegmentsGrad©  ó   
ÿÿrÛ   ÚSparseSegmentSqrtNc                 C   rÔ   )z Gradient for SparseSegmentSqrtN.rÆ   r²   Nr   r   r³   ©rÄ   rÁ   r
   r!   r"   r   Úsparse_segment_sqrt_n_gradrÎ   r   r   r   Ú_SparseSegmentSqrtNGrad³  rØ   rà   Ú!SparseSegmentSqrtNWithNumSegmentsc                 C   rÚ   )z/Gradient for SparseSegmentSqrtNWithNumSegments.rÆ   r²   Nr   r   r³   rÞ   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   rS   r   N)r
   Ú
zeros_liker"   rT   r„   r   r   rt   rª   rs   ru   Úwhere_v2)r   r   ÚzerosÚgathered_outputsÚis_selectedrw   Úweighted_gradsÚgathered_gradsr   r   r   Ú_SegmentMinOrMaxGradÇ  s   ÿrê   Ú
SegmentMinc                 C   rz   )zGradient for SegmentMin.©rê   r   r   r   r   Ú_SegmentMinGradÖ  r}   rí   Ú
SegmentMaxc                 C   rz   )zGradient for SegmentMax.rì   r   r   r   r   Ú_SegmentMaxGradÜ  r}   rï   Ú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   rS   N)r"   r   rt   r   rª   rs   r   rd   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_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   rS   )r?   )r   rP   r
   rã   r„   Úgreater_equalr!   r‘   r¨   r.   rT   r#   rò   r   Úboolrä   )ÚparamsÚidsÚzero_clipped_indicesÚis_positiveÚgatheredÚis_positive_shapeÚbroadcastable_shapeÚ
zero_slicer   r   r   Ú_GatherDropNegatives  s,   
þþø

ý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 )z7Gradient for UnsortedSegmentMin and UnsortedSegmentMax.r   r   r³   N)r	  r   r"   r   rt   Úlogical_andrÍ   rs   rT   ru   r
   rã   rä   )r   r   ræ   r  r  rç   rw   rè   ré   rš   rå   r   r   r   Ú_UnsortedSegmentMinOrMaxGrad4  s   
ÿÿ
ÿ
r  ÚUnsortedSegmentSumc                 C   s   t || jd ƒd ddfS )z Gradient for UnsortedSegmentSum.r   r   N)r	  r"   r   r   r   r   Ú_UnsortedSegmentSumGradI  s   r  ÚUnsortedSegmentMaxc                 C   rz   )z" Gradient for UnsortedSegmentMax. ©r  r   r   r   r   Ú_UnsortedSegmentMaxGradO  r}   r  ÚUnsortedSegmentMinc                 C   rz   )z" Gradient for UnsortedSegmentMin. r  r   r   r   r   Ú_UnsortedSegmentMinGradU  r}   r  Ú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   rS   r   r³   N)r   rt   r"   r   rÍ   rs   r   rd   r
   rä   rñ   rã   rò   Úunsorted_segment_prodrP   r„   r   r	  )r   r   rõ   rö   r÷   rø   r  rù   rú   rû   rü   rý   r   r   r   Ú_UnsortedSegmentProdGrad[  s8   ÿÿÿÿÿÿÿÿr  ÚAbsc                 C   s   | j d }|t |¡ S ©Nr   )r"   r   Úsign©r   r   r/   r   r   r   Ú_AbsGrad‹  s   
r  ÚNegc                 C   s   | S )zReturns -grad.r   ©rš   r   r   r   r   Ú_NegGrad‘  ó   r  ÚInvc                 C   ó   | j d }t ||¡S ©zReturns -grad * (1 / x^2).r   ©r   r   Úreciprocal_grad©r   r   r0   r   r   r   Ú_InvGrad—  ó   
r%  Ú
Reciprocalc                 C   r   r!  r"  r$  r   r   r   Ú_ReciprocalGradž  r&  r(  Ú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   r”   r   r#  ©r   r   ÚbÚcaÚcgr   r   r   Ú_InvGradGrad¥  ó   

$ýr3  ÚReciprocalGradc                 C   r*  r+  r-  r/  r   r   r   Ú_ReciprocalGradGrad¯  r4  r6  Ú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   ç       @rS   )	r"   r   r.  r   r”   r   rc   rT   Úmultiply©r   r   r/   r0   r   r   r   Ú_SquareGrad¹  s   

$ýr;  ÚSqrtc                 C   r   r  )r   r   Ú	sqrt_gradr$  r   r   r   Ú	_SqrtGradÃ  s   
r>  Ú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   r”   )r   r   Úar0   Úgar   r   r   Ú_SqrtGradGradÉ  s   

$þrC  ÚRsqrtc                 C   r   )z Returns -0.5 * grad * conj(y)^3.r   )r   r   Ú
rsqrt_gradr$  r   r   r   Ú
_RsqrtGradÒ  r&  rF  Ú	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   r”   Úsquarer   rE  )r   r   rA  r0  r1  r2  Úgrad_aÚgrad_br   r   r   Ú_RsqrtGradGradÙ  s   



$ûrK  Ú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   r”   r$  r   r   r   Ú_ExpGradæ  ó
   

$þrN  ÚExpm1c                 C   sV   | j d }t |g¡ t |¡}t |¡}|| W  d  ƒ S 1 s$w   Y  dS rM  )r"   r   r.  r   r”   Úexpr:  r   r   r   Ú
_Expm1Gradï  s   


$ýrR  Ú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   r”   Ú
reciprocalr  r   r   r   Ú_LogGradù  ó
   

$þrW  Ú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   NrU  r  r   r   r   Ú
_Log1pGrad  s
   

$þrZ  Ú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   ç        rS   N)r"   r
   r!   r   r-   r   r.  r   rs   Ú	not_equalrT   r   ÚxlogyÚxdivyr#   rC   ©r   r   r/   r0   ÚsxÚsyÚrxÚryÚ
not_zero_xÚ	partial_xÚ	partial_yr   r   r   Ú
_XLogyGrad  s   



ÿÿ$ûrh  Ú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\  rS   ç      ð?N)r"   r
   r!   r   r-   r   r.  r   rs   r]  rT   r   Úxlog1pyr_  r#   rC   r`  r   r   r   Ú_XLog1pyGrad  s   



ÿÿ$ûrl  Ú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\  rS   r³   N)r"   r
   r!   r   r-   r   r.  r   rs   r]  rT   r   r_  Únegativer#   rC   r`  r   r   r   Ú
_XDivyGrad-  s   



ÿÿ$ûro  ÚSinhc                 C   rT  )zReturns grad * cosh(x).r   N)r"   r   r.  r   r”   Úcoshr  r   r   r   Ú	_SinhGrad>  rX  rr  ÚCoshc                 C   rT  )zReturns grad * sinh(x).r   N)r"   r   r.  r   r”   Úsinhr  r   r   r   Ú	_CoshGradG  rX  ru  Ú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   r”   r   Ú	tanh_gradr$  r   r   r   Ú	_TanhGradP  ó
   


$þry  Ú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   r”   rq  r$  r   r   r   Ú
_AsinhGradY  rX  r}  ÚAcoshc                 C   r|  )zReturns grad * 1/sinh(y).r   N)r   r   r.  r   r”   rt  r$  r   r   r   Ú
_AcoshGradb  rX  r  Ú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   rS   N)r"   r   r.  r   r”   rH  r   rc   rT   rV  Úsubtract©r   r   r/   Úx2ÚoneÚinvr   r   r   Ú
_AtanhGradk  ó   


$ûr‡  Ú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   r”   r"   r   rx  )r   r   rA  r0  r   r   r   Ú_TanhGradGradw  s
   $ýrŠ  Ú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   r³   rS   N©r"   r   rc   r^   ÚsqrtÚpirT   r   r.  r   r”   rQ  rH  )r   r   r/   Útwo_over_root_pir   r   r   Ú_ErfGrad  s   

$þr‘  ÚErfcc                 C   rŒ  )z(Returns -grad * 2/sqrt(pi) * exp(-x**2).r   éþÿÿÿrS   Nr  )r   r   r/   Úminus_two_over_root_pir   r   r   Ú	_ErfcGrad‰  s   
ÿ
$þr•  Ú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).r³   rS   r   N©r   rc   r^   rŽ  r  rT   r   r.  r   rQ  rH  r   )r   r   Úroot_pi_over_twor   r   r   Ú_ErfinvGrad”  s   
ÿ$ÿr™  Ú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).r³   rS   r   r8  Nr—  )r   r   Úroot_two_pir   r   r   Ú
_NdtriGrad  s   
ÿ$ÿrœ  ÚLgammac                 C   rT  )zReturns grad * digamma(x).r   N)r"   r   r.  r   r”   Údigammar  r   r   r   Ú_LgammaGrad¦  rX  rŸ  Ú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   rS   N)	r"   r   r.  r   r”   Ú	polygammar
   rc   rT   ©r   r   r/   rf  r   r   r   Ú_DigammaGrad¯  s   

$ýr£  Ú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   rj  r³   N)r"   r   r   r.  r:  r   r   r   Ú
_DawsnGrad¹  s
   

$ÿr¥  Ú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   rQ  r  r   r   r   Ú_ExpintGradÂ  s   
$ÿr§  Ú
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   r8  N)r"   r   r.  r   Úcosr^   r  rH  r  r   r   r   Ú_FresnelCosGradÊ  ó   
$ÿr«  Ú
FresnelSinc                 C   r©  )z@Compute gradient of fresnel_sin(x) with respect to its argument.r   r8  N)r"   r   r.  r   Úsinr^   r  rH  r  r   r   r   Ú_FresnelSinGradÒ  r¬  r¯  Ú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   rj  N)	r"   r   r.  r   Úlogr
   Úwherert   rò   r¢  r   r   r   Ú_SpenceGradÚ  s   
ÿ$ür³  Ú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   Ú	bessel_i1r¢  r   r   r   Ú_BesselI0Gradå  rO  r¶  Ú	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   Ú
bessel_i1er   r  ©r   r   r/   r0   rf  r   r   r   Ú_BesselI0eGradî  s   

$þrº  Ú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\  rj  N)r"   r   r   r.  r
   rä   r   rt   rs   rT   r   Ú	bessel_i0Údiv©r   r   r/   r0   Údy_dxr   r   r   Ú_BesselI1Gradø  ó   

þ$÷rÁ  Ú	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   rt   rs   rT   r   Ú
bessel_i0er  rV  r¿  r   r   r   Ú_BesselI1eGrad	  s   


ÿþ$örÅ  Ú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   Ú	bessel_k1r¢  r   r   r   Ú_BesselK0Grad  ó
   
$þrÉ  Ú	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   Ú
bessel_k1er¹  r   r   r   Ú_BesselK0eGrad$  s   

$þrÍ  Ú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   Ú	bessel_k0r   r¾  r¹  r   r   r   Ú_BesselK1Grad.  s   

$ürÐ  Ú	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   rj  N)r"   r   r   r.  r   rV  r   Ú
bessel_k0er¹  r   r   r   Ú_BesselK1eGrad:  s   

ÿ$ûrÓ  ÚBesselJ0c                 C   rÇ  )z>Compute gradient of bessel_j0(x) with respect to its argument.r   N)r"   r   r.  r   Ú	bessel_j1r¢  r   r   r   Ú_BesselJ0GradG  rÊ  rÖ  Ú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   rt   rs   rT   r   Ú	bessel_j0r¾  r¿  r   r   r   Ú_BesselJ1GradP  rÂ  rÙ  ÚBesselY0c                 C   rÇ  )z>Compute gradient of bessel_y0(x) with respect to its argument.r   N)r"   r   r.  r   Ú	bessel_y1r¢  r   r   r   Ú_BesselY0Grada  rÊ  rÜ  Ú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   Ú	bessel_y0r   r¾  r¹  r   r   r   Ú_BesselY1Gradj  s   

$ürß  Ú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   rQ  r±  Úlgammar#   rC   )
r   r   rA  r/   Úsara  Úrarc  Ú	partial_arf  r   r   r   Ú_IgammaGradv  s   



ÿÿ$úræ  ÚIgammacc                 C   s   t | |ƒ\}}| | fS )zDReturns gradient of igammac(a, x) = 1 - igamma(a, x) w.r.t. a and x.)ræ  )r   r   rá  Úigamma_grad_xr   r   r   Ú_IgammacGrad‰  s   ré  Ú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   rQ  rk  r^  r#   rC   )r   r   rA  r0  r/   rã  ra  rš   rc  Úlog_betarf  r   r   r   Ú_BetaincGrad  s"   

ÿÿÿÿýrì  Ú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   r”   Úzetar#   rC   )	r   r   r/   Úqra  ÚsqÚ	unused_rxÚrqÚ	partial_qr   r   r   Ú	_ZetaGrad¬  s   





ÿ$ürô  Ú	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   r”   r¡  r#   rC   )	r   r   Únr/   Úsnra  Ú	unused_rnrc  rf  r   r   r   Ú_PolygammaGrad¿  s   





ÿ$ürù  ÚSigmoidc                 C   rw  )z-Returns grad * sigmoid(x) * (1 - sigmoid(x)).r   N)r   r   r.  r   r”   r   Úsigmoid_gradr$  r   r   r   Ú_SigmoidGradÒ  rz  rü  ÚSigmoidGradc                 C   st   t  |g¡* t | jd ¡}t | jd ¡}|| }|d| |  t ||¡fW  d   ƒ S 1 s3w   Y  d S )Nr   r   r8  )r   r.  r   r”   r"   r   rû  )r   r   rA  r0  Úgbr   r   r   Ú_SigmoidGradGradÛ  s   $ürÿ  ÚSignc                 C   s   | j d }t |¡S )z
Returns 0.r   )r"   r
   rã   )r   rš   r/   r   r   r   Ú	_SignGradä  s   

r  ÚSinc                 C   rT  )zReturns grad * cos(x).r   N)r"   r   r.  r   r”   rª  r  r   r   r   Ú_SinGradë  rX  r  Ú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   r”   r®  r  r   r   r   Ú_CosGradô  s
   

$þr  Ú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   r”   rV  rª  rH  )r   r   r/   ÚsecxÚsecx2r   r   r   Ú_TanGradý  s   


$ür	  Ú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   rS   N©r"   r   r.  r   r”   rH  r   rc   rT   rŽ  r‚  rV  ©r   r   r/   r„  r…  Údenr†  r   r   r   Ú	_AsinGrad  s   



$úr  Ú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   rS   Nr  r  r   r   r   Ú	_AcosGrad  s   



$úr  ÚAtanc                 C   r  )zReturns grad * 1/ (1 + x^2).r   r   rS   N)r"   r   r.  r   r”   rH  r   rc   rT   rV  Úaddrƒ  r   r   r   Ú	_AtanGrad"  rˆ  r  ÚAtan2c                 C   s|   | j d }| j d }t |g¡$ |t |¡t |¡  }|| }| | }t||||ƒW  d  ƒ S 1 s7w   Y  dS )z8Returns grad * x / (y^2 + x^2), grad * -y / (y^2 + x^2).r   r   N)r"   r   r.  r   rH  rL   )r   r   r0   r/   Úgrad_invrI   rH   r   r   r   Ú
_Atan2Grad.  s   


$ûr  ÚAddNc                 C   s   |gt | jƒ S )z"Copies the gradient to all inputs.)r]   r"   r   r   r   r   Ú	_AddNGrad<  s   r  c                 C   s8   |   ¡ }|  ¡ }|  ¡ }||ko||ko|d uod |vS r   )rM   )r/   r0   r   r1   r2   Ú
grad_shaper   r   r   Ú_ShapesFullySpecifiedAndEqualC  s   ÿÿr  ÚAddÚAddV2c                 C   s¢   | j d }z| jp
d}d|v rt|ƒr|dfW S W n ty$   d}Y nw | j d }t|tjƒr:t|||ƒr:||fS d|v r@dn|}d|v rHdn|}t||||ƒS )zGradient for Add.r   r   Nr   ©	r"   Úskip_input_indicesrO   ÚAttributeErrorr*   r   r+   r  rL   ©r   r   r0   r  r/   rH   rI   r   r   r   Ú_AddGradM  s"   


€þ
ÿr!  ÚSubc                 C   s¦   | j d }z| jp
d}d|v rt|ƒr|dfW S W n ty$   d}Y nw | j d }t|tjƒr;t|||ƒr;|| fS d|v rAdn|}d|v rIdn| }t||||ƒS )zGradient for Sub.r   r   Nr   r  r   r   r   r   Ú_SubGrade  s"   


€þ
ÿ
r#  ÚMulc                 C   s  | j d }z| jp
d}d|v rt|ƒrt |t |¡¡dfW S W n ty+   d}Y nw | j d }t|t	j
ƒrRt|||ƒrR|jtjtjfv rRt ||¡t ||¡fS |jj|jjkscJ |jd|jfƒ‚d|v rjd}n	t |t |¡¡}d|v rzd}n	t t |¡|¡}t||||ƒS )z&The gradient of scalar multiplication.r   r   Nr   ú vs. )r"   r  rO   r   Úmulr   r”   r  r*   r   r+   r  rT   r   rd   Úfloat32Ú
base_dtyperL   r   r   r   r   Ú_MulGrad|  s0   

€þ

ÿ
þ"r)  Ú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	||||ƒS )z;The gradient of scalar multiplication with NaN-suppression.r   r   r%  )
r"   r*   r   r+   r  r   Ú
mul_no_nanrT   r(  rL   ©r   r   r/   r0   rH   rI   r   r   r   Ú_MulNoNanGradž  s   

ÿ"r-  ÚDivc                 C   s\   | j d }| j d }t |¡}t |¡}t ||¡}|t t | |¡|¡ }t||||ƒS )z"The gradient for the Div operator.r   r   )r"   r   r”   ru   rL   ©r   r   r/   r0   ÚcxÚcyrH   rI   r   r   r   Ú_DivGrad®  s   



r2  ÚFloorDivc                 C   ó   dS )z'The gradient for the FloorDiv operator.r(   r   ©rš   Úunused_gradr   r   r   Ú_FloorDivGradº  s   r7  ÚFloorModc                 C   sL   t  | jd ¡}t  | jd ¡}t  ||¡}|}|t  |¡ }t||||ƒS )z Returns grad * (1, -floor(x/y)).r   r   )r   r”   r"   Ú	floor_divrn  rL   )r   r   r/   r0   Úfloor_xyrH   rI   r   r   r   Ú_FloorModGradÀ  s   r;  ÚTruncateDivc                 C   r4  )Nr(   r   r5  r   r   r   Ú_TruncateDivGradË  s   r=  ÚRealDivc                 C   sh   | j d }| j d }t | j d ¡}t | j d ¡}t ||¡}|t t | |¡|¡ }t||||ƒS )zRealDiv op gradient.r   r   )r"   r   r”   ÚrealdivrL   r/  r   r   r   Ú_RealDivGradÐ  s   

r@  ÚDivNoNanc                 C   sT   t  | jd ¡}t  | jd ¡}t  ||¡}|t  t  | |¡|¡ }t||||ƒS )zDivNoNan op gradient.r   r   )r   r”   r"   Ú
div_no_nanrL   r,  r   r   r   Ú_DivNoNanGradÜ  s
   rC  ÚPowc                 C   s"  | j d }| j d }t |¡}t |¡}z| jpd}d|v r1t|ƒr1|| t ||d ¡ dfW S W n ty=   d}Y nw d|v rEd}n|| t ||d ¡ }d|v rXd}n2|jjrct 	|d¡}	n|dk}	t
 |	|t
 |¡¡}
t
 |	t |
¡t
 |¡¡}|t | jd ¡ | }t||||ƒS )z%Returns grad * (y*x^(y-1), z*log(x)).r   r   r   N)r"   r   r”   r  rO   Úpowr  rT   Ú
is_complexr]  r
   r²  rò   r±  rã   r   rL   )r   r   r/   r0   r0  r1  r  rH   rI   ÚmaskÚsafe_xÚlog_xr   r   r   Ú_PowGradæ  s0   




€þrJ  c           	      C   sB   | j d }| j d }t |¡}|||ƒ}t |||¡}d }||fS ©Nr   r   )r"   r
   rã   rä   )	r   r   Úselector_opr/   r0   rå   ÚxmaskÚxgradÚygradr   r   r   Ú_MaximumMinimumGradInputOnly  s   



rP  c           
      C   s²   | j d }z| jp
d}d|v rt|ƒrt| ||ƒW S W n ty&   d}Y nw | j d }t |¡}|||ƒ}d|v r=d}nt |||¡}d|v rKd}	nt |||¡}	t||||	ƒS )z;Factor out the code for the gradient of Maximum or Minimum.r   r   r   N)	r"   r  rO   rP  r  r
   rã   rä   rL   )
r   r   rL  r0   r  r/   rå   rM  rH   rI   r   r   r   Ú_MaximumMinimumGrad  s&   

€þ


rQ  ÚMaximumc                 C   ó   t | |tjƒS )z/Returns grad*(x >= y, x < y) with type of grad.)rQ  r   rÿ   r   r   r   r   Ú_MaximumGrad/  ó   rT  ÚMinimumc                 C   rS  )z/Returns grad*(x <= y, x > y) with type of grad.)rQ  r   Ú
less_equalr   r   r   r   Ú_MinimumGrad5  rU  rX  ÚSquaredDifferencec                 C   sÌ   | j d }| j d }z| jpd}W n ty   d}Y nw t |g¡ t d|¡||  }W d  ƒ n1 s8w   Y  t|tj	ƒrNt
|||ƒrN|| fS d|v rTdn|}d|v r\dn| }t||||ƒS )z!Returns the gradient for (x-y)^2.r   r   r   r8  N)r"   r  r  r   r.  r   Ú
scalar_mulr*   r   r+   r  rL   )r   r   r/   r0   r  Úx_gradrH   rI   r   r   r   Ú_SquaredDifferenceGrad;  s"   

þýÿ
r\  ÚLessÚ	LessEqualÚGreaterÚGreaterEqualÚEqualÚApproximateEqualÚNotEqualÚ
LogicalAndÚ	LogicalOrÚ
LogicalNotÚSelectc                 C   s<   | j d }| j d }t |¡}d t |||¡t |||¡fS rK  )r"   r
   rã   r²  )r   r   Úcr/   rå   r   r   r   Ú_SelectGradb  s   


ýri  ÚSelectV2c           
      C   s„   | j d }| j d }| j d }| jd }tjg |jjd}t |||¡}t |||¡}t|||d ƒ\}}	t|||d ƒ\}}	d ||fS )Nr   r   r³   rS   )r"   r   r
   rå   rT   r(  rä   rL   )
r   r   rh  r/   r0   Úzrå   rH   rI   rš   r   r   r   Ú_SelectGradV2n  s   




rl  c                 C   s¬   |   d¡}|   d¡}t | jd ¡}|s#|s#tj||ddd}|dfS |s3|r3tj||dd}|dfS |rD|sDtj||ddd}|dfS |rR|rRtj||dddd}|dfS )	z.Gradient for MatMul, only for the first input.Útranspose_aÚtranspose_br   T©rn  rI  ©rI  ©rm  rn  rI  N©r   r   r”   r"   r   Úmat_mul)r   r   Út_aÚt_br0  rI  r   r   r   Ú_MatMulGradAgainstFirstOnly|  s"   

	øúü
ÿrv  c                 C   s¬   |   d¡}|   d¡}t | jd ¡}|s#|s#tj||ddd}d|fS |s4|r4tj||ddd}d|fS |rD|sDtj||dd}d|fS |rR|rRtj||dddd}d|fS )	z/Gradient for MatMul, only for the second input.rm  rn  r   T©rm  rJ  ©rJ  ©rm  rn  rJ  Nrr  )r   r   rt  ru  rA  rJ  r   r   r   Ú_MatMulGradAgainstSecondOnlyŽ  s"   

	øúü
ÿrz  ÚMatMulc           	      C   sR  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 ¡}|s[|s[tj	||ddd}tj	||ddd}||fS |st|rttj	||dd	}tj	||ddd}||fS |r|stj	||ddd}tj	||dd
}||fS |r¥|r¥tj	||dddd}tj	||dddd}||fS )zGradient for MatMul.Nr   r   rm  rn  Tro  rw  rp  rx  rq  ry  )
r  rv  rz  r  r   r   r”   r"   r   rs  )	r   r   r  rt  ru  rA  r0  rI  rJ  r   r   r   Ú_MatMulGrad   sF   €þ

óöù
ÿ
ÿr|  Ú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.rm  rn  Úa_is_sparser   Úb_is_sparser   Ú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)rm  rn  r~  r  )Úrefr
   r’   r   ÚmatmulrT   rs   )Út1Út2Ú	out_dtyperm  rn  Ú	t1_sparseÚ	t2_sparser   ©Ú	is_sparser   r   Ú_SparseMatMulÒ  s"   
ú
z(_SparseMatMulGrad.<locals>._SparseMatMulT)rn  )rm  )rm  rn  N)FF)r   r"   r  r   r)   r   ÚtyperT   )r   r   rt  ru  rŠ  Údtype_aÚdtype_br   rˆ  r   Ú_SparseMatMulGradÅ  sB   




ÿÿÿÿÿþþÿrŽ  ÚFloorc                 C   ó   d gS r   r   r5  r   r   r   Ú
_FloorGradù  ó   r‘  ÚCeilc                 C   r  r   r   r5  r   r   r   Ú	_CeilGradþ  r’  r”  ÚRoundc                 C   r  r   r   r5  r   r   r   Ú
_RoundGrad  r’  r–  ÚRintc                 C   r  r   r   r5  r   r   r   Ú	_RintGrad  r  r˜  Ú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)Ú	adjoint_aÚ	adjoint_b)r"   r   r   r‚  )r   r   r/   r0   r›  rœ  Úgrad_xÚgrad_yr   r   r   Ú_BatchMatMul  s&   



ö	ùýr¡  ÚBatchMatMulV2ÚBatchMatMulV3c                 C   s¾  | j d }| j d }|  d¡}|  d¡}|sB|s-tj||dddd}tj||dddd}n@tj||dddd}tj||dddd}n+|sYtj||dddd}tj||dddd}ntj||dddd}tj||d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œ  FT)r  rž  rI  )r  rž  rJ  Nr³   r“  )r"   r   r   r‚  Ú	get_shaper.   Úis_fully_definedr
   r!   r   r-   r#   rC   )r   r   r/   r0   r›  rœ  rŸ  r   Úshape_x_staticÚshape_y_staticÚ%output_may_have_non_empty_batch_shapeÚbatch_shapes_matchra  rb  rc  rd  r   r   r   Ú_BatchMatMulV2(  sb   




ÿ
ÿ
ÿ
ÿ
ÿ
ÿ
ÿ
ÿþÿý

 rª  ÚRangeÚLinSpaceÚComplexc                 C   s6   | j d }| j d }t |¡}t |¡}t||||ƒS )zBReturns the real and imaginary components of 'grad', respectively.r   r   )r"   r   ÚrealÚimagrL   r,  r   r   r   Ú_ComplexGradj  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   rS   ©r   rc   rT   r   Úcomplex©rš   r   Úzeror   r   r   Ú	_RealGradt  ó   r¶  ÚImagc                 C   s   t jd|jd}t ||¡S )z=Returns 'grad' as the imaginary part and set the real part 0.r   rS   r²  r´  r   r   r   Ú	_ImagGrad{  r·  r¹  Ú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) + i Re(x))`.r   rS   N)r"   r   r.  r   r®  r¯  rV  r³  r   rc   rT   )r   r   r/   ÚreÚimrk  rµ  Úcomplex_gradr   r   r   Ú
_AngleGrad‚  s   


$úr¾  ÚConjc                 C   s
   t  |¡S )z&Returns the complex conjugate of grad.)r   r”   r  r   r   r   Ú	_ConjGrad  r}   rÀ  Ú
ComplexAbsc              
   C   s>   t  t  |t |¡¡| jd  t  | jd t | jd ¡¡¡S )z#Returns the gradient of ComplexAbs.r   )r   rB  r³  r
   rã   r"   r   r   r   r   r   Ú_ComplexAbsGrad•  s   
ÿÿÿýrÂ  Ú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   Úfloat16r'  Úfloat64Úbfloat16Ú	complex64Ú
complex128r"   rT   r(  r   rs   )r   r   rY   Úsrc_typeÚdst_typer   r   r   Ú	_CastGradŸ  s   þrË  ÚCrossc                 C   s,   | j d }| j d }t ||¡t ||¡fS rK  )r"   r   Úcross)r   r   ÚuÚvr   r   r   Ú
_CrossGrad­  s   

rÐ  ÚCumsumc                 C   s6   | j d }|  d¡}|  d¡}tj|||| dd gS )Nr   r   rŽ   ©r   rŽ   )r"   r   r   Úcumsum)r   r   r?   r   rŽ   r   r   r   Ú_CumsumGrad´  s   


þrÔ  ÚCumprodc                 C   sb   | j d }| j d }|  d¡}|  d¡}tj||||d}tj|| ||| d}t ||¡d gS )Nr   r   r   rŽ   rÒ  )r"   r   r   r“   rÓ  rB  )r   r   r/   r?   r   rŽ   r   r£   r   r   r   Ú_CumprodGrad¿  s   



ÿrÖ  Ú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   r   rŽ   )r?   rŽ   r   )r"   r   r   r
   rä   r   rñ   r±  rT   ÚminÚlessrQ  Úcumulative_logsumexp)r   r   r/   r?   rÚ  r   rŽ   Úlog_grad_positiveÚlog_grad_negativeÚ
output_posÚ
output_negr   r   r   Ú_CumulativeLogsumexpGradÎ  s@   





ý

ýþþÿþþÿrß  Ú	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   rS   N)r"   r
   r!   r   r-   r   r.  r¨   rT   rå   r#   r   rC   )
r   r   Úx1r„  Ús_x1Ús_x2Úr_x1Úr_x2Ú
partial_x1Ú
partial_x2r   r   r   Ú_NextAfterGradð  s    



ÿÿþ$ýrè  r   r(   )¥Ú__doc__Únumpyr^   Ú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'   r7   r,   rG   rL   rN   rO   rQ   rr   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  r  r%  r(  r3  r6  r;  r>  rC  rF  rK  rN  rR  rW  rZ  rh  rl  ro  rr  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  r  r	  r  r  r  r  r  r  r!  r#  r)  r-  r2  r7  r;  r=  r@  rC  rJ  rP  rQ  rT  rX  r\  ÚNotDifferentiableri  rl  rv  rz  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>   sN  %	G0				)ý)/
					
	
		





















!







	$







$
3





<

	




	





!