Skip to content

Commit

Permalink
Merge pull request #3854 from pleroy/ZeroTolerance
Browse files Browse the repository at this point in the history
Change the zero-free test of the Чебышёв series to take an error estimate
  • Loading branch information
pleroy authored Jan 27, 2024
2 parents cb322b6 + 1eb7cad commit dca39ec
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 4 deletions.
7 changes: 5 additions & 2 deletions numerics/чебышёв_series.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,11 @@ class ЧебышёвSeries final {

// Returns true if this polynomial may (but doesn't necessarily) have real
// roots. Returns false it is guaranteed not to have real roots. This is
// significantly faster than calling |RealRoots|.
bool MayHaveRealRoots() const;
// significantly faster than calling |RealRoots|. If |error_estimate| is
// given, false is only returned if the envelope of the series at a distance
// of |error_estimate| has no real roots. This is useful if the series is an
// approximation of some function with an L∞ error less than |error_estimate|.
bool MayHaveRealRoots(Value error_estimate = Value{}) const;

// Returns the real roots of the polynomial, computed as the eigenvalues of
// the Frobenius companion matrix.
Expand Down
9 changes: 7 additions & 2 deletions numerics/чебышёв_series_body.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,9 @@ UnboundedMatrix<double>
}

template<typename Value, typename Argument>
bool ЧебышёвSeries<Value, Argument>::MayHaveRealRoots() const {
bool ЧебышёвSeries<Value, Argument>::MayHaveRealRoots(
Value const error_estimate) const {
CHECK_LE(Value{}, error_estimate);
// TODO(phl): This is a property of the series so we should cache it.
// This code follow [Boy06], theorem 2. Note that [Boy06] has another
// criterion, B₁ and concludes: “There was no detectable difference between
Expand All @@ -313,7 +315,10 @@ bool ЧебышёвSeries<Value, Argument>::MayHaveRealRoots() const {
auto const abs_aⱼ = Abs(helper_.coefficients(j));
B₀ += abs_aⱼ;
}
return B₀ >= Abs(helper_.coefficients(0));
auto const abs_a₀ = Abs(helper_.coefficients(0));
// The error may shift the curve vertically. Note that the following
// comparison is valid if the right-hand side is negative.
return B₀ >= abs_a₀ - error_estimate;
}

template<typename Value, typename Argument>
Expand Down
2 changes: 2 additions & 0 deletions numerics/чебышёв_series_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ TEST_F(ЧебышёвSeriesTest, MayHaveRealRoots) {
// B₀ path.
ЧебышёвSeries<double, Instant> series1({16, 5, 3, 7}, t_min_, t_max_);
EXPECT_FALSE(series1.MayHaveRealRoots());
// An error estimate causes the result to be more pessimistic.
EXPECT_TRUE(series1.MayHaveRealRoots(/*error_estimate*/1.5));
// We don't know, but it actually doesn't have zeroes.
ЧебышёвSeries<double, Instant> series2({13, 5, 3, 7}, t_min_, t_max_);
EXPECT_TRUE(series2.MayHaveRealRoots());
Expand Down

0 comments on commit dca39ec

Please sign in to comment.