
    AVhA                     v   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 g dZ	 ej                  dej                        Z ej                  d	ej                        Z ej                  d
ej                        Z ej                  dej                        ZddZd ZddZd ZddZd Zd ZddZd ZddZy)zSpecial Math Ops.    N)constant_op)ops)	array_ops)math_ops)erfinvndtrndtrilog_ndtrlog_cdf_laplaceii      c                 >   t        j                  || g      5  t        j                  | d      } | j                  j                  t
        j                  t
        j                  fvrt        d| j                  z        t        |       cddd       S # 1 sw Y   yxY w)aG  Normal distribution function.

  Returns the area under the Gaussian probability density function, integrated
  from minus infinity to x:

  ```
                    1       / x
     ndtr(x)  = ----------  |    exp(-0.5 t**2) dt
                sqrt(2 pi)  /-inf

              = 0.5 (1 + erf(x / sqrt(2)))
              = 0.5 erfc(x / sqrt(2))
  ```

  Args:
    x: `Tensor` of type `float32`, `float64`.
    name: Python string. A name for the operation (default="ndtr").

  Returns:
    ndtr: `Tensor` with `dtype=x.dtype`.

  Raises:
    TypeError: if `x` is not floating-type.
  valuesxname=x.dtype=%s is not handled, see docstring for supported types.N)
