code: public void backward() {
          double l2distAdj = yAdj.getValue(0);
          VarTensor[] varBeliefs = inf.getOutput().varBeliefs;
          VarTensor[] varBeliefsAdjs = inf.getOutputAdj().varBeliefs;
          
          // Fill in the non-zero adjoints with the adjoint of the expected recall.
          for (Var v : vc.getVars()) {
              if (v.getType() == VarType.PREDICTED) {
                  VarTensor marg = varBeliefs[v.getId()];
                  int goldState = vc.getState(v);
                  for (int c=0; c<marg.size(); c++) {
                      double goldMarg = (c == goldState) ? s.one() : s.zero();
                      double predMarg = marg.getValue(c);
                      // dG/db(x_i) = dG/dy 2(b(x_i) - b*(x_i))
                      double diff = s.minus(predMarg, goldMarg);
                      double adj_b = s.times(l2distAdj, s.plus(diff, diff));
                      // Increment adjoint of the belief.
                      varBeliefsAdjs[v.getId()].addValue(c, adj_b);
                  }
              }
          }
      }
docs: Backward pass:
  
  Expanding the square, we get y = \sum_i \sum_{x_i} b(x_i)^2 - 2b(x_i)b*(x_i) + b*(x_i)^2
  
  dG/db(x_i) = dG/dy dy/db(x_i) = dG/dy 2(b(x_i) - b*(x_i)), \forall x_i.