stan-dev / stan

Stan development repository. The master branch contains the current release. The develop branch contains the latest stable development. See the Developer Process Wiki for details.
https://mc-stan.org
BSD 3-Clause "New" or "Revised" License
2.59k stars 371 forks source link

test fixture test_gradients problem #1224

Closed rtrangucci closed 9 years ago

rtrangucci commented 9 years ago

the test_gradients test in test_fixture_distr.hpp, test_fixture_cdf.hpp, test_fixture_cdf_log.hpp and test_fixture_ccdf_log.hpp is broken.

The test_gradients in test_fixture_distr.hpp is intended to test a density's implementation of partials with an autodiffed naive implementation of the density. However, due to the current pattern, the test always passes. To verify this, change line 87 in stan/src/test/unit-distribution/univariate/continuous/normal/normal_test.hpp from:

return -0.5 * (y - mu) * (y - mu) / (sigma * sigma)

to:

return -0.5 * (y - mu) * (y - mu) / (sigma * sigma) * 100

and run:

./runTests.py -j2 src/test/unit-distribution/univariate/continuous/normal/normal_00000_generated_v_test.cpp

noting that the "Function" tests for v32 and v36 pass when they shouldn't. The problematic section in test_fixture_distr.hpp are lines 522-552:

      Scalar0 p0 = get_param<Scalar0>(parameters[n], 0);
      Scalar1 p1 = get_param<Scalar1>(parameters[n], 1);
      Scalar2 p2 = get_param<Scalar2>(parameters[n], 2);
      Scalar3 p3 = get_param<Scalar3>(parameters[n], 3);
      Scalar4 p4 = get_param<Scalar4>(parameters[n], 4);
      Scalar5 p5 = get_param<Scalar5>(parameters[n], 5);

      vector<var> x1;
      vector<var> x2;
      vector<var> x3;
      vector<var> y1;
      vector<var> y2;
      vector<var> y3;
      add_vars(x1, p0, p1, p2, p3, p4, p5);
      add_vars(x2, p0, p1, p2, p3, p4, p5);
      add_vars(x3, p0, p1, p2, p3, p4, p5);
      add_vars(y1, p0, p1, p2, p3, p4, p5);
      add_vars(y2, p0, p1, p2, p3, p4, p5);
      add_vars(y3, p0, p1, p2, p3, p4, p5);

      T_return_type logprob = TestClass.template log_prob
        <Scalar0,Scalar1,Scalar2,Scalar3,Scalar4,Scalar5>
        (p0,p1,p2,p3,p4,p5);

      T_return_type logprob_funct = TestClass.template log_prob_function
        <Scalar0,Scalar1,Scalar2,Scalar3,Scalar4,Scalar5>
        (p0,p1,p2,p3,p4,p5);

      calculate_gradients_1storder(expected_gradients1, logprob_funct, x1);
      calculate_gradients_1storder(gradients1, logprob, y1);

The reason the tests pass is because calculate_gradients_1storder in stan/src/test/unit-distribution/test_fixture_distr.hpp calls stan::agrad::recover_memory() and the naive implementation and the density function are called with the same vars. y1 and x1 point to the same varis, whose adjoints are updated when calculate_gradients_1storder is called the first time.

The fix is to change the order of how calculate_gradients is called and how vars are created for the naive implementation vs. the stan::prob densities within test_gradients.

syclik commented 9 years ago

This issue was moved to stan-dev/math#102