//Method called from the main combinatorics loops for multivariate cases above (addMulti). Its whole purpose is reducing the size of the loops.
        //It includes the "more internal loops", the ones creating the corresponding ValidCombination and adding it to the list of all the combinations so far
        private List<ValidCombination> internalLoop(int[] curOpers, int[] curExps, List<ValidCombination> allCombinations, Config curConfig, List<int> indices, List<Input> inputs, Variable indepVar)
        {
            for (int rel = 0; rel < curConfig.operations.Count; rel++)
            {
                if (cancelSim) return allCombinations;

                Combination curCombination = new Combination();
                curOpers[indices.Count - 2] = rel;

                for (int i = 0; i < indices.Count; i++)
                {
                    int genIndex = indices[i];

                    //The cast to decimal type is included in order to avoid problems with the double floating point (e.g., without casting to decimal, 10.55 wouldn't be found)
                    int maxDec = inputs[genIndex].vals.Max(x => x <= Int32.MaxValue ? ((decimal)x - Convert.ToInt32((decimal)x)).ToString().Length - 2 : 0);
                    if (maxDec < 0) maxDec = 0;

                    Variable curVariable = new Variable { index = genIndex, input = inputs[genIndex], noDec = maxDec };
                    CombinationItem curItem = new CombinationItem() { variable = curVariable, exponent = curConfig.exponents[curExps[i]], operation = curConfig.operations[curOpers[i]] };
                    curCombination.items.Add(curItem);
                }

                allCombinations = addToAllCombinations(curCombination, inputs, curConfig, allCombinations, indepVar);
            }

            return allCombinations;
        }
        //Method actually creating a new ValidCombination variable and performing preliminary validity checks
        private ValidCombination newCombination(Combination curCombination, Variable yVar, List<Input> inputs, List<ValidCombination> allValidCombinations, Config curConfig)
        {
            //Performing the regression and the corresponding analysis to determine whether this specific combination should be stored or not
            CombValues xVals = Common.getCombinationListVals(curCombination, inputs);
            CombValues yVals = new CombValues();
            yVals.combination = new Combination();
            int maxDec = inputs[yVar.index].vals.Max(x => x <= Int32.MaxValue ? ((decimal)x - Convert.ToInt32((decimal)x)).ToString().Length - 2 : 0);
            if (maxDec < 0) maxDec = 0;

            Variable curVariable = new Variable() { index = yVar.index, input = inputs[yVar.index], noDec = maxDec };
            CombinationItem curItem = new CombinationItem() { variable = curVariable, operation = new Operation(), exponent = 1.0 };
            yVals.combination.items.Add(curItem);

            for (int row = 0; row < inputs[yVar.index].vals.Count; row++)
            {
                RowVal curRowVal = new RowVal();
                curRowVal.value = inputs[yVar.index].vals[row];
                curRowVal.weights.Add(1.0);
                yVals.values.Add(curRowVal);
            }

            Analysis curAnalysis = new Analysis();
            ValidCombination curValidCombination = curAnalysis.createValidComb(curCombination, inputs, xVals, yVals, curConfig, true);

            if (curValidCombination != null && allValidCombinations.Count > 0)
            {
                if (alreadyStored(curValidCombination, allValidCombinations))
                {
                    curValidCombination = null;
                }
            }

            return curValidCombination;
        }
        //Method in charge of putting together all the inputs for the given combination (i.e., variables, exponents and operations) and bring together all the remaining factors (e.g., suitability of the fit)
        //to form the associated ValidCombination and add it to the list of valid combinations created so far
        private List<ValidCombination> addCombination(List<Input> inputs, List<int> indices, Config curConfig, List<ValidCombination> allCombinations, Variable indepVar)
        {
            if (indices.Count == 1)
            {
                //Only one variable is accounted for and thus the whole combinatorial process will consist in accounting for the different exponents
                int genIndex = indices[0];

                for (int i = 0; i < curConfig.exponents.Count; i++)
                {
                    if (cancelSim) break;

                    Combination curCombination = new Combination();

                    //The cast to decimal type is included in order to avoid problems from the double floating point (e.g., 10.55)
                    int maxDec = inputs[genIndex].vals.Max(x => x <= Int32.MaxValue ? ((decimal)x - Convert.ToInt32((decimal)x)).ToString().Length - 2 : 0);
                    if (maxDec < 0) maxDec = 0;
                    Variable curVariable = new Variable { index = genIndex, input = inputs[genIndex], noDec = maxDec };
                    CombinationItem curItem = new CombinationItem() { variable = curVariable, exponent = curConfig.exponents[i], operation = curConfig.operations[0] };
                    curCombination.items.Add(curItem);

                    allCombinations = addToAllCombinations(curCombination, inputs, curConfig, allCombinations, indepVar);
                }
            }
            else
            {
                //Various variables are accounted for and thus everything (i.e., variables, exponents & operations) have to be brought into picture
                allCombinations = addMulti(inputs, indices, curConfig, allCombinations, indepVar);
            }

            return allCombinations;
        }