Operands and partials

So Bob, Rob, and I have been looking at redesigning OperandsAndPartials, and we have a new interface that changes from exposing the partial derivative directly (op.d_x1[i] += adj) to exposing an increment method (op.increment_dx1(i, adj)). I then discovered there are a lot of *= uses of the partial in especially the CDFs, like in binomial_cdf.hpp:

      for (size_t i = 0; i < size; i++) {
          ...
          operands_and_partials.increment_dx1(i, - pow(theta_dbl, n_dbl)
            * pow(1-theta_dbl, N_dbl-n_dbl-1) / betafunc / Pi);
}

and is then *='d like so:

      if (!is_constant_struct<T_prob>::value) {
        for (size_t i = 0; i < stan::length(theta); ++i)
          operands_and_partials.d_x1[i] *= P;
      }

Since I think theta's length and size are not always the same value, it’s not obvious to me how to combine these such that they can fit into the increment_dx1() call. @Bob_Carpenter or @rtrangucci, thoughts?

-Sean

I don’t see how to do that easily, either You could obviously create an vector of values, increment them manually, then toss them into increment.

If we just expose the data structures, we might even make this all easier because d_x1 will be a vector now, right? So then it’d just be

operands_and_partials<...> ops(...);
ops.d_x1 *= P;

We probably shouldn’t call the variable operands_and_partials if that’s what we call the class. At least I always find that confusing in code.

Okay, I think I will try setting the API back to exposing the data structures.

I can’t find any uses of OperandsAndPartials where we actually care about the size; can anyone confirm or deny this? If we don’t need it I can switch the API more easily leaving that functionality out. It’s really only weird in the multivariate case anyway.

What size are you talking about here?

the size of the partials (or operands); e.g. d_x1.size()

It should be safe to remove. That information is redundant and we can get
the size in other ways.

I don’t remember any uses of it off the top of my head, but you know how
code goes. I’d remove it and see where it fails to compile.