Skip to content

Commit

Permalink
add inverse_laplace_cdf function
Browse files Browse the repository at this point in the history
  • Loading branch information
wills-feng committed Jul 13, 2024
1 parent 322d892 commit 5ddfebf
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 0 deletions.
6 changes: 6 additions & 0 deletions velox/docs/functions/presto/math.rst
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,12 @@ Probability Functions: inverse_cdf
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
18 changes: 18 additions & 0 deletions velox/functions/prestosql/Probability.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,24 @@ struct InverseCauchyCDFFunction {
result = boost::math::quantile(cauchyDist, p);
}
}
}
;

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
Expand Down
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
28 changes: 28 additions & 0 deletions velox/functions/prestosql/tests/ProbabilityTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,5 +577,33 @@ 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 5ddfebf

Please sign in to comment.