Skip to content

Commit

Permalink
add inverse_laplace_cdf function
Browse files Browse the repository at this point in the history
address
  • Loading branch information
wills-feng committed Apr 25, 2024
1 parent a9a620d commit 656d27a
Show file tree
Hide file tree
Showing 4 changed files with 53 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 @@ -319,6 +319,12 @@ Probability Functions: inverse_cdf
probability (p): P(N < n). The a, b parameters must be positive real values (all of type DOUBLE).
The probability p must lie 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 @@ -249,5 +249,22 @@ struct WeibullCDFFunction {
}
};

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 @@ -189,6 +189,8 @@ void registerSimpleFunctions(const std::string& prefix) {
Map<Varchar, double>>({prefix + "cosine_similarity"});
registerFunction<WeibullCDFFunction, double, double, double, double>(
{prefix + "weibull_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 @@ -453,5 +453,33 @@ TEST_F(ProbabilityTest, weibullCDF) {
weibullCDF(kDoubleMin, kNan, kDoubleMax), "b must be greater than 0");
}

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 656d27a

Please sign in to comment.