+
+ // reduction_parameters() precalculates some parameters used later by reduction. Becasue
+ // floating point operations are involved we try to recalculate reduction at each move, but
+ // we do the most consuming computation only once per node.
+
+ void reduction_parameters(float baseReduction, float reductionInhibitor, Depth depth, float& logLimit, float& gradient)
+ {
+ // Precalculate some parameters to avoid to calculate the following formula for each move:
+ //
+ // red = baseReduction + ln(moveCount) * ln(depth / 2) / reductionInhibitor;
+ //
+ logLimit = depth > OnePly ? (1 - baseReduction) * reductionInhibitor / ln(depth / 2) : 1000;
+ gradient = depth > OnePly ? ln(depth / 2) / reductionInhibitor : 0;
+ }
+
+
+ // reduction() returns reduction in plies based on moveCount and depth.
+ // Reduction is always at least one ply.
+
+ Depth reduction(int moveCount, float logLimit, float baseReduction, float gradient) {
+
+ if (ln(moveCount) < logLimit)
+ return Depth(0);
+
+ float red = baseReduction + ln(moveCount) * gradient;
+ return Depth(int(floor(red * int(OnePly))));
+ }
+
+