27 valarray_t& wins, std::valarray<long double>& denominator)
const
33 const range_t range = features.range(g);
35 const bool in_check = EffectUtil::isKingInCheck(state.
turn(), state);
36 if (! in_check || features.effectiveInCheck(g))
39 int found = features.group(g).findMatch(state, selected, env);
41 ++wins[found+range.first];
43 valarray_t sum_c(0.0, range.second-range.first);
44 long double sum_e = 0.0;
45 for (
size_t i=0; i<moves.
size(); ++i) {
50 for (
size_t j=0; j<features.groupSize(); ++j) {
52 if (in_check && ! features.effectiveInCheck(j))
55 int found = features.group(j).findMatch(state, m, env);
58 found += features.range(j).first;
59 product *= features.weight(found);
62 assert(range.first <= found && found < range.second);
69 sum_c[match_id-range.first] += product / features.weight(match_id);
72 for (
int f=range.first; f<range.second; ++f)
73 denominator[f] += sum_c[f-range.first]/sum_e;
101 assert(wins.size() == features.featureSize());
102 KisenFile kisen_file(kisen_filename.c_str());
105 for (
size_t i=first; i<
last; i++) {
116 const auto moves=kisen_file.
moves(i+kisen_start);
117 for (
size_t j=0; j<moves.size(); j++) {
126 if (!
addSquare(g, state, env, moves[j], wins, denominator))
130 env.
update(state, moves[j]);
139 std::valarray<valarray_t>
wins(
valarray_t(0.0, features.featureSize()), num_cpus);
140 std::valarray<std::valarray<long double> >
denominator(std::valarray<long double>(0.0, features.featureSize()), num_cpus);
141 assert(wins.size() == num_cpus);
143 KisenFile kisen_file(kisen_filename.c_str());
145 num_records=kisen_file.
size();
147 accumulate(g, 0, num_records, wins[0], denominator[0]);
151 size_t last =
num_records, step = (last - cur)/num_cpus;
152 boost::ptr_vector<std::thread> threads;
153 std::valarray<size_t>
skip((
size_t)0, num_cpus);
154 for (
size_t i=0; i<
num_cpus; ++i, cur += step) {
155 size_t next = (i+1 ==
num_cpus) ? last : cur + step;
156 threads.push_back(
new std::thread(
Thread(
this, g, cur, next, &wins[i], &denominator[i], &skip[i])));
161 std::cerr <<
"skip " << skip.sum() <<
" / " << num_records <<
"\n";
163 const range_t range = features.range(g);
164 for (
int f=range.first; f<range.second; ++f) {
165 const int NPRIOR = 10;
166 double sum_win = NPRIOR;
167 long double sum_denom = (1.0 / (features.weight(f) + 1.0)) * 2 * NPRIOR;
169 sum_win += wins[i][f];
170 sum_denom += denominator[i][f];
173 std::cerr <<
" " << std::setw(14) << features.feature(f).name()
174 <<
" " << features.weight(f) <<
" => " << sum_win/sum_denom
175 <<
" " << sum_win <<
" / " << sum_denom
176 <<
" " << 400*log10(sum_win/sum_denom) <<
"\n";
180 features.setWeight(f, sum_win/sum_denom);
181 assert(! std::isinf(features.weight(f)));
182 assert(! std::isnan(features.weight(f)));
185 features.showGroup(std::cerr, g);
bool addSquare(size_t g, const NumEffectState &state, const RatingEnv &env, Move selected, valarray_t &wins, std::valarray< long double > &denominator) const