simplify risk tolerance

Passed Non-regression STC:
LLR: 2.98 (-2.94,2.94) <-1.75,0.25>
Total: 73408 W: 19028 L: 18844 D: 35536
Ptnml(0-2): 201, 8709, 18743, 8807, 244
https://tests.stockfishchess.org/tests/view/68051f3698cd372e3ae9f63a

Passed Non-regression LTC:
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 91236 W: 23193 L: 23045 D: 44998
Ptnml(0-2): 34, 9908, 25599, 10030, 47
https://tests.stockfishchess.org/tests/view/6805239498cd372e3ae9fa41

closes https://github.com/official-stockfish/Stockfish/pull/6000

bench 1864632
This commit is contained in:
Shawn Xu
2025-04-20 09:21:01 -07:00
committed by Joost VandeVondele
parent 16cd38dba1
commit 4176ad7b0a

View File

@@ -97,31 +97,6 @@ int correction_value(const Worker& w, const Position& pos, const Stack* const ss
return 7685 * pcv + 7495 * micv + 9144 * (wnpcv + bnpcv) + 6469 * cntcv; return 7685 * pcv + 7495 * micv + 9144 * (wnpcv + bnpcv) + 6469 * cntcv;
} }
int risk_tolerance(const Position& pos, Value v) {
// Returns (some constant of) second derivative of sigmoid.
static constexpr auto sigmoid_d2 = [](int x, int y) {
return 644800 * x / ((x * x + 3 * y * y) * y);
};
int m = pos.count<PAWN>() + pos.non_pawn_material() / 300;
// a and b are the crude approximation of the wdl model.
// The win rate is: 1/(1+exp((a-v)/b))
// The loss rate is 1/(1+exp((v+a)/b))
int a = 356;
int b = ((65 * m - 3172) * m + 240578) / 2048;
// guard against overflow
assert(abs(v) + a <= std::numeric_limits<int>::max() / 644800);
// The risk utility is therefore d/dv^2 (1/(1+exp(-(v-a)/b)) -1/(1+exp(-(-v-a)/b)))
// -115200x/(x^2+3) = -345600(ab) / (a^2+3b^2) (multiplied by some constant) (second degree pade approximant)
int winning_risk = sigmoid_d2(v - a, b);
int losing_risk = sigmoid_d2(v + a, b);
return -(winning_risk + losing_risk) * 32;
}
// Add correctionHistory value to raw staticEval and guarantee evaluation // Add correctionHistory value to raw staticEval and guarantee evaluation
// does not hit the tablebase range. // does not hit the tablebase range.
Value to_corrected_static_eval(const Value v, const int cv) { Value to_corrected_static_eval(const Value v, const int cv) {
@@ -150,6 +125,29 @@ void update_correction_history(const Position& pos,
<< bonus * 143 / 128; << bonus * 143 / 128;
} }
int risk_tolerance(Value v) {
// Returns (some constant of) second derivative of sigmoid.
static constexpr auto sigmoid_d2 = [](int x, int y) {
return 644800 * x / ((x * x + 3 * y * y) * y);
};
// a and b are the crude approximation of the wdl model.
// The win rate is: 1/(1+exp((a-v)/b))
// The loss rate is 1/(1+exp((v+a)/b))
int a = 356;
int b = 123;
// guard against overflow
assert(abs(v) + a <= std::numeric_limits<int>::max() / 644800);
// The risk utility is therefore d/dv^2 (1/(1+exp(-(v-a)/b)) -1/(1+exp(-(-v-a)/b)))
// -115200x/(x^2+3) = -345600(ab) / (a^2+3b^2) (multiplied by some constant) (second degree pade approximant)
int winning_risk = sigmoid_d2(v - a, b);
int losing_risk = sigmoid_d2(v + a, b);
return -(winning_risk + losing_risk) * 32;
}
// Add a small random component to draw evaluations to avoid 3-fold blindness // Add a small random component to draw evaluations to avoid 3-fold blindness
Value value_draw(size_t nodes) { return VALUE_DRAW - 1 + Value(nodes & 0x2); } Value value_draw(size_t nodes) { return VALUE_DRAW - 1 + Value(nodes & 0x2); }
Value value_to_tt(Value v, int ply); Value value_to_tt(Value v, int ply);
@@ -1218,7 +1216,7 @@ moves_loop: // When in check, search starts here
r -= std::abs(correctionValue) / 29696; r -= std::abs(correctionValue) / 29696;
if (PvNode && std::abs(bestValue) <= 2000) if (PvNode && std::abs(bestValue) <= 2000)
r -= risk_tolerance(pos, bestValue); r -= risk_tolerance(bestValue);
// Increase reduction for cut nodes // Increase reduction for cut nodes
if (cutNode) if (cutNode)