Inspired by @Bob_Carpenter I started using `expect_near_rel`

instead of various manual solutions to test “approximate equivalence” in my tests for Stan math. I have however become slightly suspect of its behavior recently and want to discuss whether it’s implementation shouldn’t change (especially if we want to encourage it’s use across the codebase).

The relevant part of the code is:

```
void expect_near_rel_finite(const std::string& msg, const T1& x1, const T2& x2,
double tol = 1e-8) {
using stan::math::fabs;
// if either arg near zero, must use absolute tolerance as rel tol -> 2
if (fabs(x1) < tol || fabs(x2) < tol) {
EXPECT_NEAR(x1, x2, tol)
return;
}
auto avg = 0.5 * (fabs(x1) + fabs(x2));
auto relative_diff = (x1 - x2) / avg;
EXPECT_NEAR(0, relative_diff, tol)
```

This however behaves strangely for values close to the tolerance (`1e-8`

by default), where a steep change in required precision happens. For example, I now have a failing test with:

```
actual: 1.2019658157669255e-008,
expected: 1.2019540397111151e-008,
relative tolerance = 1e-008; relative diff = 9.7973780478180374e-006
```

This is OK to fail, but if I had `actual = 0.9e-008`

, the test would suddenly pass, even though the difference just increased.

Some discussion on the topic is at Relative delta in finite difference approximations of derivatives? where @anon75146577 recommends using `max(epsilon, epsilon*|x|)`

as a tolerance, which doesn’t have this problem, but might be unnecessarily lax when we care about small numbers. I’ve previously used something like `max(1e-14, 1e-8*|x|)`

.

So I am asking whether there is some good reason `expect_near_rel`

is implemented as it is and whether it might be sensible to implement it differently. `expect_near_rel`

is currently used in 21 tests, so it should not be a major change. It is also possible that `expect_near_rel`

is tailored to the autodiff case and shouldn’t be used elsewhere…

Thanks for any input!