//Method called from the main combinatorics loops for multivariate cases above (addMulti). Its whole purpose is reducing the size of the loops. //It updates certain variables; mainly the exponent/operation indices currently being considered (obj2) private ExpRelUpdate updateObj2(ExpRelUpdate obj2) { obj2.otherProp = false; if (obj2.curList[obj2.index] >= obj2.max) { obj2.index = obj2.index - 1; obj2.completed = true; if (obj2.index < 0 || obj2.curList[obj2.index] >= obj2.max) { bool finished = true; if (obj2.index > 0) { finished = false; while (obj2.index > 0 && obj2.curList[obj2.index] >= obj2.max) { obj2.index = obj2.index - 1; } if (obj2.curList[obj2.index] >= obj2.max) finished = true; } if (finished) { obj2.otherProp = true; return obj2; } } for (int i = obj2.index + 1; i < obj2.totIndices; i++) { obj2.curList[i] = 0; } } obj2.curList[obj2.index] = obj2.curList[obj2.index] + 1; return obj2; }
//Method called from the main combinatorics loops for multivariate cases above (addMulti). Its whole purpose is reducing the size of the loops. //It updates certain variables; mainly the exponent/operation indices currently being considered (obj1 & obj3) private ExpRelUpdate updateObjs13(ExpRelUpdate curObj, bool restart) { if (curObj.curList[curObj.index] < curObj.max) { curObj.curList[curObj.index] = curObj.curList[curObj.index] + 1; } else { if (curObj.index <= 0) { curObj.completed = true; return curObj; } else { curObj.index = curObj.index - 1; curObj.curList[curObj.index] = 1; //index 0 was done in the first iteration restart = true; } } if (restart) //The given list has to be restarted every time or only under certain conditions (i.e., obj1) { for (int i = curObj.index + 1; i < curObj.totIndices; i++) { curObj.curList[curObj.index] = 0; } } return curObj; }
//Method performing all the required actions to create the combinations under the most difficult conditions (i.e., more than one variable), that is: perform all the //combinations among variables, exponents and operations; call the methods in charge of creating the corresponding "ValidCombination"; and, eventually, add the new //instance to the list of all the valid combinations so far //NOTA DEL CREADOR: modestia aparte, esta funciĆ³n es una puta obra de arte (en Spanish porque suena mejor :)) private List<ValidCombination> addMulti(List<Input> inputs, List<int> indices, Config curConfig, List<ValidCombination> allCombinations, Variable indepVar) { int[] curExps = new int[indices.Count]; int[] curOpers = new int[indices.Count]; //The code below these lines is fairly complicated as far as it has to deal with many variations (i.e., all the possible combinations among exponents, operations and variables). //In any case, it should be noted that a relevant "combinatorics effort" has already been done before calling this function, that is: setting all the possible combinations of variables. //The combinations are created as shown in the following example (vars: var1, var2, var3; exps: 1, 2; operations: *, +): // var1^1 * var2^1 * var3^1 // var1^1 * var2^1 + var3^1 // var1^1 * var2^1 * var3^2 // var1^1 * var2^1 + var3^2 // var1^1 + var2^1 * var3^1 // var1^1 + var2^1 + var3^1 // var1^1 + var2^1 * var3^2 //etc. ExpRelUpdate obj1 = new ExpRelUpdate(indices.Count - 2, curConfig.exponents.Count - 1, indices.Count, curExps); curExps[obj1.index] = -1; while (!obj1.completed) { obj1 = updateObjs13(obj1, true); if (obj1.completed) break; ExpRelUpdate obj2 = new ExpRelUpdate(indices.Count - 2, curConfig.exponents.Count - 1, indices.Count, curExps); while (!obj2.completed) { for (int i = 0; i < indices.Count; i++) { curOpers[i] = 0; } ExpRelUpdate obj3 = new ExpRelUpdate(indices.Count - 2, curConfig.operations.Count - 1, indices.Count, curOpers); curOpers[obj3.index] = -1; while (!obj3.completed) { obj3 = updateObjs13(obj3, false); if (obj3.completed) break; for (int exp = 0; exp < curConfig.exponents.Count; exp++) { if (cancelSim) break; curExps[indices.Count - 1] = exp; allCombinations = internalLoop(curOpers, curExps, allCombinations, curConfig, indices, inputs, indepVar); } } obj2 = updateObj2(obj2); if (obj2.otherProp) { obj1.completed = true; break; } } } return allCombinations; }