protected static double CalculateReplacementValue(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
                                                          IDataset dataset, IEnumerable <int> rows)
        {
            //optimization: constant nodes return always the same value
            ConstantTreeNode constantNode = node as ConstantTreeNode;

            if (constantNode != null)
            {
                return(constantNode.Value);
            }

            var rootSymbol  = new ProgramRootSymbol().CreateTreeNode();
            var startSymbol = new StartSymbol().CreateTreeNode();

            rootSymbol.AddSubtree(startSymbol);
            startSymbol.AddSubtree((ISymbolicExpressionTreeNode)node.Clone());

            var tempTree = new SymbolicExpressionTree(rootSymbol);

            // clone ADFs of source tree
            for (int i = 1; i < sourceTree.Root.SubtreeCount; i++)
            {
                tempTree.Root.AddSubtree((ISymbolicExpressionTreeNode)sourceTree.Root.GetSubtree(i).Clone());
            }
            return(interpreter.GetSymbolicExpressionTreeValues(tempTree, dataset, rows).Median());
        }
Beispiel #2
0
        public static ISymbolicExpressionTree CreateTree(
            IEnumerable <KeyValuePair <string, IEnumerable <string> > > factors, double[] factorCoefficients,
            string[] variableNames, double[] coefficients,
            double @const = 0)
        {
            if (factorCoefficients.Length == 0 && coefficients.Length == 0 && @const == 0)
            {
                throw new ArgumentException();
            }

            // Combine both trees
            ISymbolicExpressionTreeNode add = (new Addition()).CreateTreeNode();

            // Create tree for double variables
            if (coefficients.Length > 0)
            {
                var varTree = CreateTree(variableNames, new int[variableNames.Length], coefficients);
                foreach (var varNode in varTree.IterateNodesPrefix().OfType <VariableTreeNode>())
                {
                    add.AddSubtree(varNode);
                }
            }

            // Create tree for string variables
            if (factorCoefficients.Length > 0)
            {
                var factorTree = CreateTree(factors, factorCoefficients);
                foreach (var binFactorNode in factorTree.IterateNodesPrefix().OfType <BinaryFactorVariableTreeNode>())
                {
                    add.AddSubtree(binFactorNode);
                }
            }

            if (@const != 0.0)
            {
                ConstantTreeNode cNode = (ConstantTreeNode) new Constant().CreateTreeNode();
                cNode.Value = @const;
                add.AddSubtree(cNode);
            }

            ISymbolicExpressionTree     tree      = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
            ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();

            tree.Root.AddSubtree(startNode);
            startNode.AddSubtree(add);
            return(tree);
        }
Beispiel #3
0
        public static ISymbolicExpressionTree CreateTree(string[] variableNames, int[] lags, double[] coefficients,
                                                         double @const = 0)
        {
            if (variableNames.Length == 0 ||
                variableNames.Length != coefficients.Length ||
                variableNames.Length != lags.Length)
            {
                throw new ArgumentException("The length of the variable names, lags, and coefficients vectors must match");
            }

            ISymbolicExpressionTree     tree      = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
            ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();

            tree.Root.AddSubtree(startNode);
            ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();

            startNode.AddSubtree(addition);

            for (int i = 0; i < variableNames.Length; i++)
            {
                if (lags[i] == 0)
                {
                    VariableTreeNode vNode = (VariableTreeNode) new Variable().CreateTreeNode();
                    vNode.VariableName = variableNames[i];
                    vNode.Weight       = coefficients[i];
                    addition.AddSubtree(vNode);
                }
                else
                {
                    LaggedVariableTreeNode vNode = (LaggedVariableTreeNode) new LaggedVariable().CreateTreeNode();
                    vNode.VariableName = variableNames[i];
                    vNode.Weight       = coefficients[i];
                    vNode.Lag          = lags[i];
                    addition.AddSubtree(vNode);
                }
            }

            if ([email protected](0.0))
            {
                ConstantTreeNode cNode = (ConstantTreeNode) new Constant().CreateTreeNode();
                cNode.Value = @const;
                addition.AddSubtree(cNode);
            }
            return(tree);
        }
        protected IEnumerable <double> CalculateReplacementValues(ISymbolicExpressionTreeNode node, ISymbolicExpressionTree sourceTree, ISymbolicDataAnalysisExpressionTreeInterpreter interpreter,
                                                                  IDataset dataset, IEnumerable <int> rows)
        {
            //optimization: constant nodes return always the same value
            ConstantTreeNode             constantNode     = node as ConstantTreeNode;
            BinaryFactorVariableTreeNode binaryFactorNode = node as BinaryFactorVariableTreeNode;
            FactorVariableTreeNode       factorNode       = node as FactorVariableTreeNode;

            if (constantNode != null)
            {
                yield return(constantNode.Value);
            }
            else if (binaryFactorNode != null)
            {
                // valid replacements are either all off or all on
                yield return(0);

                yield return(1);
            }
            else if (factorNode != null)
            {
                foreach (var w in factorNode.Weights)
                {
                    yield return(w);
                }
                yield return(0.0);
            }
            else
            {
                var rootSymbol  = new ProgramRootSymbol().CreateTreeNode();
                var startSymbol = new StartSymbol().CreateTreeNode();
                rootSymbol.AddSubtree(startSymbol);
                startSymbol.AddSubtree((ISymbolicExpressionTreeNode)node.Clone());

                var tempTree = new SymbolicExpressionTree(rootSymbol);
                // clone ADFs of source tree
                for (int i = 1; i < sourceTree.Root.SubtreeCount; i++)
                {
                    tempTree.Root.AddSubtree((ISymbolicExpressionTreeNode)sourceTree.Root.GetSubtree(i).Clone());
                }
                yield return(interpreter.GetSymbolicExpressionTreeValues(tempTree, dataset, rows).Median());

                yield return(interpreter.GetSymbolicExpressionTreeValues(tempTree, dataset, rows).Average()); // TODO perf
            }
        }
        public virtual void CalculateImpactAndReplacementValues(ISymbolicDataAnalysisModel model, ISymbolicExpressionTreeNode node, IDataAnalysisProblemData problemData, IEnumerable <int> rows,
                                                                out double impactValue, out double replacementValue, out double newQualityForImpactsCalculation,
                                                                double qualityForImpactsCalculation = double.NaN)
        {
            if (double.IsNaN(qualityForImpactsCalculation))
            {
                qualityForImpactsCalculation = CalculateQualityForImpacts(model, problemData, rows);
            }

            var cloner        = new Cloner();
            var tempModel     = cloner.Clone(model);
            var tempModelNode = (ISymbolicExpressionTreeNode)cloner.GetClone(node);

            var tempModelParentNode = tempModelNode.Parent;
            int i = tempModelParentNode.IndexOfSubtree(tempModelNode);

            double bestReplacementValue = 0.0;
            double bestImpactValue      = double.PositiveInfinity;

            newQualityForImpactsCalculation = qualityForImpactsCalculation; // initialize
            // try the potentially reasonable replacement values and use the best one
            foreach (var repValue in CalculateReplacementValues(node, model.SymbolicExpressionTree, model.Interpreter, problemData.Dataset, problemData.TrainingIndices))
            {
                tempModelParentNode.RemoveSubtree(i);

                var constantNode = new ConstantTreeNode(new Constant())
                {
                    Value = repValue
                };
                tempModelParentNode.InsertSubtree(i, constantNode);

                newQualityForImpactsCalculation = CalculateQualityForImpacts(tempModel, problemData, rows);

                impactValue = qualityForImpactsCalculation - newQualityForImpactsCalculation;
                if (impactValue < bestImpactValue)
                {
                    bestImpactValue      = impactValue;
                    bestReplacementValue = repValue;
                }
            }

            replacementValue = bestReplacementValue;
            impactValue      = bestImpactValue;
        }
