Hi all,
I’ve started going about writing a new function for Stan because
- I want something for extending ICAR’s beyond what Mitzi’s code can easily do and the current options are very slow
- I’m sick of having to explain to people that I’m not stan-dev, I’m just pushy*, so I’m taking the first step towards doing something about it.
- Structured procrastination is my new jam.
As I’m probably the simplest programmer you’re likely to have trying to do this and I’m implementing the simplest program ( I want sparse quadratic forms y = v’Qv, which even I can differentiate), @betanalpha suggested I point out things I find missing in the doc. Obviously, the caveat here is there are probably doc pages I’m not seeing, or things I’m reading too fast. I’m also a very bad programmer. But in the event that this is useful for other people, here are my feelings so far (more will come as feelings develop).
-
Broadly speaking, the Contributing New Functions to Stan page is excellent, but it is not obvious to find from mc-stan.org. (You need to go click to the Developer Process overview and then find it in the menu on the right. It could be more obvious.
-
Similarly, to find the How To Write Unit Tests page you literally need to click on the button to find the hidden topics. Perhaps it would be better for the developer page on mc-stan.org to have an index of wikis separated by topics. This could also be linked in the Contributing New Funtions To Stan page.
-
Some stuff is a bit unclear. For example, the asserts that are commonly on the top of functions (are the argument dimensions correct, is the matrix positive definite etc) present two challenges.
– The first is that it’s not clear what’s there or where it is (eg the check_size_match.hpp function is in math/prim/scal/ even though its obvious use case is checking dimensions, which are multivariate. It makes sense after you find it.)
– The second is that some of the @throw doxygen comments are a bit odd. For example, the string for prim/mat/fun/dot_self.hpp says “@throw std::domain_error If v is not vector dimensioned.” while the code for check_vector() just calls the function invalid_argument(), which may through that exception, but it’s not obvious. -
For the unit testing, I don’t have the foggiest what the TEST( arg, arg) macro (I guess it’s a macro) does and I don’t know where to find the information. I can pattern match, but it’s really only a guess. Also how to run them would be nice. I worked out hat it’s
python runTests.py test/unit/math/prim/mat/fun/dot_self_test.cpp
-
I am not yet at a point to do model tests, but some more doc would probably be useful there too.
-
It would be super-nice to have a more obvious link to the Stan Math library doc on arxiv and maybe a paragraph of “sense checking”. For instance Mike sent me, for computing the reverse mode AD of f(x) that it should be:
adjoints_in [vector of size dim(x)] = J^{T} [matrix of size dim(x) x dim(f) ] * adjoints_out [ vector of size dim(f) ]
-
The key thing there that was useful for me that was harder to read in the ninety-something page doc is exactly what dimension everything should be!
-
There are also some unclear things about memory management for the AD that may only be relevant because I’m reading matrix stuff. For example in rev/mat/fun/multiply.hpp there’s a comment that says
* It is critical for the efficiency of this object * that the constructor create new varis that aren't * popped onto the var_stack_, but rather are * popped onto the var_nochain_stack_. This is * controlled to the second argument to * vari's constructor.
- This probably means a lot to existing devs, but I couldn’t find any doc on the memory management for varis. This is very much a fringe issue and maybe not best dealt with through docs (rather through venues like the discourse or during PR reviews), but I’m listing everything.
I’ll add more in the thread if more comes up.
*“I Don’t Push, I’m Just Pushy” is my late-career Sinead O’Connor tribute album.