| 1698 | } |
| 1699 | |
| 1700 | XlaOp RegularizedIncompleteBeta(XlaOp a, XlaOp b, XlaOp x) { |
| 1701 | auto& builder = *x.builder(); |
| 1702 | return builder.ReportErrorOrReturn([&]() -> StatusOr<XlaOp> { |
| 1703 | TF_ASSIGN_OR_RETURN(Shape shape, builder.GetShape(a)); |
| 1704 | TF_ASSIGN_OR_RETURN(Shape b_shape, builder.GetShape(b)); |
| 1705 | TF_ASSIGN_OR_RETURN(Shape x_shape, builder.GetShape(x)); |
| 1706 | if (b_shape.element_type() != shape.element_type() || |
| 1707 | x_shape.element_type() != shape.element_type()) { |
| 1708 | return InvalidArgument( |
| 1709 | "Operands to RegularizedIncompleteBeta must have identical types, " |
| 1710 | "got shapes %s, %s, and %s", |
| 1711 | shape.ToString(), b_shape.ToString(), x_shape.ToString()); |
| 1712 | } |
| 1713 | if (!primitive_util::IsFloatingPointType(shape.element_type())) { |
| 1714 | return InvalidArgument( |
| 1715 | "Operands to RegularizedIncompleteBeta must be real-valued " |
| 1716 | "floating-point, but got %s", |
| 1717 | PrimitiveType_Name(shape.element_type())); |
| 1718 | } |
| 1719 | PrimitiveType element_type = shape.element_type(); |
| 1720 | if (element_type == F16 || element_type == BF16) { |
| 1721 | element_type = F32; |
| 1722 | a = ConvertElementType(a, F32); |
| 1723 | b = ConvertElementType(b, F32); |
| 1724 | x = ConvertElementType(x, F32); |
| 1725 | } |
| 1726 | |
| 1727 | // The partial numerator for the incomplete beta function is given |
| 1728 | // here: http://dlmf.nist.gov/8.17.E23 Note that there is a special |
| 1729 | // case: the partial numerator for the first iteration is one. |
| 1730 | auto NthPartialBetaincNumerator = |
| 1731 | [&](XlaOp iteration, absl::Span<const XlaOp> inputs, |
| 1732 | XlaBuilder* builder) -> StatusOr<std::vector<XlaOp>> { |
| 1733 | auto a = inputs[0]; |
| 1734 | auto b = inputs[1]; |
| 1735 | auto x = inputs[2]; |
| 1736 | auto iteration_bcast = Broadcast(iteration, shape.dimensions()); |
| 1737 | auto iteration_is_even = |
| 1738 | Eq(iteration_bcast % FullLike(iteration_bcast, 2), |
| 1739 | FullLike(iteration_bcast, 0)); |
| 1740 | auto iteration_is_one = Eq(iteration_bcast, FullLike(iteration_bcast, 1)); |
| 1741 | auto iteration_minus_one = iteration_bcast - FullLike(iteration_bcast, 1); |
| 1742 | auto m = iteration_minus_one / FullLike(iteration_minus_one, 2); |
| 1743 | m = ConvertElementType(m, element_type); |
| 1744 | auto one = FullLike(a, 1.0); |
| 1745 | auto two = FullLike(a, 2.0); |
| 1746 | // Partial numerator terms. |
| 1747 | auto even_numerator = |
| 1748 | -(a + m) * (a + b + m) * x / ((a + two * m) * (a + two * m + one)); |
| 1749 | auto odd_numerator = |
| 1750 | m * (b - m) * x / ((a + two * m - one) * (a + two * m)); |
| 1751 | auto one_numerator = ScalarLike(x, 1.0); |
| 1752 | auto numerator = Select(iteration_is_even, even_numerator, odd_numerator); |
| 1753 | return std::vector<XlaOp>{ |
| 1754 | Select(iteration_is_one, one_numerator, numerator)}; |
| 1755 | }; |
| 1756 | |
| 1757 | auto NthPartialBetaincDenominator = |
nothing calls this directly
no test coverage detected