Beispiel #6
0
        public static ISymbolicExpressionTree CreateTree(IEnumerable <KeyValuePair <string, IEnumerable <string> > > factors,
                                                         double[] factorCoefficients,
                                                         double @const = 0)
        {
            ISymbolicExpressionTree     tree      = new SymbolicExpressionTree(new ProgramRootSymbol().CreateTreeNode());
            ISymbolicExpressionTreeNode startNode = new StartSymbol().CreateTreeNode();

            tree.Root.AddSubtree(startNode);
            ISymbolicExpressionTreeNode addition = new Addition().CreateTreeNode();

            startNode.AddSubtree(addition);

            int i = 0;

            foreach (var factor in factors)
            {
                var varName = factor.Key;
                foreach (var factorValue in factor.Value)
                {
                    var node = (BinaryFactorVariableTreeNode) new BinaryFactorVariable().CreateTreeNode();
                    node.VariableValue = factorValue;
                    node.VariableName  = varName;
                    node.Weight        = factorCoefficients[i];
                    addition.AddSubtree(node);
                    i++;
                }
            }

            if ([email protected](0.0))
            {
                ConstantTreeNode cNode = (ConstantTreeNode) new Constant().CreateTreeNode();
                cNode.Value = @const;
                addition.AddSubtree(cNode);
            }
            return(tree);
        }
