public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable <int> rows, bool applyLinearScaling)
        {
            IEnumerable <double>  estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
            IEnumerable <double>  targetValues    = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
            OnlineCalculatorError errorState;

            double mae;

            if (applyLinearScaling)
            {
                var maeCalculator = new OnlineMeanAbsoluteErrorCalculator();
                CalculateWithScaling(targetValues, estimatedValues, lowerEstimationLimit, upperEstimationLimit, maeCalculator, problemData.Dataset.Rows);
                errorState = maeCalculator.ErrorState;
                mae        = maeCalculator.MeanAbsoluteError;
            }
            else
            {
                IEnumerable <double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
                mae = OnlineMeanAbsoluteErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
            }
            if (errorState != OnlineCalculatorError.None)
            {
                return(double.NaN);
            }
            return(mae);
        }
        /// <summary>
        /// Takes two parent individuals P0 and P1.
        /// Randomly choose a node i from the first parent, then get a node j from the second parent that matches the semantic similarity criteria.
        /// </summary>
        public static ISymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionTree parent0, ISymbolicExpressionTree parent1, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
                                                    T problemData, List <int> rows, int maxDepth, int maxLength, DoubleRange range)
        {
            var crossoverPoints0 = new List <CutPoint>();

            parent0.Root.ForEachNodePostfix((n) => {
                if (n.Parent != null && n.Parent != parent0.Root)
                {
                    crossoverPoints0.Add(new CutPoint(n.Parent, n));
                }
            });

            var crossoverPoint0 = crossoverPoints0.SampleRandom(random);
            int level           = parent0.Root.GetBranchLevel(crossoverPoint0.Child);
            int length          = parent0.Root.GetLength() - crossoverPoint0.Child.GetLength();

            var allowedBranches = new List <ISymbolicExpressionTreeNode>();

            parent1.Root.ForEachNodePostfix((n) => {
                if (n.Parent != null && n.Parent != parent1.Root)
                {
                    if (n.GetDepth() + level <= maxDepth && n.GetLength() + length <= maxLength && crossoverPoint0.IsMatchingPointType(n))
                    {
                        allowedBranches.Add(n);
                    }
                }
            });

            if (allowedBranches.Count == 0)
            {
                return(parent0);
            }

            var dataset = problemData.Dataset;

            // create symbols in order to improvize an ad-hoc tree so that the child can be evaluated
            var           rootSymbol       = new ProgramRootSymbol();
            var           startSymbol      = new StartSymbol();
            var           tree0            = CreateTreeFromNode(random, crossoverPoint0.Child, rootSymbol, startSymbol);
            List <double> estimatedValues0 = interpreter.GetSymbolicExpressionTreeValues(tree0, dataset, rows).ToList();

            crossoverPoint0.Child.Parent = crossoverPoint0.Parent; // restore parent
            ISymbolicExpressionTreeNode selectedBranch = null;

            // pick the first node that fulfills the semantic similarity conditions
            foreach (var node in allowedBranches)
            {
                var           parent           = node.Parent;
                var           tree1            = CreateTreeFromNode(random, node, startSymbol, rootSymbol); // this will affect node.Parent
                List <double> estimatedValues1 = interpreter.GetSymbolicExpressionTreeValues(tree1, dataset, rows).ToList();
                node.Parent = parent;                                                                       // restore parent

                OnlineCalculatorError errorState;
                double ssd = OnlineMeanAbsoluteErrorCalculator.Calculate(estimatedValues0, estimatedValues1, out errorState);

                if (range.Start <= ssd && ssd <= range.End)
                {
                    selectedBranch = node;
                    break;
                }
            }

            // perform the actual swap
            if (selectedBranch != null)
            {
                Swap(crossoverPoint0, selectedBranch);
            }
            return(parent0);
        }
        protected override void Run()
        {
            IRegressionProblemData problemData            = Problem.ProblemData;
            IEnumerable <string>   selectedInputVariables = problemData.AllowedInputVariables;
            int nSv;
            ISupportVectorMachineModel model;

            Run(problemData, selectedInputVariables, SvmType.Value, KernelType.Value, Cost.Value, Nu.Value, Gamma.Value, Epsilon.Value, Degree.Value, out model, out nSv);

            if (CreateSolution)
            {
                var solution = new SupportVectorRegressionSolution((SupportVectorMachineModel)model, (IRegressionProblemData)problemData.Clone());
                Results.Add(new Result("Support vector regression solution", "The support vector regression solution.", solution));
            }

            Results.Add(new Result("Number of support vectors", "The number of support vectors of the SVR solution.", new IntValue(nSv)));


            {
                // calculate regression model metrics
                var ds         = problemData.Dataset;
                var trainRows  = problemData.TrainingIndices;
                var testRows   = problemData.TestIndices;
                var yTrain     = ds.GetDoubleValues(problemData.TargetVariable, trainRows);
                var yTest      = ds.GetDoubleValues(problemData.TargetVariable, testRows);
                var yPredTrain = model.GetEstimatedValues(ds, trainRows).ToArray();
                var yPredTest  = model.GetEstimatedValues(ds, testRows).ToArray();

                OnlineCalculatorError error;
                var trainMse = OnlineMeanSquaredErrorCalculator.Calculate(yPredTrain, yTrain, out error);
                if (error != OnlineCalculatorError.None)
                {
                    trainMse = double.MaxValue;
                }
                var testMse = OnlineMeanSquaredErrorCalculator.Calculate(yPredTest, yTest, out error);
                if (error != OnlineCalculatorError.None)
                {
                    testMse = double.MaxValue;
                }

                Results.Add(new Result("Mean squared error (training)", "The mean of squared errors of the SVR solution on the training partition.", new DoubleValue(trainMse)));
                Results.Add(new Result("Mean squared error (test)", "The mean of squared errors of the SVR solution on the test partition.", new DoubleValue(testMse)));


                var trainMae = OnlineMeanAbsoluteErrorCalculator.Calculate(yPredTrain, yTrain, out error);
                if (error != OnlineCalculatorError.None)
                {
                    trainMae = double.MaxValue;
                }
                var testMae = OnlineMeanAbsoluteErrorCalculator.Calculate(yPredTest, yTest, out error);
                if (error != OnlineCalculatorError.None)
                {
                    testMae = double.MaxValue;
                }

                Results.Add(new Result("Mean absolute error (training)", "The mean of absolute errors of the SVR solution on the training partition.", new DoubleValue(trainMae)));
                Results.Add(new Result("Mean absolute error (test)", "The mean of absolute errors of the SVR solution on the test partition.", new DoubleValue(testMae)));


                var trainRelErr = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(yPredTrain, yTrain, out error);
                if (error != OnlineCalculatorError.None)
                {
                    trainRelErr = double.MaxValue;
                }
                var testRelErr = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(yPredTest, yTest, out error);
                if (error != OnlineCalculatorError.None)
                {
                    testRelErr = double.MaxValue;
                }

                Results.Add(new Result("Average relative error (training)", "The mean of relative errors of the SVR solution on the training partition.", new DoubleValue(trainRelErr)));
                Results.Add(new Result("Average relative error (test)", "The mean of relative errors of the SVR solution on the test partition.", new DoubleValue(testRelErr)));
            }
        }