10 #include <boost/thread/thread.hpp> 
   17   : features(f), 
kisen_filename(kisen_file), kisen_start(kisen_start), num_cpus(1), num_records(200),
 
   29                           valarray_t& wins, std::valarray<long double>& denominator)
 const 
   33   if (! moves.isMember(selected))
 
   35   const range_t range = features.range(g);
 
   37   const bool in_check = EffectUtil::isKingInCheck(state.turn(), state);
 
   38   if (! in_check || features.effectiveInCheck(g))
 
   41     int found = features.group(g).findMatch(state, selected, env);
 
   43       ++wins[found+range.first];
 
   45   valarray_t sum_c(0.0, range.second-range.first);
 
   46   long double sum_e = 0.0;
 
   47   for (
size_t i=0; i<moves.size(); ++i) {
 
   52     for (
size_t j=0; j<features.groupSize(); ++j) {
 
   54       if (in_check && ! features.effectiveInCheck(j))
 
   57       int found = features.group(j).findMatch(state, m, env);
 
   60       found += features.range(j).first;
 
   61       product *= features.weight(found);
 
   64         assert(range.first <= found && found < range.second);
 
   71       sum_c[match_id-range.first] += product / features.weight(match_id);
 
   74   for (
int f=range.first; f<range.second; ++f)
 
   75     denominator[f] += sum_c[f-range.first]/sum_e;
 
   91     : features(a), 
target(t), first(f), last(l), wins(w), denominator(d), skip(s)
 
   96     *skip = features->accumulate(
target, first, last, *wins, *denominator);
 
  103   assert(wins.size() == features.featureSize());
 
  107   for (
size_t i=first; i<
last; i++) {
 
  115     NumEffectState state(kisen_file.getInitialState());
 
  119     for (
size_t j=0; j<moves.size(); j++) {
 
  123         const Player turn = state.turn();
 
  124         if (! state.inCheck()
 
  128       if (! 
addSquare(g, state, env, moves[j], wins, denominator))
 
  131       state.makeMove(moves[j]);
 
  132       env.update(state, moves[j]);
 
  141   std::valarray<valarray_t> 
wins(
valarray_t(0.0, features.featureSize()), num_cpus);
 
  142   std::valarray<std::valarray<long double> > 
denominator(std::valarray<long double>(0.0, features.featureSize()), num_cpus);
 
  147     num_records=kisen_file.size();
 
  149     accumulate(g, 0, num_records, wins[0], denominator[0]);
 
  153     size_t last = 
num_records, step = (last - cur)/num_cpus;
 
  154     boost::ptr_vector<boost::thread> threads;  
 
  155     std::valarray<size_t> 
skip((
size_t)0, num_cpus);
 
  156     for (
size_t i=0; i<
num_cpus; ++i, cur += step) {
 
  157       size_t next = (i+1 == 
num_cpus) ? last : cur + step;
 
  158       threads.push_back(
new boost::thread(
Thread(
this, g, cur, next, &wins[i], &denominator[i], &skip[i])));
 
  163       std::cerr << 
"skip " << skip.sum() << 
" / " << num_records << 
"\n";
 
  165   const range_t range = features.range(g);
 
  166   for (
int f=range.first; f<range.second; ++f) {
 
  167     const int NPRIOR = 10; 
 
  168     double sum_win = NPRIOR;
 
  169     long double sum_denom = (1.0 / (features.weight(f) + 1.0)) * 2 * NPRIOR;
 
  171       sum_win += wins[i][f];
 
  172       sum_denom += denominator[i][f];
 
  175     std::cerr << 
"  " << std::setw(14) << features.feature(f).name() 
 
  176               << 
" " << features.weight(f) << 
" => " << sum_win/sum_denom
 
  177               << 
"  " << sum_win << 
" / " << sum_denom
 
  178               << 
"  " << 400*log10(sum_win/sum_denom) << 
"\n";
 
  182       features.setWeight(f, sum_win/sum_denom);
 
  183     assert(! std::isinf(features.weight(f)));
 
  184     assert(! std::isnan(features.weight(f)));
 
  187   features.showGroup(std::cerr, g);
 
  193   for (
int j=0; j<16; ++j) {
 
  194     std::cerr << 
"\nnew iteration " << j << 
"\n";
 
  195     for (
size_t i=0; i<features.groupSize(); ++i) {
 
  197       features.save(output_directory, i); 
 
  198       if ((
int)(i+1) == fix_group)