Beispiel #7
0
        private void CompileInstructions(ILGenerator il, InterpreterState state, IDataset ds)
        {
            Instruction currentInstr = state.NextInstruction();
            int         nArgs        = currentInstr.nArguments;

            switch (currentInstr.opCode)
            {
            case OpCodes.Add: {
                if (nArgs > 0)
                {
                    CompileInstructions(il, state, ds);
                }
                for (int i = 1; i < nArgs; i++)
                {
                    CompileInstructions(il, state, ds);
                    il.Emit(System.Reflection.Emit.OpCodes.Add);
                }
                return;
            }

            case OpCodes.Sub: {
                if (nArgs == 1)
                {
                    CompileInstructions(il, state, ds);
                    il.Emit(System.Reflection.Emit.OpCodes.Neg);
                    return;
                }
                if (nArgs > 0)
                {
                    CompileInstructions(il, state, ds);
                }
                for (int i = 1; i < nArgs; i++)
                {
                    CompileInstructions(il, state, ds);
                    il.Emit(System.Reflection.Emit.OpCodes.Sub);
                }
                return;
            }

            case OpCodes.Mul: {
                if (nArgs > 0)
                {
                    CompileInstructions(il, state, ds);
                }
                for (int i = 1; i < nArgs; i++)
                {
                    CompileInstructions(il, state, ds);
                    il.Emit(System.Reflection.Emit.OpCodes.Mul);
                }
                return;
            }

            case OpCodes.Div: {
                if (nArgs == 1)
                {
                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0);
                    CompileInstructions(il, state, ds);
                    il.Emit(System.Reflection.Emit.OpCodes.Div);
                    return;
                }
                if (nArgs > 0)
                {
                    CompileInstructions(il, state, ds);
                }
                for (int i = 1; i < nArgs; i++)
                {
                    CompileInstructions(il, state, ds);
                    il.Emit(System.Reflection.Emit.OpCodes.Div);
                }
                return;
            }

            case OpCodes.Average: {
                CompileInstructions(il, state, ds);
                for (int i = 1; i < nArgs; i++)
                {
                    CompileInstructions(il, state, ds);
                    il.Emit(System.Reflection.Emit.OpCodes.Add);
                }
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, nArgs);
                il.Emit(System.Reflection.Emit.OpCodes.Div);
                return;
            }

            case OpCodes.Cos: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, cos);
                return;
            }

            case OpCodes.Sin: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, sin);
                return;
            }

            case OpCodes.Tan: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, tan);
                return;
            }

            case OpCodes.Power: {
                CompileInstructions(il, state, ds);
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, round);
                il.Emit(System.Reflection.Emit.OpCodes.Call, power);
                return;
            }

            case OpCodes.Root: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // 1 / round(...)
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, round);
                il.Emit(System.Reflection.Emit.OpCodes.Div);
                il.Emit(System.Reflection.Emit.OpCodes.Call, power);
                return;
            }

            case OpCodes.Exp: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, exp);
                return;
            }

            case OpCodes.Log: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, log);
                return;
            }

            case OpCodes.Square: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0);
                il.Emit(System.Reflection.Emit.OpCodes.Call, power);
                return;
            }

            case OpCodes.SquareRoot: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, sqrt);
                return;
            }

            case OpCodes.AiryA: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, airyA);
                return;
            }

            case OpCodes.AiryB: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, airyB);
                return;
            }

            case OpCodes.Bessel: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, bessel);
                return;
            }

            case OpCodes.CosineIntegral: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, cosIntegral);
                return;
            }

            case OpCodes.Dawson: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, dawson);
                return;
            }

            case OpCodes.Erf: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, erf);
                return;
            }

            case OpCodes.ExponentialIntegralEi: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, expIntegralEi);
                return;
            }

            case OpCodes.FresnelCosineIntegral: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, fresnelCosIntegral);
                return;
            }

            case OpCodes.FresnelSineIntegral: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, fresnelSinIntegral);
                return;
            }

            case OpCodes.Gamma: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, gamma);
                return;
            }

            case OpCodes.HyperbolicCosineIntegral: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, hypCosIntegral);
                return;
            }

            case OpCodes.HyperbolicSineIntegral: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, hypSinIntegral);
                return;
            }

            case OpCodes.Norm: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, norm);
                return;
            }

            case OpCodes.Psi: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, psi);
                return;
            }

            case OpCodes.SineIntegral: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Call, sinIntegral);
                return;
            }

            case OpCodes.IfThenElse: {
                Label end = il.DefineLabel();
                Label c1  = il.DefineLabel();
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
                il.Emit(System.Reflection.Emit.OpCodes.Cgt);
                il.Emit(System.Reflection.Emit.OpCodes.Brfalse, c1);
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Br, end);
                il.MarkLabel(c1);
                CompileInstructions(il, state, ds);
                il.MarkLabel(end);
                return;
            }

            case OpCodes.AND: {
                Label falseBranch = il.DefineLabel();
                Label end         = il.DefineLabel();
                CompileInstructions(il, state, ds);
                for (int i = 1; i < nArgs; i++)
                {
                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
                    il.Emit(System.Reflection.Emit.OpCodes.Cgt);
                    il.Emit(System.Reflection.Emit.OpCodes.Brfalse, falseBranch);
                    CompileInstructions(il, state, ds);
                }
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
                il.Emit(System.Reflection.Emit.OpCodes.Cgt);
                il.Emit(System.Reflection.Emit.OpCodes.Brfalse, falseBranch);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // 1
                il.Emit(System.Reflection.Emit.OpCodes.Br, end);
                il.MarkLabel(falseBranch);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // -1
                il.Emit(System.Reflection.Emit.OpCodes.Neg);
                il.MarkLabel(end);
                return;
            }

            case OpCodes.OR: {
                Label trueBranch   = il.DefineLabel();
                Label end          = il.DefineLabel();
                Label resultBranch = il.DefineLabel();
                CompileInstructions(il, state, ds);
                for (int i = 1; i < nArgs; i++)
                {
                    Label nextArgBranch = il.DefineLabel();
                    // complex definition because of special properties of NaN
                    il.Emit(System.Reflection.Emit.OpCodes.Dup);
                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // <= 0
                    il.Emit(System.Reflection.Emit.OpCodes.Ble, nextArgBranch);
                    il.Emit(System.Reflection.Emit.OpCodes.Br, resultBranch);
                    il.MarkLabel(nextArgBranch);
                    il.Emit(System.Reflection.Emit.OpCodes.Pop);
                    CompileInstructions(il, state, ds);
                }
                il.MarkLabel(resultBranch);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0); // > 0
                il.Emit(System.Reflection.Emit.OpCodes.Cgt);
                il.Emit(System.Reflection.Emit.OpCodes.Brtrue, trueBranch);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // -1
                il.Emit(System.Reflection.Emit.OpCodes.Neg);
                il.Emit(System.Reflection.Emit.OpCodes.Br, end);
                il.MarkLabel(trueBranch);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // 1
                il.MarkLabel(end);
                return;
            }

            case OpCodes.NOT: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);    // > 0
                il.Emit(System.Reflection.Emit.OpCodes.Cgt);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // * 2
                il.Emit(System.Reflection.Emit.OpCodes.Mul);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // - 1
                il.Emit(System.Reflection.Emit.OpCodes.Sub);
                il.Emit(System.Reflection.Emit.OpCodes.Neg);         // * -1
                return;
            }

            case OpCodes.XOR: {
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
                il.Emit(System.Reflection.Emit.OpCodes.Cgt);// > 0

                for (int i = 1; i < nArgs; i++)
                {
                    CompileInstructions(il, state, ds);
                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
                    il.Emit(System.Reflection.Emit.OpCodes.Cgt);// > 0
                    il.Emit(System.Reflection.Emit.OpCodes.Xor);
                }
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // * 2
                il.Emit(System.Reflection.Emit.OpCodes.Mul);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // - 1
                il.Emit(System.Reflection.Emit.OpCodes.Sub);
                return;
            }

            case OpCodes.GT: {
                CompileInstructions(il, state, ds);
                CompileInstructions(il, state, ds);

                il.Emit(System.Reflection.Emit.OpCodes.Cgt);         // 1 (>) / 0 (otherwise)
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // * 2
                il.Emit(System.Reflection.Emit.OpCodes.Mul);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // - 1
                il.Emit(System.Reflection.Emit.OpCodes.Sub);
                return;
            }

            case OpCodes.LT: {
                CompileInstructions(il, state, ds);
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Clt);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // * 2
                il.Emit(System.Reflection.Emit.OpCodes.Mul);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 1.0); // - 1
                il.Emit(System.Reflection.Emit.OpCodes.Sub);
                return;
            }

            case OpCodes.TimeLag: {
                LaggedTreeNode laggedTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row -= lag
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, laggedTreeNode.Lag);
                il.Emit(System.Reflection.Emit.OpCodes.Add);
                il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
                var prevLaggedContext = state.InLaggedContext;
                state.InLaggedContext = true;
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row += lag
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, laggedTreeNode.Lag);
                il.Emit(System.Reflection.Emit.OpCodes.Sub);
                il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
                state.InLaggedContext = prevLaggedContext;
                return;
            }

            case OpCodes.Integral: {
                int            savedPc        = state.ProgramCounter;
                LaggedTreeNode laggedTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row -= lag
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, laggedTreeNode.Lag);
                il.Emit(System.Reflection.Emit.OpCodes.Add);
                il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
                var prevLaggedContext = state.InLaggedContext;
                state.InLaggedContext = true;
                CompileInstructions(il, state, ds);
                for (int l = laggedTreeNode.Lag; l < 0; l++)
                {
                    il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row += lag
                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_1);
                    il.Emit(System.Reflection.Emit.OpCodes.Add);
                    il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
                    state.ProgramCounter = savedPc;
                    CompileInstructions(il, state, ds);
                    il.Emit(System.Reflection.Emit.OpCodes.Add);
                }
                state.InLaggedContext = prevLaggedContext;
                return;
            }

            //mkommend: derivate calculation taken from:
            //http://www.holoborodko.com/pavel/numerical-methods/numerical-derivative/smooth-low-noise-differentiators/
            //one sided smooth differentiatior, N = 4
            // y' = 1/8h (f_i + 2f_i-1, -2 f_i-3 - f_i-4)
            case OpCodes.Derivative: {
                int savedPc = state.ProgramCounter;
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row --
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_M1);
                il.Emit(System.Reflection.Emit.OpCodes.Add);
                il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
                state.ProgramCounter = savedPc;
                var prevLaggedContext = state.InLaggedContext;
                state.InLaggedContext = true;
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // f_0 + 2 * f_1
                il.Emit(System.Reflection.Emit.OpCodes.Mul);
                il.Emit(System.Reflection.Emit.OpCodes.Add);

                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row -=2
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_2);
                il.Emit(System.Reflection.Emit.OpCodes.Sub);
                il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
                state.ProgramCounter = savedPc;
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 2.0); // f_0 + 2 * f_1 - 2 * f_3
                il.Emit(System.Reflection.Emit.OpCodes.Mul);
                il.Emit(System.Reflection.Emit.OpCodes.Sub);

                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row --
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_M1);
                il.Emit(System.Reflection.Emit.OpCodes.Add);
                il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
                state.ProgramCounter = savedPc;
                CompileInstructions(il, state, ds);
                il.Emit(System.Reflection.Emit.OpCodes.Sub);         // f_0 + 2 * f_1 - 2 * f_3 - f_4
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, 8.0); // / 8
                il.Emit(System.Reflection.Emit.OpCodes.Div);

                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // row +=4
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_4);
                il.Emit(System.Reflection.Emit.OpCodes.Add);
                il.Emit(System.Reflection.Emit.OpCodes.Starg, 0);
                state.InLaggedContext = prevLaggedContext;
                return;
            }

            case OpCodes.Call: {
                throw new NotSupportedException(
                          "Automatically defined functions are not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter. Either turn of ADFs or change the interpeter.");
            }

            case OpCodes.Arg: {
                throw new NotSupportedException(
                          "Automatically defined functions are not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter. Either turn of ADFs or change the interpeter.");
            }

            case OpCodes.Variable: {
                VariableTreeNode varNode = (VariableTreeNode)currentInstr.dynamicNode;
                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); // load columns array
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)currentInstr.data);
                // load correct column of the current variable
                il.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);
                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); // rowIndex
                if (!state.InLaggedContext)
                {
                    il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, varNode.Weight); // load weight
                    il.Emit(System.Reflection.Emit.OpCodes.Mul);
                }
                else
                {
                    var nanResult    = il.DefineLabel();
                    var normalResult = il.DefineLabel();
                    il.Emit(System.Reflection.Emit.OpCodes.Dup);
                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
                    il.Emit(System.Reflection.Emit.OpCodes.Blt, nanResult);
                    il.Emit(System.Reflection.Emit.OpCodes.Dup);
                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, ds.Rows);
                    il.Emit(System.Reflection.Emit.OpCodes.Bge, nanResult);
                    il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, varNode.Weight); // load weight
                    il.Emit(System.Reflection.Emit.OpCodes.Mul);
                    il.Emit(System.Reflection.Emit.OpCodes.Br, normalResult);
                    il.MarkLabel(nanResult);
                    il.Emit(System.Reflection.Emit.OpCodes.Pop); // rowIndex
                    il.Emit(System.Reflection.Emit.OpCodes.Pop); // column reference
                    il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, double.NaN);
                    il.MarkLabel(normalResult);
                }
                return;
            }

            case OpCodes.LagVariable: {
                var nanResult    = il.DefineLabel();
                var normalResult = il.DefineLabel();
                LaggedVariableTreeNode varNode = (LaggedVariableTreeNode)currentInstr.dynamicNode;
                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); // load columns array
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, (int)currentInstr.data);
                // load correct column of the current variable
                il.Emit(System.Reflection.Emit.OpCodes.Ldelem_Ref);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, varNode.Lag); // lag
                il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);             // rowIndex
                il.Emit(System.Reflection.Emit.OpCodes.Add);                 // actualRowIndex = rowIndex + sampleOffset
                il.Emit(System.Reflection.Emit.OpCodes.Dup);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4_0);
                il.Emit(System.Reflection.Emit.OpCodes.Blt, nanResult);
                il.Emit(System.Reflection.Emit.OpCodes.Dup);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_I4, ds.Rows);
                il.Emit(System.Reflection.Emit.OpCodes.Bge, nanResult);
                il.Emit(System.Reflection.Emit.OpCodes.Call, listGetValue);
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, varNode.Weight); // load weight
                il.Emit(System.Reflection.Emit.OpCodes.Mul);
                il.Emit(System.Reflection.Emit.OpCodes.Br, normalResult);
                il.MarkLabel(nanResult);
                il.Emit(System.Reflection.Emit.OpCodes.Pop); // sample index
                il.Emit(System.Reflection.Emit.OpCodes.Pop); // column reference
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, double.NaN);
                il.MarkLabel(normalResult);
                return;
            }

            case OpCodes.Constant: {
                ConstantTreeNode constNode = (ConstantTreeNode)currentInstr.dynamicNode;
                il.Emit(System.Reflection.Emit.OpCodes.Ldc_R8, constNode.Value);
                return;
            }

            //mkommend: this symbol uses the logistic function f(x) = 1 / (1 + e^(-alpha * x) )
            //to determine the relative amounts of the true and false branch see http://en.wikipedia.org/wiki/Logistic_function
            case OpCodes.VariableCondition: {
                throw new NotSupportedException("Interpretation of symbol " + currentInstr.dynamicNode.Symbol.Name +
                                                " is not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter");
            }

            default:
                throw new NotSupportedException("Interpretation of symbol " + currentInstr.dynamicNode.Symbol.Name +
                                                " is not supported by the SymbolicDataAnalysisTreeILEmittingInterpreter");
            }
        }
