Expm1¶
Expm1 - 29¶
Version¶
name: Expm1 (GitHub)
domain:
mainsince_version:
29function:
Falsesupport_level:
SupportType.COMMONshape inference:
True
This version of the operator has been available since version 29.
Summary¶
Computes exp(x) - 1 element-wise, where exp is the exponential to base e.
The input may have any shape, including a scalar or an empty tensor. The output
has the same shape and element type as the input.
For finite nonzero x, the output is a floating-point approximation of the
real-valued function exp(x) - 1 at the exact value represented by x.
The computation must preserve nonzero results representable in the output type
when an intermediate floating-point exp(x) would round to 1. For example,
a FLOAT input 1e-8 produces a result approximately equal to 1e-8, rather
than zero.
Special values are defined element-wise as follows:
Input |
Output |
|---|---|
Positive zero |
Positive zero |
Negative zero |
Negative zero |
Negative infinity |
|
Positive infinity |
Positive infinity |
NaN |
NaN |
The sign and payload of an output NaN are unspecified. Finite positive inputs whose results overflow the output type produce positive infinity.
Inputs¶
input (heterogeneous) - T:
Input tensor
Outputs¶
output (heterogeneous) - T:
The exponential of the input minus one, computed element-wise
Type Constraints¶
T in (
tensor(bfloat16),tensor(double),tensor(float),tensor(float16)):Constrain input and output types to float tensors.
Examples¶
_expm1¶
import numpy as np
import onnx
node = onnx.helper.make_node("Expm1", ["x"], ["y"])
for dtype in [np.float16, ml_dtypes.bfloat16, np.float32, np.float64]:
x = np.array([[-10.0, -0.5, 0.0, 0.25], [0.5, 1.0, 3.0, 5.0]], dtype=dtype)
y = np.array([math.expm1(float(v)) for v in x.flat], dtype=dtype).reshape(
x.shape
)
expect(
node,
inputs=[x],
outputs=[y],
name=f"test_expm1_{np.dtype(dtype).name}",
rtol=1e-2 if dtype == ml_dtypes.bfloat16 else 1e-3,
)
_expm1_small_inputs¶
import numpy as np
import onnx
node = onnx.helper.make_node("Expm1", ["x"], ["y"])
for dtype, tiny in [
(np.float16, 2.0**-14),
(ml_dtypes.bfloat16, 2.0**-10),
(np.float32, 1e-8),
(np.float64, 1e-20),
]:
x = np.array([-tiny, -0.0, 0.0, tiny], dtype=dtype)
y = np.array([math.expm1(float(v)) for v in x], dtype=dtype)
# Relative error allows backend variation, while atol=0 catches
# an incorrect zero caused by rounding the intermediate exp(x).
expect(
node,
inputs=[x],
outputs=[y],
name=f"test_expm1_small_inputs_{np.dtype(dtype).name}",
rtol=1e-2 if dtype == ml_dtypes.bfloat16 else 1e-3,
atol=0,
)
_expm1_special_values¶
import numpy as np
import onnx
node = onnx.helper.make_node("Expm1", ["x"], ["y"])
for dtype in [np.float16, ml_dtypes.bfloat16, np.float32, np.float64]:
x = np.array([-0.0, 0.0, -np.inf, np.inf, np.nan], dtype=dtype)
y = np.array([-0.0, 0.0, -1.0, np.inf, np.nan], dtype=dtype)
expect(
node,
inputs=[x],
outputs=[y],
name=f"test_expm1_special_values_{np.dtype(dtype).name}",
)
_expm1_scalar_and_empty¶
import numpy as np
import onnx
node = onnx.helper.make_node("Expm1", ["x"], ["y"])
expect(
node,
inputs=[np.array(1.0, dtype=np.float32)],
outputs=[np.array(math.expm1(1), dtype=np.float32)],
name="test_expm1_scalar",
)
x = np.empty((0, 3), dtype=np.float32)
expect(node, inputs=[x], outputs=[x], name="test_expm1_empty")