A non-programmer idea for Stockfish, probably worthless

Discussion of chess software programming and technical issues.

Moderator: Ras

User avatar
hgm
Posts: 28480
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: A non-programmer idea for Stockfish, probably worthless

Post by hgm »

Isaac wrote:(or pawn, if we were to include them in order to calculate the game phase, but this isn't how Stockfish works as of now)
One of the important effects of game phase on engine play is that when the engine has an advantage that is worth more in the end-game than in the opening-phase, it will play for advancing the game phase even if that does not change the advantage. (In fact it might even sacrifice another, small advantage for advancing the game phase.)

Usually evaluation is dominated by material, and material advantages increase (e.g. when translated to win probability) towards the end-game. If you include Pawns in the game phase with positive weights, this means you will encourage engines that are ahead in material to trade Pawns, to advance the game phase. And trading Pawns is of course exactly what you should not do to maximize your winning chances. It is what the engine that is behind should strive for.

If Pawns are to be weighted into the game phase, it would make more sense to give them a negative weight.
Isaac
Posts: 265
Joined: Sat Feb 22, 2014 8:37 pm

Re: A non-programmer idea for Stockfish, probably worthless

Post by Isaac »

Joerg Oster wrote:
mcostalba wrote:
Isaac wrote:or pawn, if we were to include them in order to calculate the game phase, but this isn't how Stockfish works as of now
I did some quick test in a far past to include pawns in game phase calculation and not just no-pawn material, but was not good..anyhow could be right time to retest it :-)
I did test it not too long ago, and it failed.
Ah it was you! Yeah I knew someone had tested this not long ago.
mcostalba wrote:Of course you can, I even suggest to just pick a value of your choice for b (like 0.01) and run in fishtest against master, so to verify everything is more or less ok and also wet your hands with test submitting.
I'm a bit aware of the process of test submitting (I tried one test that failed the first SPRT, my account is "stockfishbot").
But before going to the fishtest I have 2 questions and one remark.
I did some few games testing with different values of b in my computer. I used the exact same way they test on the fishtest, except for the time control which would correspond to roughly 7 to 8+0.05 in the fishtest. The results are:
For b=0.03, my version scored 27-50-90 against the master. Not good, "as expected".
For b=-0.01, 29-52-61. Not very promising either.
For b=0, 7-18-28, not good.
For b=0.016 (which is the closest to the current straight line), the score was 44-51-139. So not good either but not a disaster, unlike the others.
I know I cannot conclude anything from such small samples, but at first glance it doesn't look promising to change too much from a straight line, if I want to use a quadratic instead. So if I were to give 2 shots, I'd try for example b=0.009 and b=0.0135.
Now the questions:
The expression is

Code: Select all

: Phase( 5.64*pow(10,-7)*pow(npm,2) -9 + b *(-3182-pow(npm,2)*5.11*pow(10,-5) +npm) );
.
When I directly replace b by any value (like 0.016) and when I add

Code: Select all

#include <math.h>
, I can compile without any problem and even run the Stockfish modified version. However, for efficiency I thought that it would be better to write the polynomial in the form ax²+dx+c instead of the expression above. For b=0.016 this gives -2.52x10^(-7) npm² +0.016 npm -59.91. Or written like in the code:

Code: Select all

 : Phase( -2.52*pow(10,-7)*pow(npm,2)+0.013*npm-59.91 );
But then, when I try to compile, I get errors and the executable is never created.
The exact error I get is :

Code: Select all

material.cpp:264:51: error: ambiguous overload for ‘operator*’ (operand types are ‘double’ and ‘Value’)
         : Phase( -2.52*pow(10,-7)*pow(npm,2)+0.013*npm-59.91 );
                                                   ^
material.cpp:264:51: note: candidates are:
material.cpp:264:51: note: operator*(double, int) <built-in>
In file included from bitboard.h:24:0,
                 from position.h:26,
                 from endgame.h:26,
                 from material.h:23,
                 from material.cpp:24:
types.h:281:10: note: Value operator*(int, Value)
 inline T operator*(int i, const T d) { return T(i * int(d)); }              \
          ^
types.h:288:32: note: in expansion of macro ‘ENABLE_SAFE_OPERATORS_ON’
 #define ENABLE_OPERATORS_ON(T) ENABLE_SAFE_OPERATORS_ON(T)                  \
                                ^
types.h:294:1: note: in expansion of macro ‘ENABLE_OPERATORS_ON’
 ENABLE_OPERATORS_ON(Value)
 ^
material.cpp:266:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
make[1]: *** [material.o] Error 1
make[1]: Leaving directory `/home/isaac/Downloads/Stockfish-master/src'
make: *** [build] Error 2
and I'm not sure why I get this. Apparently the compiler doesn't like when I multiply "npm" or divide it by 62.5 (which is the same as multiplying by 0.016). I just tried to replace 0.013 by 13/1000 and now it works, but I feel like I may be doing something unwanted and that my code is "broken".
So question 1): Can I rewrite

Code: Select all

: Phase( 5.64*pow(10,-7)*pow(npm,2) -9 + b *(-3182-pow(npm,2)*5.11*pow(10,-5) +npm) );
in a more efficient way if I want to plug a value for b?
For example would it be better to use the code

Code: Select all

: Phase( -2.52*pow(10,-7)*pow(npm,2)+(npm*(13/1000))-59.91 );
instead of

Code: Select all

: Phase( 5.64*pow(10,-7)*pow(npm,2) -9 + 0.013 *(-3182-pow(npm,2)*5.11*pow(10,-5) +npm) );
?

Question 2): For some values of b, it may happen that for 3998< npm <15581, the scaling factor due to game phase is slightly negative (-0.03) instead of being slightly greater than 0, due to rounding errors. Is this a problem?

Thank you.
Isaac
Posts: 265
Joined: Sat Feb 22, 2014 8:37 pm

Re: A non-programmer idea for Stockfish, probably worthless

Post by Isaac »

I've just scheduled a test in the fishtest. The bench number is -surprisingly- high. Let's see how it goes...
Isaac
Posts: 265
Joined: Sat Feb 22, 2014 8:37 pm

Re: A non-programmer idea for Stockfish, probably worthless

Post by Isaac »

A question principally for H.G. Muller but anyone else can respond:
When you say that
HGM wrote:In phase = (phase * 256 + TotalPhase/2)/TotalPhase the multipliation with 256 is there to start working in units of 1/256, so that you can use integer variables for representing a fraction. As phase/TotalPhase would always be smaller than 1, and thus rounded to 0 with integer division. (The adding of TotalPhase/2 produces nearest rounding.) Because of this normalization the phase now becomes a number that ranges from 0 to 256.
, I've got a question.
In Stockfish's code, I tried

Code: Select all

Phase(pow(10.0,-7.0)*pow(npm,2.0)+(9*npm)/1000-37);
with in mind that I get Phase(0) when npm=EndgameLimit (3998) and Phase(128) when npm=MidgameLimit (15581).
My question is, for the part that reads

Code: Select all

(9*npm)/1000
. What exactly do I get here? npm supposedly is an integer that ranges from 3998 to 15581. My goal was to get a float, or if I get an integer, that it would be rounded to the nearest integer and NOT worth 0 all the time (!!!).

Edit: Hmm since 9*npm is always greater than 1000, I guess I get what I wanted, i.e. a rounded off integer that is never worth 0. Correct?