void mhwd::updateConfigData(mhwd::Data *data) { // Clear config vectors in each device element for (std::vector<mhwd::Device*>::iterator iterator = data->PCIDevices.begin(); iterator != data->PCIDevices.end(); iterator++) { (*iterator)->availableConfigs.clear(); } for (std::vector<mhwd::Device*>::iterator iterator = data->USBDevices.begin(); iterator != data->USBDevices.end(); iterator++) { (*iterator)->availableConfigs.clear(); } // Clear installed config vectors std::for_each(data->allPCIConfigs.begin(), data->allPCIConfigs.end(), delete_ptr<mhwd::Config>()); std::for_each(data->allUSBConfigs.begin(), data->allUSBConfigs.end(), delete_ptr<mhwd::Config>()); data->allPCIConfigs.clear(); data->allUSBConfigs.clear(); // Refill data fillAllConfigs(data, mhwd::TYPE_PCI); fillAllConfigs(data, mhwd::TYPE_USB); setMatchingConfigs(&data->PCIDevices, &data->allPCIConfigs, false); setMatchingConfigs(&data->USBDevices, &data->allUSBConfigs, false); // Update also installed config data updateInstalledConfigData(data); }
int PMN::fillAllConfigs(int from, int to, int left, std::vector<PMConfig> &conf, int counter){ //First save the initial configuration to a temporary vector, as we will need it PMConfig initConf(conf[counter]); //If there is only one p left to place, place one at every possible location and return if(left == 1){ for(int i=from; i<to; i++){ if(i>from){ conf[counter] = initConf; } conf[counter][i] = Cfg_P; counter++; } }else{ for(int i=from; i<to; i++){ if(i>from){ conf[counter] = initConf; } conf[counter][i] = Cfg_P; //If there are more to place, place one and call itself. The to //argument is such that if you have 2 left to place, you cannot go //to the end of the array, only to the second last element (as there //must be room for the last p) counter = fillAllConfigs(i+1,to+1,left-1,conf,counter); } } return counter; }
void PMN::fillConfigs(){ for(int i=0; i < (order/2); i++){ int kappa = (i+1)*2; //First initialise all configurations, and add them to a vector. As there must be an equal number of p's and m's //there are binominal(n,n/2) of these. int validConfigs = Utility::BinomialCoefficients<int>(kappa, kappa/2); std::vector<PMConfig> allConfigs(validConfigs,PMConfig(kappa)); //The configurations are filled using a recursive function fillAllConfigs, which is explained in more detail later. //After this the vector allConfigs should be filled. At e.q. k^4 it is filled with ppmm, pmpm, pmmp, mpmp, mmpp, mppm fillAllConfigs(0,(kappa/2+1),kappa/2,allConfigs,0); //Do a superficial ordering of all elements so that they all start with a p and end with an m for(auto &conf : allConfigs){ conf.ordering(); } //Add an emply std::vector<PMPair> to the back of the configurations-list //configurations.emplace_back; for(int j=0; j<validConfigs; j++){ bool incr = false; //Check through the vector of PMPairs and see if the configuration is already present or not for(auto &conf : configurations[i]){ //If it is present, add to the count and move on. The overloaded equality operator //also checks all permutations if(allConfigs[j] == conf){ conf++; incr=true; break; } } //If it wasn't found, add it if(!incr){ configurations[i].push_back(allConfigs[j]); configurations[i].back().finalise(); } } //Then add its exponential combinatoric factor: -2/order, the 2 from the gamma-trace for(auto &conf : configurations[i]){ conf *= (PM::pref_type)-2; conf /= kappa; } } //At order kappa^2 there are no multi-trace configurations if(order == 2){ return; } int first_multi_trace = configurations.back().size(); //The number of single trace configurations //Here we use the subset_sum function defined in std_libs/std_funcs.h. It takes a list of positive integers to //sum and a target, then it finds all possible ways to sum the numbers in the subset so that the result is the target. //E.g. {2,4} to 6 gives 2 lists: {2,2,2},{2,4} std::vector<int> subset(order/2 - 1); for(int i=0; i < (order/2-1); i++){ subset[i] = (i+1)*2; } SubsetSum<> sumCreator(order, subset); std::list< std::vector<int> > combinations = sumCreator.calculate(); //A comb is now a list of which PMConfig's we want to construct the multi-trace contrib for(auto &comb : combinations){ configurations.back().emplace_back(order); std::list< std::vector<int> > send_set; //This is a parameter sent between the recursive calls to calculate fill_multi_config(comb,0,0,send_set); //the combinatoric factor in the end } //An iterator which starts at the first multi trace multi_trace_begin = configurations.back().begin(); std::advance(multi_trace_begin, first_multi_trace); multi_trace_begin_const = multi_trace_begin; }