shap/tree_shap.h
inline void unwind_path(PathElement *unique_path, unsigned unique_depth, unsigned path_index) {
  const tfloat one_fraction = unique_path[path_index].one_fraction;
  const tfloat zero_fraction = unique_path[path_index].zero_fraction;
  tfloat next_one_portion = unique_path[unique_depth].pweight;

  for (int i = unique_depth - 1; i >= 0; --i) {
    if (one_fraction != 0) {
      const tfloat tmp = unique_path[i].pweight;
      unique_path[i].pweight = next_one_portion * (unique_depth + 1)
                               / static_cast<tfloat>((i + 1) * one_fraction);
      next_one_portion = tmp - unique_path[i].pweight * zero_fraction * (unique_depth - i)
                               / static_cast<tfloat>(unique_depth + 1);
    } else {
      unique_path[i].pweight = (unique_path[i].pweight * (unique_depth + 1))
                               / static_cast<tfloat>(zero_fraction * (unique_depth - i));
    }
  }

  for (unsigned i = path_index; i < unique_depth; ++i) {
    unique_path[i].feature_index = unique_path[i+1].feature_index;
    unique_path[i].zero_fraction = unique_path[i+1].zero_fraction;
    unique_path[i].one_fraction = unique_path[i+1].one_fraction;
  }
}
// undo a previous extension of the decision path
undo a previous extension of the decision path
undo a previous extension of the decision path
inline void unwind_path(PathElement *unique_path, unsigned unique_depth, unsigned path_index) {
  const tfloat one_fraction = unique_path[path_index].one_fraction;
  const tfloat zero_fraction = unique_path[path_index].zero_fraction;
  tfloat next_one_portion = unique_path[unique_depth].pweight;
  for (int i = unique_depth - 1; i >= 0; --i) {
    if (one_fraction != 0) {
      const tfloat tmp = unique_path[i].pweight;
      unique_path[i].pweight = next_one_portion * (unique_depth + 1)
                               / static_cast<tfloat>((i + 1) * one_fraction);
      next_one_portion = tmp - unique_path[i].pweight * zero_fraction * (unique_depth - i)
                               / static_cast<tfloat>(unique_depth + 1);
    } else {
      unique_path[i].pweight = (unique_path[i].pweight * (unique_depth + 1))
                               / static_cast<tfloat>(zero_fraction * (unique_depth - i));
    }
  }
  for (unsigned i = path_index; i < unique_depth; ++i) {
    unique_path[i].feature_index = unique_path[i+1].feature_index;
    unique_path[i].zero_fraction = unique_path[i+1].zero_fraction;
    unique_path[i].one_fraction = unique_path[i+1].one_fraction;
  }
}
inline void unwind_path ( PathElement * unique_path , unsigned unique_depth , unsigned path_index ) { const tfloat one_fraction = unique_path [ path_index ] . one_fraction ; const tfloat zero_fraction = unique_path [ path_index ] . zero_fraction ; tfloat next_one_portion = unique_path [ unique_depth ] . pweight ; for ( int i = unique_depth - 1 ; i >= 0 ; -- i ) { if ( one_fraction != 0 ) { const tfloat tmp = unique_path [ i ] . pweight ; unique_path [ i ] . pweight = next_one_portion * ( unique_depth + 1 ) / static_cast < tfloat > ( ( i + 1 ) * one_fraction ) ; next_one_portion = tmp - unique_path [ i ] . pweight * zero_fraction * ( unique_depth - i ) / static_cast < tfloat > ( unique_depth + 1 ) ; } else { unique_path [ i ] . pweight = ( unique_path [ i ] . pweight * ( unique_depth + 1 ) ) / static_cast < tfloat > ( zero_fraction * ( unique_depth - i ) ) ; } } for ( unsigned i = path_index ; i < unique_depth ; ++ i ) { unique_path [ i ] . feature_index = unique_path [ i + 1 ] . feature_index ; unique_path [ i ] . zero_fraction = unique_path [ i + 1 ] . zero_fraction ; unique_path [ i ] . one_fraction = unique_path [ i + 1 ] . one_fraction ; } }
undo a previous extension of the decision path
undo a previous extension of the decision path