@@ -1874,10 +1874,9 @@ public extension Tensor where Scalar: TensorFlowFloatingPoint {
1874
1874
standardDeviation ( squeezingAxes: axes)
1875
1875
}
1876
1876
1877
- /// Returns the standard deviation of the elements along the specified axes. The reduced
1878
- /// dimensions are retained with value `1`. Does not apply Bessel's correction.
1877
+ /// Returns the standard deviation of all elements in this tensor.
1878
+ /// Does not apply Bessel's correction.
1879
1879
///
1880
- /// - Parameter axes: The dimensions to reduce.
1881
1880
/// - Precondition: Each value in `axes` must be in the range `-rank..<rank`.
1882
1881
@inlinable
1883
1882
@differentiable ( wrt: self )
@@ -1920,6 +1919,123 @@ public extension Tensor where Scalar: TensorFlowFloatingPoint {
1920
1919
func standardDeviation( alongAxes axes: Int ... ) -> Tensor {
1921
1920
TensorFlow . sqrt ( variance ( alongAxes: axes) )
1922
1921
}
1922
+
1923
+ /// Returns `log(exp(self).sum(squeezingAxes: axes))`. The reduced dimensions are removed.
1924
+ ///
1925
+ /// This function is more numerically stable than computing
1926
+ /// `log(exp(self).sum(squeezingAxes: axes))` directly. It avoids overflows caused by computing
1927
+ /// the `exp` of large inputs and underflows caused by computing the `log` of small inputs.
1928
+ ///
1929
+ /// - Parameter axes: The dimensions to reduce.
1930
+ /// - Precondition: Each value in `axes` must be in the range `-rank..<rank`.
1931
+ @inlinable
1932
+ @differentiable ( wrt: self )
1933
+ func logSumExp( squeezingAxes axes: Tensor < Int32 > ) -> Tensor {
1934
+ let rawMax = max ( alongAxes: axes)
1935
+ let offset = Swift . withoutDerivative ( at: rawMax) { rawMax in
1936
+ rawMax. replacing (
1937
+ with: Tensor < Scalar > ( zerosLike: rawMax) ,
1938
+ where: rawMax. isFinite)
1939
+ }
1940
+ let result = TensorFlow . log ( TensorFlow . exp ( self - offset) . sum ( squeezingAxes: axes) )
1941
+ let resultShape = Swift . withoutDerivative ( at: result. shapeTensor, in: identity)
1942
+ return result + offset. reshaped ( toShape: resultShape)
1943
+ }
1944
+
1945
+ /// Returns `log(exp(self).sum(squeezingAxes: axes))`. The reduced dimensions are removed.
1946
+ ///
1947
+ /// This function is more numerically stable than computing
1948
+ /// `log(exp(self).sum(squeezingAxes: axes))` directly. It avoids overflows caused by computing
1949
+ /// the `exp` of large inputs and underflows caused by computing the `log` of small inputs.
1950
+ ///
1951
+ /// - Parameter axes: The dimensions to reduce.
1952
+ /// - Precondition: Each value in `axes` must be in the range `-rank..<rank`.
1953
+ @inlinable
1954
+ @differentiable ( wrt: self )
1955
+ func logSumExp( squeezingAxes axes: [ Int ] ) -> Tensor {
1956
+ // TODO(TF-433): Remove workaround for differentiating `map`.
1957
+ let axes = Swift . withoutDerivative ( at: axes) { $0. map ( Int32 . init) }
1958
+ return logSumExp ( squeezingAxes: Tensor < Int32 > ( axes) )
1959
+ }
1960
+
1961
+ /// Returns `log(exp(self).sum(squeezingAxes: axes))`. The reduced dimensions are removed.
1962
+ ///
1963
+ /// This function is more numerically stable than computing
1964
+ /// `log(exp(self).sum(squeezingAxes: axes))` directly. It avoids overflows caused by computing
1965
+ /// the `exp` of large inputs and underflows caused by computing the `log` of small inputs.
1966
+ ///
1967
+ /// - Parameter axes: The dimensions to reduce.
1968
+ /// - Precondition: Each value in `axes` must be in the range `-rank..<rank`.
1969
+ @inlinable
1970
+ @differentiable ( wrt: self )
1971
+ func logSumExp( squeezingAxes axes: Int ... ) -> Tensor {
1972
+ return logSumExp ( squeezingAxes: axes)
1973
+ }
1974
+
1975
+ /// Returns `log(exp(self).sum())`. The result is a scalar.
1976
+ ///
1977
+ /// This function is more numerically stable than computing `log(exp(self).sum())` directly. It
1978
+ /// avoids overflows caused by computing the `exp` of large inputs and underflows caused by
1979
+ /// computing the `log` of small inputs.
1980
+ @inlinable
1981
+ @differentiable ( wrt: self )
1982
+ func logSumExp( ) -> Tensor {
1983
+ return logSumExp ( squeezingAxes: Array ( 0 ..< shape. rank) )
1984
+ }
1985
+
1986
+ /// Returns `log(exp(self).sum(alongAxes: axes))`. The reduced dimensions are retained with
1987
+ /// value `1`.
1988
+ ///
1989
+ /// This function is more numerically stable than computing
1990
+ /// `log(exp(self).sum(alongAxes: axes))` directly. It avoids overflows caused by computing
1991
+ /// the `exp` of large inputs and underflows caused by computing the `log` of small inputs.
1992
+ ///
1993
+ /// - Parameter axes: The dimensions to reduce.
1994
+ /// - Precondition: Each value in `axes` must be in the range `-rank..<rank`.
1995
+ @inlinable
1996
+ @differentiable ( wrt: self )
1997
+ func logSumExp( alongAxes axes: Tensor < Int32 > ) -> Tensor {
1998
+ let rawMax = max ( alongAxes: axes)
1999
+ let offset = Swift . withoutDerivative ( at: rawMax) { rawMax in
2000
+ rawMax. replacing (
2001
+ with: Tensor < Scalar > ( zerosLike: rawMax) ,
2002
+ where: rawMax. isFinite)
2003
+ }
2004
+ let result = TensorFlow . log ( TensorFlow . exp ( self - offset) . sum ( alongAxes: axes) )
2005
+ return result + offset
2006
+ }
2007
+
2008
+ /// Returns `log(exp(self).sum(alongAxes: axes))`. The reduced dimensions are retained with
2009
+ /// value `1`.
2010
+ ///
2011
+ /// This function is more numerically stable than computing
2012
+ /// `log(exp(self).sum(alongAxes: axes))` directly. It avoids overflows caused by computing
2013
+ /// the `exp` of large inputs and underflows caused by computing the `log` of small inputs.
2014
+ ///
2015
+ /// - Parameter axes: The dimensions to reduce.
2016
+ /// - Precondition: Each value in `axes` must be in the range `-rank..<rank`.
2017
+ @inlinable
2018
+ @differentiable ( wrt: self )
2019
+ func logSumExp( alongAxes axes: [ Int ] ) -> Tensor {
2020
+ // TODO(TF-433): Remove workaround for differentiating `map`.
2021
+ let axes = Swift . withoutDerivative ( at: axes) { $0. map ( Int32 . init) }
2022
+ return logSumExp ( alongAxes: Tensor < Int32 > ( axes) )
2023
+ }
2024
+
2025
+ /// Returns `log(exp(self).sum(alongAxes: axes))`. The reduced dimensions are retained with
2026
+ /// value `1`.
2027
+ ///
2028
+ /// This function is more numerically stable than computing
2029
+ /// `log(exp(self).sum(alongAxes: axes))` directly. It avoids overflows caused by computing
2030
+ /// the `exp` of large inputs and underflows caused by computing the `log` of small inputs.
2031
+ ///
2032
+ /// - Parameter axes: The dimensions to reduce.
2033
+ /// - Precondition: Each value in `axes` must be in the range `-rank..<rank`.
2034
+ @inlinable
2035
+ @differentiable ( wrt: self )
2036
+ func logSumExp( alongAxes axes: Int ... ) -> Tensor {
2037
+ return logSumExp ( alongAxes: axes)
2038
+ }
1923
2039
}
1924
2040
1925
2041
//===------------------------------------------------------------------------------------------===//
0 commit comments