r   
name_scopeconvert_to_tensordtypeas_numpy_dtypenpfloat32float64	TypeError_ndtrr   r   s     `/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/distributions/special_math.pyr   r   k   s    4 ~~dA3' ac*Awwbjj"**%==
IGG  8     A0BBc                    t        j                  dt        j                  d      z  | j                  d      }| |z  }t        j                  |      }t        j                  t        j                  ||      dt        j                  |      z   t        j                  t        j                  |d      dt        j                  |      z
  t        j                  |                  }d|z  S )zImplements ndtr core logic.      ?       @half_sqrt_2)r   r         ?        )r   constantr   sqrtr   r   absr   where_v2lesserfgreatererfc)r   r$   wzys        r   r   r      s    $$	BGGBKqww]<++o!ll1o!mmA{#R(,,q/%9


1b
!2a(8#8(--:JLM! 
q.    c                 >   t        j                  || g      5  t        j                  | d      } | j                  j                  t
        j                  t
        j                  fvrt        d| j                  z        t        |       cddd       S # 1 sw Y   yxY w)a  The inverse of the CDF of the Normal distribution function.

  Returns x such that the area under the pdf from minus infinity to x is equal
  to p.

  A piece-wise rational approximation is done for the function.
  This is a port of the implementation in netlib.

  Args:
    p: `Tensor` of type `float32`, `float64`.
    name: Python string. A name for the operation (default="ndtri").

  Returns:
    x: `Tensor` with `dtype=p.dtype`.

  Raises:
    TypeError: if `p` is not floating-type.
  r   pr   z=p.dtype=%s is not handled, see docstring for supported types.N)
r   r   r   r   r   r   r   r   r   _ndtri)r4   r   s     r   r	   r	      s    ( ~~dA3' ac*Awwbjj"**%==
IGG  !9  r    c           
      (   g d}g d}g d}g d}g d}g d}fdt        j                  | t        j                  d       kD  d	| z
  |       }t        j                  |d
k  t        j                  t        j
                  |       t        j                  d| j                  j                              |      }|dz
  }	|	dz  }
|	|	|
z   |
|       |
|      z  z  z   }|t        j                  dt        j                  z         z  }t        j                  dt        j                  |      z        }|t        j                  |      |z  z
  } d	|z  |       d	|z  |      z  |z  } d	|z  |       d	|z  |      z  |z  }||z
  }||z
  }t        j                  |t        j                  d      kD  |t        j                  |dk\  ||            }t        j                  | d	t        j                  d      z
  kD  ||       }t        j                  t        j                   | j                        }t        j                  t        j
                  |       |      }t        j                  | d
k  | t        j                  | d	k\  ||            }|S )zImplements ndtri core logic.)g~g;+@gVLgX@g-^OM)	gͿgcu/@gٷaTgSi@g_6V.lgԁ5U@g@gt ҕE?r%   )	glLgAcgwDglz9~@g>F^-@gN
F@gBהL@gyՒm?@gێ<8@)	g}yNgmENg23¿g <	@gE؇.@gF"D@go)F@g;Z/@r%   )	gX0:>g4"L)L>g3?gM5iPV?gQ&^E?gT?g+@gx'1@gtՓ	@)	g=kv)=>gC>g)e+5?gǶ'|?g<_?g b*G?g8ҪMp@g(V@r%   c                     t        j                  || j                  j                        }|j                  st        j                  |       S |d    | |dd       | z  z   S )z2Compute n_th order polynomial via Horner's method.r      N)r   arrayr   r   sizer   
zeros_like)varcoeffs_create_polynomials     r   r>   z"_ndtri.<locals>._create_polynomial   sW    XXfcii667F;;!!#&&!9)#vabz:S@@@r2   g       r%   r&   r"      r#   g       @)r   )r   r*   r   expm1fillshaper9   r   r   r(   pir   logexpr   r'   inf)r4   p0q0p1q1p2q2maybe_complement_psanitized_mcpr/   wwx_for_big_pr0   
first_termsecond_term_small_psecond_term_otherwisex_for_small_px_otherwiser   infinity_scalarinfinityx_nan_replacedr>   s                         @r   r5   r5      s   "
"""""A !))!rxx}n*<b1faH $$BnnY__Q'#qww7M7M)NO- c!Av"AF0R8 22r :; < <+"''"ruu*%%%+
 mmC(,,}556!8<<?Q&&*a$a$%'()  a$a$%'()  22-22+bffSk!;c=+>@! R"&&+--q1"5!((qww?/^^IOOA.@(%%a3h	&/&8&8c8Q&OQ.	r2   c                 \   t        |t              st        d      |dk  rt        d      |dkD  rt        d      t	        j
                  || g      5  t	        j                  | d      } | j                  j                  t        j                  k(  rt        }t        }nL| j                  j                  t        j                  k(  rt        }t        }nt        d	| j                  z        t!        j"                  t%        j&                  | |      t)        |         t!        j"                  t%        j&                  | |      t%        j*                  t)        t%        j,                  | |                  t/        t%        j0                  | |      |                  cd
d
d
       S # 1 sw Y   y
xY w)a  Log Normal distribution function.

  For details of the Normal distribution function see `ndtr`.

  This function calculates `(log o ndtr)(x)` by either calling `log(ndtr(x))` or
  using an asymptotic series. Specifically:
  - For `x > upper_segment`, use the approximation `-ndtr(-x)` based on
    `log(1-x) ~= -x, x << 1`.
  - For `lower_segment < x <= upper_segment`, use the existing `ndtr` technique
    and take a log.
  - For `x <= lower_segment`, we use the series approximation of erf to compute
    the log CDF directly.

  The `lower_segment` is set based on the precision of the input:

  ```
  lower_segment = { -20,  x.dtype=float64
                  { -10,  x.dtype=float32
  upper_segment = {   8,  x.dtype=float64
                  {   5,  x.dtype=float32
  ```

  When `x < lower_segment`, the `ndtr` asymptotic series approximation is:

  ```
     ndtr(x) = scale * (1 + sum) + R_N
     scale   = exp(-0.5 x**2) / (-x sqrt(2 pi))
     sum     = Sum{(-1)^n (2n-1)!! / (x**2)^n, n=1:N}
     R_N     = O(exp(-0.5 x**2) (2N+1)!! / |x|^{2N+3})
  ```

  where `(2n-1)!! = (2n-1) (2n-3) (2n-5) ...  (3) (1)` is a
  [double-factorial](https://en.wikipedia.org/wiki/Double_factorial).


  Args:
    x: `Tensor` of type `float32`, `float64`.
    series_order: Positive Python `integer`. Maximum depth to
      evaluate the asymptotic expansion. This is the `N` above.
    name: Python string. A name for the operation (default="log_ndtr").

  Returns:
    log_ndtr: `Tensor` with `dtype=x.dtype`.

  Raises:
    TypeError: if `x.dtype` is not handled.
    TypeError: if `series_order` is a not Python `integer.`
    ValueError:  if `series_order` is not in `[0, 30]`.
  z&series_order must be a Python integer.r   z"series_order must be non-negative.   zseries_order must be <= 30.r   r   r   zx.dtype=%s is not supported.N)
isinstanceintr   
ValueErrorr   r   r   r   r   r   r   LOGNDTR_FLOAT64_LOWERLOGNDTR_FLOAT64_UPPERr   LOGNDTR_FLOAT32_LOWERLOGNDTR_FLOAT32_UPPERr   r*   r   r-   r   rD   maximum_log_ndtr_lowerminimum)r   series_orderr   lower_segmentupper_segments        r   r
   r
     sS   d 
L#	&
<
==A
9
::B
2
33
~~dA3'  Pac*Aww++m+m	
		2::	-+m+m4qww>??  M*	r
Q.LLx//=ABCH,,Q>M	OP5 P  P  Ps   EF""F+c                     t        j                  |       }d|z  t        j                  |        z
  dt        j                  dt        j                  z        z  z
  }|t        j                  t        | |            z   S )zGAsymptotic expansion version of `Log[cdf(x)]`, appropriate for `x<<-1`.      r"   r#   )r   squarerD   r   rC   _log_ndtr_asymptotic_series)r   re   x_2	log_scales       r   rc   rc   r  s`    #Sj8<<++cBFF2:4F.FF)	X\\"=a"NO	OOr2   c                    | j                   j                  }|dk  rt        j                  d|      S t	        j
                  |       }t        j                  |       }t        j                  |       }|}t        d|dz         D ]?  }t        j                  t        d|z  dz
        |      |z  }|dz  r||z  }n||z  }||z  }A d|z   |z
  S )z2Calculates the asymptotic series used in log_ndtr.r   r8   r?   r%   )
