void singlePeCalMin() { vector<inputValues> b; // Blank runs vector<inputValues> t; // Total runs vector<outputValues> o; vector<string> cutString(cut_b.size(), "Min > "); // Create strings to perform cuts for (int i = 0; i < cut_b.size(); i++) { cutString[i].append(to_string(cut_b[i])); } // Get input and output values from .root spectra for (int i = 0; i < fileNames_b.size(); i++) { b.push_back(getInputValues(fileNames_b[i], pulseWidths_b[i], cutString[i])); for (int j = 0; j < fileNames_t.size(); j++) { t.push_back(getInputValues(fileNames_t[j], pulseWidths_t[j], cutString[i])); o.push_back(getOutputValues(b[i], t[j])); } } makePlots(b, t, o, cut_b[0]); // Debugging cout << "BG E[T}: " << b[0].e << " BG a/n: " << b[0].a / b[0].n << endl; cout << setw(12) << "a/n " << setw(12) << "E[L] " << setw(12) << "E[Psi]" << setw(12) << "E[T]" << endl; for ( int i = 0; i < t.size(); i++) { cout << setw(12) << (float)t[i].a / t[i].n << setw(12) << o[i].eL << setw(12) << o[i].ePsi << setw(12) << t[i].e << endl; } }
void singlePeVaryMode() { vector<inputValues> b; // Blank runs vector<inputValues> t; // Total runs vector<outputValues> o; vector<string> cutString(cut_b.size(), "Charge > "); // Create strings to perform cuts - I would be able to use to_string if C++11 worked for (int i = 0; i < cut_b.size(); i++) { ostringstream ss; ss << cut_b[i]; cutString[i].append(ss.str()); } // Get input and output values from .root spectra for (int i = 0; i < fileNames_b.size(); i++) { b.push_back(getInputValues(fileNames_b[i], pulseWidths_b[i], useChargeMode_b[i], cutString[i])); for (int j = 0; j < fileNames_t.size(); j++) { if (useChargeMode_t[j] == useChargeMode_b[i]) { t.push_back(getInputValues(fileNames_t[j], pulseWidths_t[j], useChargeMode_t[j], cutString[i])); o.push_back(getOutputValues(b[i], t[j])); } } } makePlots(b, t, o); }
double strategytdexp4::boardValue( const board& brd, const hash_map<string,int>* context ) const { // get the inputs from the board, assuming the player holds the dice vector<double> inputs = getInputValues( brd, brd.perspective() ); // calculate the middle layer node values vector<double> middles = getMiddleValues( inputs ); // calculate the output node values from the middles double probWin = getOutputProbValue( middles ); double probCondGammonWin = getOutputGammonWinValue( middles, brd ); double probCondGammonLoss = getOutputGammonLossValue( middles, brd ); double probCondBgWin = getOutputBackgammonWinValue( middles, brd ); double probCondBgLoss = getOutputBackgammonLossValue( middles, brd ); // calculate the expected number of points the player will win. probWin // corresponds to the probability of a win (any win); probCondGammon // corresponds to the probability of a gammon conditional on a win; // probCondGammonLoss corresponds to the probability of a gammon loss // conditional on a loss. Ditto for backgammon win/loss conditional probs. double ppg = probWin * ( 1 * ( 1 - probCondGammonWin ) + 2 * probCondGammonWin * ( 1 - probCondBgWin ) + 3 * probCondGammonWin * probCondBgWin ) - ( 1 - probWin ) * ( 1 * ( 1 - probCondGammonLoss ) + 2 * probCondGammonLoss * ( 1 - probCondBgLoss ) + 3 * probCondGammonLoss * probCondBgLoss ); // the ppg is always from player 0's perspective. But we want it from the board // perspective. if( brd.perspective() == 0 ) return ppg; else return -ppg; }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QObject::connect(this->ui->minimizeButton,SIGNAL(clicked()),SLOT(getInputValues())); QObject::connect(this,SIGNAL(inputComplete()),SLOT(printResult())); }
void strategytdexp4::update( const board& oldBoard, const board& newBoard ) { // get the values from the old board vector<double> oldInputs = getInputValues( oldBoard, oldBoard.perspective() ); vector<double> oldMiddles = getMiddleValues( oldInputs ); double oldProbOutput = getOutputProbValue( oldMiddles ); double oldGammonWinOutput = getOutputGammonWinValue( oldMiddles, oldBoard ); double oldGammonLossOutput = getOutputGammonLossValue( oldMiddles, oldBoard ); double oldBgWinOutput = getOutputBackgammonWinValue( oldMiddles, oldBoard ); double oldBgLossOutput = getOutputBackgammonLossValue( oldMiddles, oldBoard ); // calculate all the partial derivatives we'll need (of output node values // to the various weights) int i, j; // then do derivs of the prob nodes to each of the middle->input weights (that's a 2d array), and the derivs of each of // the middle nodes to its weights->inputs. double mid, input, v1, v2, v3, v4, v5; for( i=0; i<nMiddle; i++ ) { mid = oldMiddles.at(i); v1 = outputProbWeights.at(i); v2 = outputGammonWinWeights.at(i); v3 = outputGammonLossWeights.at(i); v4 = outputBackgammonWinWeights.at(i); v5 = outputBackgammonLossWeights.at(i); probDerivs.at(i) = mid * oldProbOutput * ( 1 - oldProbOutput ); gamWinDerivs.at(i) = mid * oldGammonWinOutput * ( 1 - oldGammonWinOutput ); gamLossDerivs.at(i) = mid * oldGammonLossOutput * ( 1 - oldGammonLossOutput ); bgWinDerivs.at(i) = mid * oldBgWinOutput * ( 1 - oldBgWinOutput ); bgLossDerivs.at(i) = mid * oldBgLossOutput * ( 1 - oldBgLossOutput ); for( j=0; j<198; j++ ) { input = oldInputs.at(j); probInputDerivs.at(i).at(j) = v1 * input * oldProbOutput * ( 1 - oldProbOutput ) * mid * ( 1 - mid ); gamWinInputDerivs.at(i).at(j) = v2 * input * oldGammonWinOutput * ( 1 - oldGammonWinOutput ) * mid * ( 1 - mid ); gamLossInputDerivs.at(i).at(j) = v3 * input * oldGammonLossOutput * ( 1 - oldGammonLossOutput ) * mid * ( 1 - mid ); bgWinInputDerivs.at(i).at(j) = v4 * input * oldBgWinOutput * ( 1 - oldBgWinOutput ) * mid * ( 1 - mid ); bgLossInputDerivs.at(i).at(j) = v5 * input * oldBgLossOutput * ( 1 - oldBgLossOutput ) * mid * ( 1 - mid ); } probInputDerivs.at(i).at(198) = v1 * oldProbOutput * ( 1 - oldProbOutput ) * mid * ( 1 - mid ); gamWinInputDerivs.at(i).at(198) = v2 * oldGammonWinOutput * ( 1 - oldGammonWinOutput ) * mid * ( 1 - mid ); gamLossInputDerivs.at(i).at(198) = v3 * oldGammonLossOutput * ( 1 - oldGammonLossOutput ) * mid * ( 1 - mid ); bgWinInputDerivs.at(i).at(198) = v4 * oldBgWinOutput * ( 1 - oldBgWinOutput ) * mid * ( 1 - mid ); bgLossInputDerivs.at(i).at(198) = v5 * oldBgLossOutput * ( 1 - oldBgLossOutput ) * mid * ( 1 - mid ); } probDerivs.at(nMiddle) = oldProbOutput * ( 1 - oldProbOutput ); gamWinDerivs.at(nMiddle) = oldGammonWinOutput * ( 1 - oldGammonWinOutput ); gamLossDerivs.at(nMiddle) = oldGammonLossOutput * ( 1 - oldGammonLossOutput ); bgWinDerivs.at(nMiddle) = oldBgWinOutput * ( 1 - oldBgWinOutput ); bgLossDerivs.at(nMiddle) = oldBgLossOutput * ( 1 - oldBgLossOutput ); // now calculate the next estimate of the outputs. That's known if the game is over; otherwise we use the network's // estimate on the new board as a proxy. Note that the update fn is only ever called by the game when the player wins, not when // the player loses, just because the winner is the last one to play. But we need to train on prob of losing a gammon too, // so we flip board perspective and train again based on that. bool trainGammonLoss = true; bool trainGammonWin = true; bool trainBgLoss = true; bool trainBgWin = true; double newProbOutput, newGammonWinOutput, newGammonLossOutput, newBgWinOutput, newBgLossOutput; if( newBoard.bornIn0Raw() == 15 ) { trainGammonLoss = false; // can't train the conditional prob of a gammon loss if there isn't a loss trainBgLoss = false; // ditto for backgammon loss newProbOutput = 1.; if( newBoard.bornIn1Raw() == 0 ) // gammon or backgammon { newGammonWinOutput = 1.; vector<int> checks( newBoard.checkers1Raw() ); bool foundOne = newBoard.hit1Raw() > 0; if( !foundOne ) { for( int i=0; i<6; i++ ) if( checks.at(i) > 0 ) { foundOne = true; break; } } newBgWinOutput = foundOne ? 1 : 0; } else { newGammonWinOutput = 0.; trainBgWin = false; // no gammon win so can't train conditional bg win prob } } else if( newBoard.bornIn1Raw() == 15 ) { trainGammonWin = false; trainBgWin = false; newProbOutput = 0.; if( newBoard.bornIn0Raw() == 0 ) // gammon loss or backgammon loss { newGammonLossOutput = 1; vector<int> checks( newBoard.checkers0Raw() ); bool foundOne = newBoard.hit0Raw() > 0; if( !foundOne ) { for( int i=18; i<24; i++ ) if( checks.at(i) > 0 ) { foundOne = true; break; } } newBgLossOutput = foundOne ? 1 : 0; } else { newGammonLossOutput = 0; trainBgLoss = false; } } else { // estimate from the new board's outputs, remembering that after the move is done, // the other player gets the dice. vector<double> midVals( getMiddleValues( getInputValues( newBoard, !newBoard.perspective() ) ) ); newProbOutput = getOutputProbValue( midVals ); newGammonWinOutput = getOutputGammonWinValue( midVals, newBoard ); newGammonLossOutput = getOutputGammonLossValue( midVals, newBoard ); newBgWinOutput = getOutputBackgammonWinValue( midVals, newBoard ); newBgLossOutput = getOutputBackgammonLossValue( midVals, newBoard ); } // train the nodes as appropriate for( i=0; i<nMiddle; i++ ) { outputProbWeights.at(i) += alpha * ( newProbOutput - oldProbOutput ) * probDerivs.at(i); if( trainGammonWin ) outputGammonWinWeights.at(i) += alpha * ( newGammonWinOutput - oldGammonWinOutput ) * gamWinDerivs.at(i); if( trainGammonLoss ) outputGammonLossWeights.at(i) += alpha * ( newGammonLossOutput - oldGammonLossOutput ) * gamLossDerivs.at(i); if( trainBgWin ) outputBackgammonWinWeights.at(i) += alpha * ( newBgWinOutput - oldBgWinOutput ) * bgWinDerivs.at(i); if( trainBgLoss ) outputBackgammonLossWeights.at(i) += alpha * ( newBgLossOutput - oldBgLossOutput ) * bgLossDerivs.at(i); for( j=0; j<199; j++ ) { middleWeights.at(i).at(j) += beta * ( newProbOutput - oldProbOutput ) * probInputDerivs.at(i).at(j); if( trainGammonWin ) middleWeights.at(i).at(j) += beta * ( newGammonWinOutput - oldGammonWinOutput ) * gamWinInputDerivs.at(i).at(j); if( trainGammonLoss ) middleWeights.at(i).at(j) += beta * ( newGammonLossOutput - oldGammonLossOutput ) * gamLossInputDerivs.at(i).at(j); if( trainBgWin ) middleWeights.at(i).at(j) += beta * ( newBgWinOutput - oldBgWinOutput ) * bgWinInputDerivs.at(i).at(j); if( trainBgLoss ) middleWeights.at(i).at(j) += beta * ( newBgLossOutput - oldBgLossOutput ) * bgLossInputDerivs.at(i).at(j); } } outputProbWeights.at(nMiddle) += alpha * ( newProbOutput - oldProbOutput ) * probDerivs.at(nMiddle); if( trainGammonWin ) outputGammonWinWeights.at(nMiddle) += alpha * ( newGammonWinOutput - oldGammonWinOutput ) * gamWinDerivs.at(nMiddle); if( trainGammonLoss ) outputGammonLossWeights.at(nMiddle) += alpha * ( newGammonLossOutput - oldGammonLossOutput ) * gamLossDerivs.at(nMiddle); if( trainBgWin ) outputBackgammonWinWeights.at(nMiddle) += alpha * ( newBgWinOutput - oldBgWinOutput ) * bgWinDerivs.at(nMiddle); if( trainBgLoss ) outputBackgammonLossWeights.at(nMiddle) += alpha * ( newBgLossOutput - oldBgLossOutput ) * bgLossDerivs.at(nMiddle); }