Skip to content

Commit

Permalink
Add Presto inverse_laplace_cdf function (facebookincubator#9491)
Browse files Browse the repository at this point in the history
Summary:
Resolves facebookincubator#5541
This is a followup for facebookincubator#5543

Pull Request resolved: facebookincubator#9491

Reviewed By: kagamiori, mbasmanova

Differential Revision: D59768749

Pulled By: pedroerp

fbshipit-source-id: 25b1e038570bf67e556df33db7ddcf7a1d4e0054
  • Loading branch information
wills-feng authored and facebook-github-bot committed Jul 16, 2024
1 parent fe03c36 commit 0adc62e
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 2 deletions.
10 changes: 8 additions & 2 deletions velox/docs/functions/presto/math.rst
Original file line number Diff line number Diff line change
Expand Up @@ -349,8 +349,14 @@ Probability Functions: inverse_cdf

.. function:: inverse_cauchy_cdf(median, scale, p) -> double

Compute the inverse of the Cauchy cdf with given parameters ``median`` and ``scale`` (gamma) for the probability p.
The scale parameter must be a positive double. The probability ``p`` must be a double on the interval [0, 1].
Compute the inverse of the Cauchy cdf with given parameters ``median`` and ``scale`` (gamma) for the probability p.
The scale parameter must be a positive double. The probability ``p`` must be a double on the interval [0, 1].

.. function:: inverse_laplace_cdf(mean, scale, p) -> double

Compute the inverse of the Laplace cdf with given ``mean`` and ``scale`` parameters for the cumulative probability (p): P(N < n).
The mean must be a real value and the scale must be a positive real value (both of type DOUBLE).
The probability ``p`` must lie on the interval [0, 1].

====================================
Statistical Functions
Expand Down
17 changes: 17 additions & 0 deletions velox/functions/prestosql/Probability.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,5 +312,22 @@ struct InverseCauchyCDFFunction {
}
};

template <typename T>
struct InverseLaplaceCDFFunction {
VELOX_DEFINE_FUNCTION_TYPES(T);
FOLLY_ALWAYS_INLINE void
call(double& result, double location, double scale, double p) {
VELOX_USER_CHECK_GT(scale, 0, "scale must be greater than 0");
VELOX_USER_CHECK(p >= 0 && p <= 1, "p must be in the interval [0, 1]")

if (std::isnan(location) || std::isinf(location)) {
result = std::numeric_limits<double>::quiet_NaN();
} else {
boost::math::laplace_distribution<> laplaceDist(location, scale);
result = boost::math::quantile(laplaceDist, p);
}
}
};

} // namespace
} // namespace facebook::velox::functions
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ void registerProbTrigFunctions(const std::string& prefix) {
{prefix + "inverse_weibull_cdf"});
registerFunction<InverseCauchyCDFFunction, double, double, double, double>(
{prefix + "inverse_cauchy_cdf"});
registerFunction<InverseLaplaceCDFFunction, double, double, double, double>(
{prefix + "inverse_laplace_cdf"});
}

} // namespace
Expand Down
29 changes: 29 additions & 0 deletions velox/functions/prestosql/tests/ProbabilityTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,5 +577,34 @@ TEST_F(ProbabilityTest, inverseCauchyCDF) {
EXPECT_EQ(invCauchyCDF(kDoubleMin, 2.0, 0.5), kDoubleMin);
}

TEST_F(ProbabilityTest, inverseLaplaceCDF) {
const auto inverseLaplaceCDF = [&](std::optional<double> location,
std::optional<double> scale,
std::optional<double> p) {
return evaluateOnce<double>(
"inverse_laplace_cdf(c0, c1, c2)", location, scale, p);
};

EXPECT_EQ(inverseLaplaceCDF(0.0, 1.0, 0.5), 0.0);
EXPECT_EQ(inverseLaplaceCDF(5.0, 2.0, 0.5), 5.0);

VELOX_ASSERT_THROW(
inverseLaplaceCDF(1.0, 1.0, kNan), "p must be in the interval [0, 1]");
VELOX_ASSERT_THROW(
inverseLaplaceCDF(1.0, 1.0, 2.0), "p must be in the interval [0, 1]");

EXPECT_EQ(inverseLaplaceCDF(10.0, kDoubleMax, 0.999999999999), kInf);
EXPECT_EQ(inverseLaplaceCDF(10.0, kDoubleMin, 0.000000000001), 10.0);
VELOX_ASSERT_THROW(
inverseLaplaceCDF(1.0, kNan, 0.5), "scale must be greater than 0");
VELOX_ASSERT_THROW(
inverseLaplaceCDF(1.0, -1.0, 0.5), "scale must be greater than 0");

EXPECT_THAT(inverseLaplaceCDF(kInf, 1.0, 0.5), IsNan());
EXPECT_THAT(inverseLaplaceCDF(kNan, 1.0, 0.5), IsNan());
EXPECT_THAT(inverseLaplaceCDF(kDoubleMax, 1.0, 0.5), kDoubleMax);
EXPECT_THAT(inverseLaplaceCDF(kDoubleMin, 1.0, 0.5), kDoubleMin);
}

} // namespace
} // namespace facebook::velox

0 comments on commit 0adc62e

Please sign in to comment.