r   r   r   r9   r   rj   r   r;   range_double_factorial)	r   re   r   rl   even_sumodd_sumx_2nnr1   s	            r   rk   rk   z  s    
''
 
 %Q88Au#!!!$(  #'	$L1$% a
"1q519-u5<A1ulg!mhCKD 
h	  r2   c                 v   t        j                  || g      5  t        j                  | d      } | j                  j                  t
        j                  t
        j                  fvrt        d| j                  z        t        | dz   dz        t        j                  d      z  cddd       S # 1 sw Y   yxY w)	a  The inverse function for erf, the error function.

  Args:
    x: `Tensor` of type `float32`, `float64`.
    name: Python string. A name for the operation (default="erfinv").

  Returns:
    x: `Tensor` with `dtype=x.dtype`.

  Raises:
    TypeError: if `x` is not floating-type.
  r   r   r   r   r%   r#   r?   N)r   r   r   r   r   r   r   r   r   r	   r(   r   s     r   r   r     s     ~~dA3' /ac*Awwbjj"**%==
IGG  !c'S!BGGAJ./ / /s   BB//B8c                 V    t        j                  t        j                  | dd            S )z;The double factorial function for small Python integer `n`.r8   )r   prodarange)rt   s    r   rp   rp     s    	1a$	%%r2   c                 t   t        j                  || g      5  t        j                  | d      } t        j                  d       | z   }t        j                  t        j                  |              }t        j                  d|z        }t        j                  | dk  ||      cddd       S # 1 sw Y   yxY w)a  Log Laplace distribution function.

  This function calculates `Log[L(x)]`, where `L(x)` is the cumulative
  distribution function of the Laplace distribution, i.e.

  ```L(x) := 0.5 * int_{-infty}^x e^{-|t|} dt```

  For numerical accuracy, `L(x)` is computed in different ways depending on `x`,

  ```
  x <= 0:
    Log[L(x)] = Log[0.5] + x, which is exact

  0 < x:
    Log[L(x)] = Log[1 - 0.5 * e^{-x}], which is exact
  ```

  Args:
    x: `Tensor` of type `float32`, `float64`.
    name: Python string. A name for the operation (default="log_ndtr").

  Returns:
    `Tensor` with `dtype=x.dtype`.

  Raises:
    TypeError: if `x.dtype` is not handled.
  r   r   r   r#   ri   r&   N)r   r   r   r   rD   r   rE   r)   log1pr   r*   )r   r   lower_solutionsafe_exp_neg_xupper_solutions        r   r   r     s    : ~~dA3' Fac*A ffRj[1_N \\8<<?"23N ^^D>$9:Na"fnnE!F F Fs   BB..B7)r   )r	   )   r
   )r   )r   )__doc__numpyr   tensorflow.python.frameworkr   r   tensorflow.python.opsr   r   __all__r9   r   r^   r   r`   r_   ra   r   r   r	   r5   r
   rc   rk   r   rp   r    r2   r   <module>r      s   N   3 + + *  !bjj1  bjj1  !BJJ/  BJJ/  F
:[|YPxP!&/.&
-Fr2   