Beispiel #8
0
 private ConstantTreeNode(ConstantTreeNode original, Cloner cloner)
     : base(original, cloner)
 {
     constantValue = original.constantValue;
 }
        private string FormatRecursively(ISymbolicExpressionTreeNode node)
        {
            ISymbol       symbol        = node.Symbol;
            StringBuilder stringBuilder = new StringBuilder();

            if (symbol is ProgramRootSymbol)
            {
                stringBuilder.AppendLine(FormatRecursively(node.GetSubtree(0)));
            }
            else if (symbol is StartSymbol)
            {
                return(FormatRecursively(node.GetSubtree(0)));
            }
            else if (symbol is Addition)
            {
                stringBuilder.Append("(");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("+");
                    }
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                }
                stringBuilder.Append(")");
            }
            else if (symbol is Average)
            {
                stringBuilder.Append("(1/");
                stringBuilder.Append(node.SubtreeCount);
                stringBuilder.Append(")*(");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("+");
                    }
                    stringBuilder.Append("(");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    stringBuilder.Append(")");
                }
                stringBuilder.Append(")");
            }
            else if (symbol is Constant)
            {
                ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
                stringBuilder.Append(constantTreeNode.Value.ToString(CultureInfo.InvariantCulture));
            }
            else if (symbol is Cosine)
            {
                stringBuilder.Append("COS(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Division)
            {
                if (node.SubtreeCount == 1)
                {
                    stringBuilder.Append("1/");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                }
                else
                {
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                    stringBuilder.Append("/(");
                    for (int i = 1; i < node.SubtreeCount; i++)
                    {
                        if (i > 1)
                        {
                            stringBuilder.Append("*");
                        }
                        stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    }
                    stringBuilder.Append(")");
                }
            }
            else if (symbol is Exponential)
            {
                stringBuilder.Append("EXP(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Square)
            {
                stringBuilder.Append("POWER(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(",2)");
            }
            else if (symbol is SquareRoot)
            {
                stringBuilder.Append("SQRT(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Logarithm)
            {
                stringBuilder.Append("LN(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Multiplication)
            {
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("*");
                    }
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                }
            }
            else if (symbol is Sine)
            {
                stringBuilder.Append("SIN(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Subtraction)
            {
                stringBuilder.Append("(");
                if (node.SubtreeCount == 1)
                {
                    stringBuilder.Append("-");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                }
                else
                {
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                    for (int i = 1; i < node.SubtreeCount; i++)
                    {
                        stringBuilder.Append("-");
                        stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    }
                }
                stringBuilder.Append(")");
            }
            else if (symbol is Tangent)
            {
                stringBuilder.Append("TAN(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Variable)
            {
                VariableTreeNode variableTreeNode = node as VariableTreeNode;
                stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
                stringBuilder.Append("*");
                stringBuilder.Append(GetColumnToVariableName(variableTreeNode.VariableName));// + LagToString(currentLag));
            }
            else if (symbol is Power)
            {
                stringBuilder.Append("POWER(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(",ROUND(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append(",0))");
            }
            else if (symbol is Root)
            {
                stringBuilder.Append("(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")^(1 / ROUND(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append(",0))");
            }
            else if (symbol is IfThenElse)
            {
                stringBuilder.Append("IF(");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + " ) > 0");
                stringBuilder.Append(",");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append(",");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(2)));
                stringBuilder.Append(")");
            }
            else if (symbol is VariableCondition)
            {
                VariableConditionTreeNode variableConditionTreeNode = node as VariableConditionTreeNode;
                double threshold = variableConditionTreeNode.Threshold;
                double slope     = variableConditionTreeNode.Slope;
                string p         = "(1 / (1 + EXP(-" + slope.ToString(CultureInfo.InvariantCulture) + " * (" + GetColumnToVariableName(variableConditionTreeNode.VariableName) + "-" + threshold.ToString(CultureInfo.InvariantCulture) + "))))";
                stringBuilder.Append("((");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append("*");
                stringBuilder.Append(p);
                stringBuilder.Append(") + (");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append("*(");
                stringBuilder.Append("1 - " + p + ")");
                stringBuilder.Append("))");
            }
            else if (symbol is Xor)
            {
                stringBuilder.Append("IF(");
                stringBuilder.Append("XOR(");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + ") > 0,");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(1)) + ") > 0");
                stringBuilder.Append("), 1.0, -1.0)");
            }
            else if (symbol is Or)
            {
                stringBuilder.Append("IF(");
                stringBuilder.Append("OR(");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + ") > 0,");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(1)) + ") > 0");
                stringBuilder.Append("), 1.0, -1.0)");
            }
            else if (symbol is And)
            {
                stringBuilder.Append("IF(");
                stringBuilder.Append("AND(");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + ") > 0,");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(1)) + ") > 0");
                stringBuilder.Append("), 1.0, -1.0)");
            }
            else if (symbol is Not)
            {
                stringBuilder.Append("IF(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(" > 0, -1.0, 1.0)");
            }
            else if (symbol is GreaterThan)
            {
                stringBuilder.Append("IF((");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(") > (");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append("), 1.0, -1.0)");
            }
            else if (symbol is LessThan)
            {
                stringBuilder.Append("IF((");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(") < (");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append("), 1.0, -1.0)");
            }
            else
            {
                throw new NotImplementedException("Excel export of " + node.Symbol + " is not implemented.");
            }
            return(stringBuilder.ToString());
        }
        private string FormatRecursively(ISymbolicExpressionTreeNode node)
        {
            ISymbol       symbol        = node.Symbol;
            StringBuilder stringBuilder = new StringBuilder();

            if (symbol is ProgramRootSymbol)
            {
                stringBuilder.AppendLine(FormatRecursively(node.GetSubtree(0)));
            }
            else if (symbol is StartSymbol)
            {
                return(FormatRecursively(node.GetSubtree(0)));
            }
            else if (symbol is Addition)
            {
                stringBuilder.Append("(");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("+");
                    }
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                }
                stringBuilder.Append(")");
            }
            else if (symbol is Absolute)
            {
                stringBuilder.Append($"ABS({FormatRecursively(node.GetSubtree(0))})");
            }
            else if (symbol is AnalyticQuotient)
            {
                stringBuilder.Append($"({FormatRecursively(node.GetSubtree(0))}) / SQRT(1 + POWER({FormatRecursively(node.GetSubtree(1))}, 2))");
            }
            else if (symbol is Average)
            {
                stringBuilder.Append("(1/(");
                stringBuilder.Append(node.SubtreeCount);
                stringBuilder.Append(")*(");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("+");
                    }
                    stringBuilder.Append("(");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    stringBuilder.Append(")");
                }
                stringBuilder.Append("))");
            }
            else if (symbol is Constant)
            {
                ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
                stringBuilder.Append(constantTreeNode.Value.ToString(CultureInfo.InvariantCulture));
            }
            else if (symbol is Cosine)
            {
                stringBuilder.Append("COS(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Cube)
            {
                stringBuilder.Append($"POWER({FormatRecursively(node.GetSubtree(0))}, 3)");
            }
            else if (symbol is CubeRoot)
            {
                var arg_expr = FormatRecursively(node.GetSubtree(0));
                stringBuilder.Append($"IF({arg_expr} < 0, -POWER(-{arg_expr}, 1/3), POWER({arg_expr}, 1/3))");
            }
            else if (symbol is Division)
            {
                if (node.SubtreeCount == 1)
                {
                    stringBuilder.Append("1/(");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                    stringBuilder.Append(")");
                }
                else
                {
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                    stringBuilder.Append("/(");
                    for (int i = 1; i < node.SubtreeCount; i++)
                    {
                        if (i > 1)
                        {
                            stringBuilder.Append("*");
                        }
                        stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    }
                    stringBuilder.Append(")");
                }
            }
            else if (symbol is Exponential)
            {
                stringBuilder.Append("EXP(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Square)
            {
                stringBuilder.Append("POWER(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(",2)");
            }
            else if (symbol is SquareRoot)
            {
                stringBuilder.Append("SQRT(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Logarithm)
            {
                stringBuilder.Append("LN(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Multiplication)
            {
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("*");
                    }
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                }
            }
            else if (symbol is Sine)
            {
                stringBuilder.Append("SIN(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Subtraction)
            {
                stringBuilder.Append("(");
                if (node.SubtreeCount == 1)
                {
                    stringBuilder.Append("-");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                }
                else
                {
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                    for (int i = 1; i < node.SubtreeCount; i++)
                    {
                        stringBuilder.Append("-");
                        stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    }
                }
                stringBuilder.Append(")");
            }
            else if (symbol is Tangent)
            {
                stringBuilder.Append("TAN(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is HyperbolicTangent)
            {
                stringBuilder.Append("TANH(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Variable)
            {
                VariableTreeNode variableTreeNode = node as VariableTreeNode;
                stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
                stringBuilder.Append("*");
                stringBuilder.Append(GetColumnToVariableName(variableTreeNode.VariableName));
            }
            else if (symbol is BinaryFactorVariable)
            {
                var binFactorNode = node as BinaryFactorVariableTreeNode;
                stringBuilder.AppendFormat("IF({0}=\"{1}\", {2}, 0)",
                                           GetColumnToVariableName(binFactorNode.VariableName),
                                           binFactorNode.VariableValue,
                                           binFactorNode.Weight.ToString(CultureInfo.InvariantCulture)
                                           );
            }
            else if (symbol is FactorVariable)
            {
                var factorNode = node as FactorVariableTreeNode;
                var values     = factorNode.Symbol.GetVariableValues(factorNode.VariableName).ToArray();
                var w          = factorNode.Weights;
                // create nested if
                for (int i = 0; i < values.Length; i++)
                {
                    stringBuilder.AppendFormat("IF({0}=\"{1}\", {2}, ",
                                               GetColumnToVariableName(factorNode.VariableName),
                                               values[i],
                                               w[i].ToString(CultureInfo.InvariantCulture));
                }
                stringBuilder.Append("\"\"");             // return empty string on unknown value
                stringBuilder.Append(')', values.Length); // add closing parenthesis
            }
            else if (symbol is Power)
            {
                stringBuilder.Append("POWER(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(",ROUND(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append(",0))");
            }
            else if (symbol is Root)
            {
                stringBuilder.Append("(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")^(1 / ROUND(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append(",0))");
            }
            else if (symbol is IfThenElse)
            {
                stringBuilder.Append("IF(");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + " ) > 0");
                stringBuilder.Append(",");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append(",");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(2)));
                stringBuilder.Append(")");
            }
            else if (symbol is VariableCondition)
            {
                VariableConditionTreeNode variableConditionTreeNode = node as VariableConditionTreeNode;
                if (!variableConditionTreeNode.Symbol.IgnoreSlope)
                {
                    double threshold = variableConditionTreeNode.Threshold;
                    double slope     = variableConditionTreeNode.Slope;
                    string p         = "(1 / (1 + EXP(-" + slope.ToString(CultureInfo.InvariantCulture) + " * (" +
                                       GetColumnToVariableName(variableConditionTreeNode.VariableName) + "-" +
                                       threshold.ToString(CultureInfo.InvariantCulture) + "))))";
                    stringBuilder.Append("((");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                    stringBuilder.Append("*");
                    stringBuilder.Append(p);
                    stringBuilder.Append(") + (");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                    stringBuilder.Append("*(");
                    stringBuilder.Append("1 - " + p + ")");
                    stringBuilder.Append("))");
                }
                else
                {
                    stringBuilder.AppendFormat(CultureInfo.InvariantCulture, "(IF({0} <= {1}, {2}, {3}))",
                                               GetColumnToVariableName(variableConditionTreeNode.VariableName),
                                               variableConditionTreeNode.Threshold,
                                               FormatRecursively(node.GetSubtree(0)),
                                               FormatRecursively(node.GetSubtree(1))
                                               );
                }
            }
            else if (symbol is Xor)
            {
                stringBuilder.Append("IF(");
                stringBuilder.Append("XOR(");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + ") > 0,");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(1)) + ") > 0");
                stringBuilder.Append("), 1.0, -1.0)");
            }
            else if (symbol is Or)
            {
                stringBuilder.Append("IF(");
                stringBuilder.Append("OR(");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + ") > 0,");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(1)) + ") > 0");
                stringBuilder.Append("), 1.0, -1.0)");
            }
            else if (symbol is And)
            {
                stringBuilder.Append("IF(");
                stringBuilder.Append("AND(");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(0)) + ") > 0,");
                stringBuilder.Append("(" + FormatRecursively(node.GetSubtree(1)) + ") > 0");
                stringBuilder.Append("), 1.0, -1.0)");
            }
            else if (symbol is Not)
            {
                stringBuilder.Append("IF(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(" > 0, -1.0, 1.0)");
            }
            else if (symbol is GreaterThan)
            {
                stringBuilder.Append("IF((");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(") > (");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append("), 1.0, -1.0)");
            }
            else if (symbol is LessThan)
            {
                stringBuilder.Append("IF((");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(") < (");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append("), 1.0, -1.0)");
            }
            else
            {
                throw new NotImplementedException("Excel export of " + node.Symbol + " is not implemented.");
            }
            return(stringBuilder.ToString());
        }
Beispiel #11
0
        private string FormatRecursively(ISymbolicExpressionTreeNode node)
        {
            ISymbol       symbol        = node.Symbol;
            StringBuilder stringBuilder = new StringBuilder();

            if (symbol is ProgramRootSymbol)
            {
                stringBuilder.AppendLine(FormatRecursively(node.GetSubtree(0)));
            }
            else if (symbol is StartSymbol)
            {
                return(FormatRecursively(node.GetSubtree(0)));
            }
            else if (symbol is Addition)
            {
                stringBuilder.Append("(");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("+");
                    }
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                }
                stringBuilder.Append(")");
            }
            else if (symbol is And)
            {
                stringBuilder.Append("((");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("&");
                    }
                    stringBuilder.Append("((");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    stringBuilder.Append(")>0)");
                }
                stringBuilder.Append(")-0.5)*2");
                // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp.
            }
            else if (symbol is Average)
            {
                stringBuilder.Append("(1/");
                stringBuilder.Append(node.SubtreeCount);
                stringBuilder.Append(")*(");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("+");
                    }
                    stringBuilder.Append("(");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    stringBuilder.Append(")");
                }
                stringBuilder.Append(")");
            }
            else if (symbol is Constant)
            {
                ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
                stringBuilder.Append(constantTreeNode.Value.ToString(CultureInfo.InvariantCulture));
            }
            else if (symbol is Cosine)
            {
                stringBuilder.Append("cos(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Division)
            {
                if (node.SubtreeCount == 1)
                {
                    stringBuilder.Append("1/");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                }
                else
                {
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                    stringBuilder.Append("/(");
                    for (int i = 1; i < node.SubtreeCount; i++)
                    {
                        if (i > 1)
                        {
                            stringBuilder.Append("*");
                        }
                        stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    }
                    stringBuilder.Append(")");
                }
            }
            else if (symbol is Exponential)
            {
                stringBuilder.Append("exp(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Square)
            {
                stringBuilder.Append("(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(").^2");
            }
            else if (symbol is SquareRoot)
            {
                stringBuilder.Append("sqrt(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is GreaterThan)
            {
                stringBuilder.Append("((");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(">");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append(")-0.5)*2");
                // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp.
            }
            else if (symbol is IfThenElse)
            {
                stringBuilder.Append("(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(">0)*");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append("+");
                stringBuilder.Append("(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append("<=0)*");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(2)));
            }
            else if (symbol is LaggedVariable)
            {
                // this if must be checked before if(symbol is LaggedVariable)
                LaggedVariableTreeNode laggedVariableTreeNode = node as LaggedVariableTreeNode;
                stringBuilder.Append(laggedVariableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
                stringBuilder.Append("*");
                stringBuilder.Append(laggedVariableTreeNode.VariableName +
                                     LagToString(currentLag + laggedVariableTreeNode.Lag));
            }
            else if (symbol is LessThan)
            {
                stringBuilder.Append("((");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append("<");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append(")-0.5)*2");
                // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp.
            }
            else if (symbol is Logarithm)
            {
                stringBuilder.Append("log_(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Multiplication)
            {
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("*");
                    }
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                }
            }
            else if (symbol is Not)
            {
                stringBuilder.Append("~(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(" > 0 )");
            }
            else if (symbol is Or)
            {
                stringBuilder.Append("((");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("|");
                    }
                    stringBuilder.Append("((");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    stringBuilder.Append(")>0)");
                }
                stringBuilder.Append(")-0.5)*2");
                // MATLAB maps false and true to 0 and 1, resp., we map this result to -1.0 and +1.0, resp.
            }
            else if (symbol is Sine)
            {
                stringBuilder.Append("sin(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is Subtraction)
            {
                stringBuilder.Append("(");
                if (node.SubtreeCount == 1)
                {
                    stringBuilder.Append("-");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                }
                else
                {
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                    for (int i = 1; i < node.SubtreeCount; i++)
                    {
                        stringBuilder.Append("-");
                        stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    }
                }
                stringBuilder.Append(")");
            }
            else if (symbol is Tangent)
            {
                stringBuilder.Append("tan(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is AiryA)
            {
                stringBuilder.Append("airy(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is AiryB)
            {
                stringBuilder.Append("airy(2, ");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is Bessel)
            {
                stringBuilder.Append("besseli(0.0,");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is CosineIntegral)
            {
                stringBuilder.Append("cosint(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is Dawson)
            {
                stringBuilder.Append("dawson(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is Erf)
            {
                stringBuilder.Append("erf(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is ExponentialIntegralEi)
            {
                stringBuilder.Append("expint(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is FresnelCosineIntegral)
            {
                stringBuilder.Append("FresnelC(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is FresnelSineIntegral)
            {
                stringBuilder.Append("FresnelS(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is Gamma)
            {
                stringBuilder.Append("gamma(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is HyperbolicCosineIntegral)
            {
                stringBuilder.Append("Chi(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is HyperbolicSineIntegral)
            {
                stringBuilder.Append("Shi(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is Norm)
            {
                stringBuilder.Append("normpdf(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is Psi)
            {
                stringBuilder.Append("psi(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (node.Symbol is SineIntegral)
            {
                stringBuilder.Append("sinint(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
            }
            else if (symbol is HeuristicLab.Problems.DataAnalysis.Symbolic.Variable)
            {
                VariableTreeNode variableTreeNode = node as VariableTreeNode;
                stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
                stringBuilder.Append("*");
                stringBuilder.Append(variableTreeNode.VariableName + LagToString(currentLag));
            }
            else if (symbol is Power)
            {
                stringBuilder.Append("(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")^round(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append(")");
            }
            else if (symbol is Root)
            {
                stringBuilder.Append("(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")^(1 / round(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append("))");
            }
            else if (symbol is Derivative)
            {
                stringBuilder.Append("fivePoint(");
                // f0
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(", ");
                // f1
                currentLag--;
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(", ");
                // f3
                currentLag -= 2;
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(", ");
                currentLag--;
                // f4
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(")");
                currentLag += 4;
            }
            else if (symbol is Integral)
            {
                var    laggedNode          = node as LaggedTreeNode;
                string prevCounterVariable = CurrentIndexVariable;
                string counterVariable     = AllocateIndexVariable();
                stringBuilder.AppendLine(" sum (map(@(" + counterVariable + ") " + FormatRecursively(node.GetSubtree(0)) +
                                         ", (" + prevCounterVariable + "+" + laggedNode.Lag + "):" + prevCounterVariable +
                                         "))");
                ReleaseIndexVariable();
            }
            else if (symbol is TimeLag)
            {
                var laggedNode = node as LaggedTreeNode;
                currentLag += laggedNode.Lag;
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                currentLag -= laggedNode.Lag;
            }
            else
            {
                stringBuilder.Append("ERROR");
            }
            return(stringBuilder.ToString());
        }
 private ConstantTreeNode(ConstantTreeNode original, Cloner cloner)
   : base(original, cloner) {
   constantValue = original.constantValue;
 }
        // returns the smalltalk expression corresponding to the node
        // smalltalk expressions are always surrounded by parantheses "(<expr>)"
        private string FormatRecursively(ISymbolicExpressionTreeNode node)
        {
            ISymbol symbol = node.Symbol;

            if (symbol is ProgramRootSymbol || symbol is StartSymbol)
            {
                return(FormatRecursively(node.GetSubtree(0)));
            }

            StringBuilder stringBuilder = new StringBuilder(20);

            stringBuilder.Append("(");

            if (symbol is Addition)
            {
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("+");
                    }
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                }
            }
            else if (symbol is And)
            {
                stringBuilder.Append("(");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("&");
                    }
                    stringBuilder.Append("(");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    stringBuilder.Append(" > 0)");
                }
                stringBuilder.Append(") ifTrue:[1] ifFalse:[-1]");
            }
            else if (symbol is Average)
            {
                stringBuilder.Append("(1/");
                stringBuilder.Append(node.SubtreeCount);
                stringBuilder.Append(")*(");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("+");
                    }
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                }
                stringBuilder.Append(")");
            }
            else if (symbol is Constant)
            {
                ConstantTreeNode constantTreeNode = node as ConstantTreeNode;
                stringBuilder.Append(constantTreeNode.Value.ToString(CultureInfo.InvariantCulture));
            }
            else if (symbol is Cosine)
            {
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(" cos");
            }
            else if (symbol is Division)
            {
                if (node.SubtreeCount == 1)
                {
                    stringBuilder.Append("1/");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                }
                else
                {
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                    stringBuilder.Append("/(");
                    for (int i = 1; i < node.SubtreeCount; i++)
                    {
                        if (i > 1)
                        {
                            stringBuilder.Append("*");
                        }
                        stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    }
                    stringBuilder.Append(")");
                }
            }
            else if (symbol is Exponential)
            {
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(" exp");
            }
            else if (symbol is GreaterThan)
            {
                stringBuilder.Append("(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(" > ");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append(") ifTrue: [1] ifFalse: [-1]");
            }
            else if (symbol is IfThenElse)
            {
                stringBuilder.Append("(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(" > 0) ifTrue: [");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append("] ifFalse: [");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(2)));
                stringBuilder.Append("]");
            }
            else if (symbol is LaggedVariable)
            {
                stringBuilder.Append("lagged variable not implemented");
            }
            else if (symbol is LessThan)
            {
                stringBuilder.Append("(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(" < ");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(1)));
                stringBuilder.Append(") ifTrue: [1] ifFalse: [-1]");
            }
            else if (symbol is Logarithm)
            {
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append("ln");
            }
            else if (symbol is Multiplication)
            {
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("*");
                    }
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                }
            }
            else if (symbol is Not)
            {
                stringBuilder.Append("(");
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(">0) ifTrue: [-1] ifFalse: [1.0]");
            }
            else if (symbol is Or)
            {
                stringBuilder.Append("(");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append("|");
                    }
                    stringBuilder.Append("(");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    stringBuilder.Append(">0)");
                }
                stringBuilder.Append(") ifTrue:[1] ifFalse:[-1]");
            }
            else if (symbol is Sine)
            {
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(" sin");
            }
            else if (symbol is Subtraction)
            {
                if (node.SubtreeCount == 1)
                {
                    stringBuilder.Append("-1*");
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                }
                else
                {
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                    for (int i = 1; i < node.SubtreeCount; i++)
                    {
                        stringBuilder.Append(" - ");
                        stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                    }
                }
            }
            else if (symbol is Tangent)
            {
                stringBuilder.Append(FormatRecursively(node.GetSubtree(0)));
                stringBuilder.Append(" tan");
            }
            else if (symbol is Variable)
            {
                VariableTreeNode variableTreeNode = node as VariableTreeNode;
                stringBuilder.Append(variableTreeNode.Weight.ToString(CultureInfo.InvariantCulture));
                stringBuilder.Append("*");
                stringBuilder.Append(variableTreeNode.VariableName);
            }
            else
            {
                stringBuilder.Append("(");
                for (int i = 0; i < node.SubtreeCount; i++)
                {
                    if (i > 0)
                    {
                        stringBuilder.Append(", ");
                    }
                    stringBuilder.Append(FormatRecursively(node.GetSubtree(i)));
                }
                stringBuilder.AppendFormat(" {0} [Not Supported] )", node.Symbol.Name);
            }

            stringBuilder.Append(")");

            return(stringBuilder.ToString());
        }
        protected void Scale(IDataAnalysisProblemData problemData, string targetVariable)
        {
            var dataset         = problemData.Dataset;
            var rows            = problemData.TrainingIndices;
            var estimatedValues = Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows);
            var targetValues    = dataset.GetDoubleValues(targetVariable, rows);

            var linearScalingCalculator   = new OnlineLinearScalingParameterCalculator();
            var targetValuesEnumerator    = targetValues.GetEnumerator();
            var estimatedValuesEnumerator = estimatedValues.GetEnumerator();

            while (targetValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext())
            {
                double target    = targetValuesEnumerator.Current;
                double estimated = estimatedValuesEnumerator.Current;
                if (!double.IsNaN(estimated) && !double.IsInfinity(estimated))
                {
                    linearScalingCalculator.Add(estimated, target);
                }
            }
            if (linearScalingCalculator.ErrorState == OnlineCalculatorError.None && (targetValuesEnumerator.MoveNext() || estimatedValuesEnumerator.MoveNext()))
            {
                throw new ArgumentException("Number of elements in target and estimated values enumeration do not match.");
            }

            double alpha = linearScalingCalculator.Alpha;
            double beta  = linearScalingCalculator.Beta;

            if (linearScalingCalculator.ErrorState != OnlineCalculatorError.None)
            {
                return;
            }

            ConstantTreeNode alphaTreeNode = null;
            ConstantTreeNode betaTreeNode  = null;
            // check if model has been scaled previously by analyzing the structure of the tree
            var startNode = SymbolicExpressionTree.Root.GetSubtree(0);

            if (startNode.GetSubtree(0).Symbol is Addition)
            {
                var addNode = startNode.GetSubtree(0);
                if (addNode.SubtreeCount == 2 && addNode.GetSubtree(0).Symbol is Multiplication && addNode.GetSubtree(1).Symbol is Constant)
                {
                    alphaTreeNode = addNode.GetSubtree(1) as ConstantTreeNode;
                    var mulNode = addNode.GetSubtree(0);
                    if (mulNode.SubtreeCount == 2 && mulNode.GetSubtree(1).Symbol is Constant)
                    {
                        betaTreeNode = mulNode.GetSubtree(1) as ConstantTreeNode;
                    }
                }
            }
            // if tree structure matches the structure necessary for linear scaling then reuse the existing tree nodes
            if (alphaTreeNode != null && betaTreeNode != null)
            {
                betaTreeNode.Value  *= beta;
                alphaTreeNode.Value *= beta;
                alphaTreeNode.Value += alpha;
            }
            else
            {
                var mainBranch = startNode.GetSubtree(0);
                startNode.RemoveSubtree(0);
                var scaledMainBranch = MakeSum(MakeProduct(mainBranch, beta), alpha);
                startNode.AddSubtree(scaledMainBranch);
            }
        }
 private ISymbolicExpressionTreeNode ParseSexp(Queue <Token> tokens)
 {
     if (tokens.Peek().Symbol == TokenSymbol.LPAR)
     {
         ISymbolicExpressionTreeNode tree;
         Expect(Token.LPAR, tokens);
         if (tokens.Peek().StringValue.StartsWith(VARSTART))
         {
             tree = ParseVariable(tokens);
         }
         else if (tokens.Peek().StringValue.StartsWith(LAGGEDVARSTART))
         {
             tree = ParseLaggedVariable(tokens);
         }
         else if (tokens.Peek().StringValue.StartsWith(TIMELAGSTART))
         {
             tree = ParseTimeLag(tokens);
             tree.AddSubtree(ParseSexp(tokens));
         }
         else if (tokens.Peek().StringValue.StartsWith(INTEGRALSTART))
         {
             tree = ParseIntegral(tokens);
             tree.AddSubtree(ParseSexp(tokens));
         }
         else if (tokens.Peek().StringValue.StartsWith(DEFUNSTART))
         {
             tree = ParseDefun(tokens);
             while (!tokens.Peek().Equals(Token.RPAR))
             {
                 tree.AddSubtree(ParseSexp(tokens));
             }
         }
         else if (tokens.Peek().StringValue.StartsWith(ARGSTART))
         {
             tree = ParseArgument(tokens);
         }
         else if (tokens.Peek().StringValue.StartsWith(INVOKESTART))
         {
             tree = ParseInvoke(tokens);
             while (!tokens.Peek().Equals(Token.RPAR))
             {
                 tree.AddSubtree(ParseSexp(tokens));
             }
         }
         else if (tokens.Peek().StringValue.StartsWith("FACTOR"))
         {
             tree = ParseFactor(tokens);
         }
         else if (tokens.Peek().StringValue.StartsWith("BINFACTOR"))
         {
             tree = ParseBinaryFactor(tokens);
         }
         else
         {
             Token curToken = tokens.Dequeue();
             tree = CreateTree(curToken);
             while (!tokens.Peek().Equals(Token.RPAR))
             {
                 tree.AddSubtree(ParseSexp(tokens));
             }
         }
         Expect(Token.RPAR, tokens);
         return(tree);
     }
     else if (tokens.Peek().Symbol == TokenSymbol.NUMBER)
     {
         ConstantTreeNode t = (ConstantTreeNode)constant.CreateTreeNode();
         t.Value = tokens.Dequeue().DoubleValue;
         return(t);
     }
     else
     {
         throw new FormatException("Expected function or constant symbol");
     }
 }