Free cookie consent management tool by TermsFeed Policy Generator

source: branches/sluengo/HeuristicLab.Problems.TradeRules/Interpreter.cs @ 9333

Last change on this file since 9333 was 9325, checked in by sluengo, 12 years ago
File size: 29.3 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using HeuristicLab.Common;
6using HeuristicLab.Core;
7using HeuristicLab.Data;
8using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
9using HeuristicLab.Parameters;
10using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
11using HeuristicLab.Problems.DataAnalysis.Symbolic;
12using HeuristicLab.Problems.DataAnalysis;
13using System.Threading;
14using HeuristicLab.Problems.TradeRules.Symbols;
15
16namespace HeuristicLab.Problems.TradeRules
17{
18    [StorableClass]
19    [Item("Interpreter", "Represents a grammar for Trading Problems")]
20    public sealed class Interpreter : ParameterizedNamedItem, ITradeRulesExpresionTree
21    {
22        private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
23        private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
24        private int initialTraining;
25        private int initialTest;
26
27        [ThreadStatic]
28        private static Dictionary<ISymbolicExpressionTreeNode, double> signalCache;
29        [ThreadStatic]
30        private static Dictionary<ISymbolicExpressionTreeNode, double> firstEMACache;
31        [ThreadStatic]
32        private static Dictionary<ISymbolicExpressionTreeNode, double> secondEMACache;
33        [ThreadStatic]
34        private static Dictionary<ISymbolicExpressionTreeNode, double> RSIPositiveCache;
35        [ThreadStatic]
36        private static Dictionary<ISymbolicExpressionTreeNode, double> RSINegativeCache;
37        [ThreadStatic]
38        private static Dictionary<ISymbolicExpressionTreeNode, double> RSICache;
39        [ThreadStatic]
40        private static Dictionary<ISymbolicExpressionTreeNode, double> RSIOutputCache;
41
42        #region private classes
43        //This class manipulate the instructions of the stack
44        private class InterpreterState
45        {
46            private double[] argumentStack;
47            private int argumentStackPointer;
48            private Instruction[] code;
49            private int pc;
50            public int ProgramCounter
51            {
52                get { return pc; }
53                set { pc = value; }
54            }
55            internal InterpreterState(Instruction[] code, int argumentStackSize)
56            {
57                this.code = code;
58                this.pc = 0;
59                if (argumentStackSize > 0)
60                {
61                    this.argumentStack = new double[argumentStackSize];
62                }
63                this.argumentStackPointer = 0;
64            }
65
66            internal void Reset()
67            {
68                this.pc = 0;
69                this.argumentStackPointer = 0;
70            }
71
72            internal Instruction NextInstruction()
73            {
74                return code[pc++];
75            }
76            private void Push(double val)
77            {
78                argumentStack[argumentStackPointer++] = val;
79            }
80            private double Pop()
81            {
82                return argumentStack[--argumentStackPointer];
83            }
84
85            internal void CreateStackFrame(double[] argValues)
86            {
87                // push in reverse order to make indexing easier
88                for (int i = argValues.Length - 1; i >= 0; i--)
89                {
90                    argumentStack[argumentStackPointer++] = argValues[i];
91                }
92                Push(argValues.Length);
93            }
94
95            internal void RemoveStackFrame()
96            {
97                int size = (int)Pop();
98                argumentStackPointer -= size;
99            }
100
101            internal double GetStackFrameValue(ushort index)
102            {
103                // layout of stack:
104                // [0]   <- argumentStackPointer
105                // [StackFrameSize = N + 1]
106                // [Arg0] <- argumentStackPointer - 2 - 0
107                // [Arg1] <- argumentStackPointer - 2 - 1
108                // [...]
109                // [ArgN] <- argumentStackPointer - 2 - N
110                // <Begin of stack frame>
111                return argumentStack[argumentStackPointer - index - 2];
112            }
113        }
114
115        //Operation codes
116        private class OpCodes
117        {
118            public const byte Add = 1;
119            public const byte Sub = 2;
120            public const byte Mul = 3;
121
122            public const byte GT = 5;
123            public const byte LT = 6;
124
125            public const byte AND = 7;
126            public const byte OR = 8;
127            public const byte NOT = 9;
128            public const byte BOOLEAN = 10;
129
130            public const byte Average = 11;
131            public const byte MACD = 12;
132
133            public const byte Variable = 13;
134            public const byte Constant = 14;
135            public const byte ConstantInt = 16;
136            public const byte BoolConstant = 15;
137            public const byte Max = 17;
138            public const byte Min = 18;
139            public const byte Lag = 19;
140            public const byte RSI = 20;
141        }
142        #endregion
143
144        #region IStatefulItem
145        public void InitializeState()
146        {
147            EvaluatedSolutions.Value = 0;
148        }
149
150        public void ClearState()
151        {
152        }
153        #endregion
154
155        private Dictionary<Type, byte> symbolToOpcode = new Dictionary<Type, byte>() {
156      { typeof(Addition), OpCodes.Add },
157      { typeof(Subtraction), OpCodes.Sub },
158      { typeof(Multiplication), OpCodes.Mul },
159      { typeof(Constant), OpCodes.Constant },
160      { typeof(BoolConstant), OpCodes.BoolConstant },
161      { typeof(ConstantInt), OpCodes.ConstantInt },
162      { typeof(GreaterThan), OpCodes.GT },
163      { typeof(LessThan), OpCodes.LT },
164      { typeof(And), OpCodes.AND },
165      { typeof(Or), OpCodes.OR },
166      { typeof(Not), OpCodes.NOT},
167      { typeof(AverageTrade), OpCodes.Average},
168      { typeof(MACD), OpCodes.MACD},
169      { typeof(RSI), OpCodes.RSI},
170      { typeof(Max), OpCodes.Max},
171      { typeof(Min), OpCodes.Min},
172      { typeof(Lag), OpCodes.Lag},
173      { typeof(HeuristicLab.Problems.DataAnalysis.Symbolic.Variable), OpCodes.Variable },
174    };
175
176        public override bool CanChangeName
177        {
178            get { return false; }
179        }
180        public override bool CanChangeDescription
181        {
182            get { return false; }
183        }
184
185        #region parameter properties
186        public IValueParameter<BoolValue> CheckExpressionsWithIntervalArithmeticParameter
187        {
188            get { return (IValueParameter<BoolValue>)Parameters[CheckExpressionsWithIntervalArithmeticParameterName]; }
189        }
190
191        public IValueParameter<IntValue> EvaluatedSolutionsParameter
192        {
193            get { return (IValueParameter<IntValue>)Parameters[EvaluatedSolutionsParameterName]; }
194        }
195        #endregion
196
197        #region properties
198        public BoolValue CheckExpressionsWithIntervalArithmetic
199        {
200            get { return CheckExpressionsWithIntervalArithmeticParameter.Value; }
201            set { CheckExpressionsWithIntervalArithmeticParameter.Value = value; }
202        }
203
204        public IntValue EvaluatedSolutions
205        {
206            get { return EvaluatedSolutionsParameter.Value; }
207            set { EvaluatedSolutionsParameter.Value = value; }
208        }
209        #endregion
210
211        private double Evaluate(Dataset dataset, ref int row, InterpreterState state)
212        {
213            Instruction currentInstr = state.NextInstruction();
214
215            switch (currentInstr.opCode)
216            {
217                case OpCodes.Add:
218                    {
219                        double s = Evaluate(dataset, ref row, state);
220                        for (int i = 1; i < currentInstr.nArguments; i++)
221                        {
222                            s += Evaluate(dataset, ref row, state);
223                        }
224                        return s;
225                    }
226                case OpCodes.Sub:
227                    {
228                        double s = Evaluate(dataset, ref row, state);
229                        for (int i = 1; i < currentInstr.nArguments; i++)
230                        {
231                            s -= Evaluate(dataset, ref row, state);
232                        }
233                        if (currentInstr.nArguments == 1) s = -s;
234                        return s;
235                    }
236                case OpCodes.Mul:
237                    {
238                        double p = Evaluate(dataset, ref row, state);
239                        for (int i = 1; i < currentInstr.nArguments; i++)
240                        {
241                            p *= Evaluate(dataset, ref row, state);
242                        }
243                        return p;
244                    }
245                case OpCodes.Average:
246                    {
247                        double sum = Evaluate(dataset, ref row, state);
248                        int integerValue = (int)Math.Floor(sum);
249                        if (integerValue > 100) integerValue = 100;
250                        if (row < integerValue)
251                        {
252                            string variableName = dataset.GetValue(row, 3);
253                            double inferiorValue = Convert.ToDouble(variableName);
254                            return inferiorValue / (row + 1);
255                        }
256                        else
257                        {
258                            string variableName = dataset.GetValue(row, 3);
259                            double meanValue1 = Convert.ToDouble(variableName);
260                            string variableName2 = dataset.GetValue((row - integerValue), 3);
261                            double meanValue2 = Convert.ToDouble(variableName2);
262                            return (meanValue1 - meanValue2) / integerValue;
263                        }
264                    }
265                case OpCodes.AND:
266                    {
267                        double result = Evaluate(dataset, ref row, state);
268                        double result2 = Evaluate(dataset, ref row, state);
269                        double total = result + result2;
270                        return total < 2 ? -1.0 : 1.0;
271                    }
272                case OpCodes.OR:
273                    {
274                        double result = Evaluate(dataset, ref row, state);
275                        double result2 = Evaluate(dataset, ref row, state);
276                        double total = result + result2;
277                        return total > -2 ? 1.0 : -1.0;
278                    }
279                case OpCodes.NOT:
280                    {
281                        return Evaluate(dataset, ref row, state) > 0.0 ? -1.0 : 1.0;
282                    }
283
284                case OpCodes.BOOLEAN:
285                    {
286                        var booleanTreeNode = currentInstr.dynamicNode as BoolConstantTreeNode;
287                        return booleanTreeNode.Value;
288                    }
289                case OpCodes.GT:
290                    {
291                        double x = Evaluate(dataset, ref row, state);
292                        double y = Evaluate(dataset, ref row, state);
293                        if (x > y) return 1.0;
294                        else return -1.0;
295                    }
296                case OpCodes.LT:
297                    {
298                        double x = Evaluate(dataset, ref row, state);
299                        double y = Evaluate(dataset, ref row, state);
300                        if (x < y) return 1.0;
301                        else return -1.0;
302                    }
303                case OpCodes.Variable:
304                    {
305                        if (row < 0 || row >= dataset.Rows)
306                            return double.NaN;
307                        var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
308                        return ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
309                    }
310                case OpCodes.Constant:
311                    {
312                        var constTreeNode = currentInstr.dynamicNode as ConstantTreeNode;
313                        return constTreeNode.Value;
314                    }
315                case OpCodes.BoolConstant:
316                    {
317                        var boolConstTreeNode = currentInstr.dynamicNode as BoolConstantTreeNode;
318                        return boolConstTreeNode.Value;
319                    }
320                case OpCodes.ConstantInt:
321                    {
322                        var constIntTreeNode = currentInstr.dynamicNode as ConstantIntTreeNode;
323                        return constIntTreeNode.Value;
324                    }
325                case OpCodes.Max:
326                    {
327                        int n = (int)Evaluate(dataset, ref row, state);
328                        double max = Double.NegativeInfinity;
329                        int i = Math.Min(n, row);
330                        while (i >= 0)
331                        {
332                            int position = row - i;
333                            string variableName = dataset.GetValue(position, 2);
334                            double intValue = Convert.ToDouble(variableName);
335                            if (intValue > max) max = intValue;
336                            i--;
337                        }
338                        return max;
339                    }
340                case OpCodes.Min:
341                    {
342                        int n = (int)Evaluate(dataset, ref row, state);
343                        double min = Double.NegativeInfinity;
344                        int i = Math.Min(n, row);
345                        while (i >= 0)
346                        {
347                            int position = row - i;
348                            string variableName = dataset.GetValue(position, 2);
349                            double intValue = Convert.ToDouble(variableName);
350                            if (intValue < min) min = intValue;
351                            i--;
352                        }
353                        return min;
354                    }
355                case OpCodes.Lag:
356                    {
357                        int n = (int)Evaluate(dataset, ref row, state);
358                        if (n > row) return 0;
359                        int position = row - n;
360                        string variableName = dataset.GetValue(position, 2);
361                        double intValue = Convert.ToDouble(variableName);
362                        return intValue;
363                    }
364                case OpCodes.MACD:
365                    {
366                        //Taking the number of the days for each EMA
367                        double firstEMA = Evaluate(dataset, ref row, state);
368                        double secondEMA = Evaluate(dataset, ref row, state);
369                        double signal = Evaluate(dataset, ref row, state);
370                        //Initiation of the variables
371                        double firstElementEMA = -1000000;
372                        double secondElementEMA = -100000;
373                        double signalValue = -100000;
374                        double macd = 0;
375                        double longitud = 0;
376
377                        //Check if this MACD has previous values and retrieve them
378                        if (firstEMACache.ContainsKey(currentInstr.dynamicNode)) firstElementEMA = firstEMACache[currentInstr.dynamicNode];
379                        if (secondEMACache.ContainsKey(currentInstr.dynamicNode)) secondElementEMA = secondEMACache[currentInstr.dynamicNode];
380                        if (signalCache.ContainsKey(currentInstr.dynamicNode)) signalValue = signalCache[currentInstr.dynamicNode];
381
382               
383                            //Calculating the factor for each EMA
384                            double factor = 2.0 / (firstEMA + 1.0);
385                            double factor2 = 2.0 / (secondEMA + 1.0);
386                            double factor3 = 2.0 / (signal + 1.0);
387
388                            //Calculate the first value in the training for the two EMAs and the signal.
389                            if (row <= initialTraining || row == initialTest)
390                            {
391                                double [] meanValues = dataset.GetDoubleValues("\"Close\"", Enumerable.Range(0, row+1)).ToArray();
392                                firstElementEMA = meanValues[0];
393                                secondElementEMA = meanValues[0];
394                                double max = (Math.Max(firstEMA, secondEMA)-1);//The first macd happens when the longest EMA has its first value. We need -1 because row begin in 0.
395                                for (int i = 1; i < meanValues.Length; i++)
396                                {
397                                    firstElementEMA = (meanValues[i] * factor) + ((1 - factor) * firstElementEMA);
398                                    secondElementEMA = (meanValues[i] * factor2) + ((1 - factor2) * secondElementEMA);
399                                    if (i == max) signalValue = firstElementEMA - secondElementEMA;//First signal equals to macd.
400                                    else if (i > max)//Calculation for the next signals
401                                    {
402                                        macd = firstElementEMA - secondElementEMA;
403                                        signalValue = macd * factor3 + (1 - factor3) * signalValue;
404                                    }
405                                }
406                            }
407                            else  //The rest of the rows are calculating with the standard EMA formula
408                            {
409                                //Retrieve the dataset values
410                                string variableName = dataset.GetValue(row, 2);
411                                double meanValue1 = Convert.ToDouble(variableName);
412
413                                //Calculating EMA
414                                firstElementEMA = meanValue1 * factor + (1 - factor) * firstElementEMA;
415                                secondElementEMA = meanValue1 * factor2 + (1 - factor2) * secondElementEMA;
416
417                                //Calculating signal
418                                macd = firstElementEMA - secondElementEMA;
419                                signalValue = macd * factor3 + (1 - factor3) * signalValue;
420                            }
421                           
422                            //Save the values for the next iteration
423                            firstEMACache[currentInstr.dynamicNode] = firstElementEMA;
424                            secondEMACache[currentInstr.dynamicNode] = secondElementEMA;
425                            signalCache[currentInstr.dynamicNode] = signalValue;
426
427                        return macd > signalValue ? 1.0 : -1.0;
428                    }
429                case OpCodes.RSI:
430                    {
431                        //Taking the number of the days for EMA
432                        double numberOfDays = Evaluate(dataset, ref row, state);
433
434                        double positiveEMA = 0;
435                        double negativeEMA = 0;
436                        double yesterdayRSI = double.NegativeInfinity;
437                        double todayRSI = double.NegativeInfinity;
438                        double outputRSI = double.NegativeInfinity;
439                        //Retrieve EMA values
440                        if (RSIPositiveCache.ContainsKey(currentInstr.dynamicNode)) positiveEMA = RSIPositiveCache[currentInstr.dynamicNode];
441                        if (RSINegativeCache.ContainsKey(currentInstr.dynamicNode)) negativeEMA = RSINegativeCache[currentInstr.dynamicNode];
442                        if (RSICache.ContainsKey(currentInstr.dynamicNode)) yesterdayRSI = RSICache[currentInstr.dynamicNode];
443                        if (RSIOutputCache.ContainsKey(currentInstr.dynamicNode)) outputRSI = RSIOutputCache[currentInstr.dynamicNode];
444
445       
446                            //Calculate the factor for the EMA
447                            double factor = 1.0 / numberOfDays;
448
449                            if (row == initialTraining || row == initialTest)
450                            {
451                                double[] closeValues = dataset.GetDoubleValues("\"Close\"", Enumerable.Range(0, (row + 1))).ToArray();
452                                outputRSI = -1.0;
453                                for (int i = 1; i <= row; i++)
454                                {
455                                    if (numberOfDays >= i)
456                                    {
457                                        if ((closeValues[i] - closeValues[i - 1]) > 0) positiveEMA = ((closeValues[i] - closeValues[i - 1]) + positiveEMA);
458                                        else negativeEMA = Math.Abs(closeValues[i] - closeValues[i - 1]) + negativeEMA;
459                                        if (numberOfDays == i)
460                                        {
461                                            positiveEMA = positiveEMA / numberOfDays;
462                                            negativeEMA = negativeEMA / numberOfDays;
463                                            yesterdayRSI = 100 - (100 / (1 + (positiveEMA / negativeEMA)));
464                                        }
465                                    }
466                                    else
467                                    {
468                                        if ((closeValues[i] - closeValues[i - 1]) > 0)
469                                        {
470                                            positiveEMA = (closeValues[i] - closeValues[i - 1]) * factor + (1 - factor) * positiveEMA;
471                                            negativeEMA = 0 * factor + (1 - factor) * negativeEMA;
472                                        }
473                                        else
474                                        {
475                                            positiveEMA = 0 * factor + (1 - factor) * positiveEMA;
476                                            negativeEMA = Math.Abs(closeValues[i] - closeValues[i - 1]) * factor + (1 - factor) * negativeEMA;
477                                        }
478
479                                        todayRSI = 100 - (100 / (1 + (positiveEMA / negativeEMA)));
480
481                                        if ((yesterdayRSI < 30) && (todayRSI > 30)) outputRSI = 1.0;
482                                        else if ((yesterdayRSI > 70) && (todayRSI < 70)) outputRSI = -1.0;
483                                        yesterdayRSI = todayRSI;
484                                    }
485                                }
486                            }
487                            else
488                            {
489                                string todayCloseString = dataset.GetValue(row, 2);
490                                string yesterdayCloseString = dataset.GetValue((row - 1), 2);
491                                double todayClose = Convert.ToDouble(todayCloseString);
492                                double yesterdayClose = Convert.ToDouble(yesterdayCloseString);
493
494                                //Calculating EMA
495                                if ((todayClose - yesterdayClose) > 0)
496                                {
497                                    positiveEMA = (todayClose - yesterdayClose) * factor + (1 - factor) * positiveEMA;
498                                    negativeEMA = 0 * factor + (1 - factor) * negativeEMA;
499                                }
500                                else
501                                {
502                                    positiveEMA = 0 * factor + (1 - factor) * positiveEMA;
503                                    negativeEMA = Math.Abs(todayClose - yesterdayClose) * factor + (1 - factor) * negativeEMA;
504                                }
505                                todayRSI = 100 - (100 / (1 + (positiveEMA / negativeEMA)));
506                                if ((yesterdayRSI < 30) && (todayRSI > 30)) outputRSI = 1.0;
507                                else if ((yesterdayRSI > 70) && (todayRSI < 70)) outputRSI = -1.0;
508                            }
509
510                            //Save positive and negative EMA for the next iteration
511                            RSIPositiveCache[currentInstr.dynamicNode] = positiveEMA;
512                            RSINegativeCache[currentInstr.dynamicNode] = negativeEMA;
513                            RSICache[currentInstr.dynamicNode] = todayRSI;
514                            RSIOutputCache[currentInstr.dynamicNode] = outputRSI;
515                           
516                       
517                        return outputRSI;
518                    }
519
520                default: throw new NotSupportedException();
521            }
522        }
523
524        private byte MapSymbolToOpCode(ISymbolicExpressionTreeNode treeNode)
525        {
526            if (symbolToOpcode.ContainsKey(treeNode.Symbol.GetType()))
527                return symbolToOpcode[treeNode.Symbol.GetType()];
528            else
529                throw new NotSupportedException("Symbol: " + treeNode.Symbol);
530        }
531
532        // skips a whole branch
533        private void SkipInstructions(InterpreterState state)
534        {
535            int i = 1;
536            while (i > 0)
537            {
538                i += state.NextInstruction().nArguments;
539                i--;
540            }
541        }
542        [StorableConstructor]
543        private Interpreter(bool deserializing) : base(deserializing) { }
544        private Interpreter(Interpreter original, Cloner cloner) : base(original, cloner) { }
545        public override IDeepCloneable Clone(Cloner cloner)
546        {
547            return new Interpreter(this, cloner);
548        }
549
550        public Interpreter()
551            : base("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")
552        {
553            Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
554            Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
555        }
556
557        [StorableHook(HookType.AfterDeserialization)]
558        private void AfterDeserialization()
559        {
560            if (!Parameters.ContainsKey(EvaluatedSolutionsParameterName))
561                Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
562        }
563        public void setInitialTraining(int initialTraining)
564        {
565            this.initialTraining = initialTraining;
566        }
567
568        public void setInitialTest(int initialTest)
569        {
570            this.initialTest = initialTest;
571        }
572
573        public void clearVariables()
574        {
575            signalCache.Clear();
576            firstEMACache.Clear();
577            secondEMACache.Clear();
578            RSIPositiveCache.Clear();
579            RSINegativeCache.Clear();
580            RSICache.Clear();
581            RSIOutputCache.Clear();
582        }
583
584        //Take the symbolic expression values of the tree
585        public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows)
586        {
587            if (CheckExpressionsWithIntervalArithmetic.Value)
588                throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
589            EvaluatedSolutions.Value++; // increment the evaluated solutions counter
590            var compiler = new SymbolicExpressionTreeCompiler();
591            Instruction[] code = compiler.Compile(tree, MapSymbolToOpCode);//Take the type of symbol
592            int necessaryArgStackSize = 0;
593            for (int i = 0; i < code.Length; i++)
594            {
595                Instruction instr = code[i];
596                if (instr.opCode == OpCodes.Variable)
597                {
598                    var variableTreeNode = instr.dynamicNode as VariableTreeNode;
599                    instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
600                    code[i] = instr;
601                }
602            }
603
604            if (signalCache == null) signalCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
605            if (firstEMACache == null) firstEMACache = new Dictionary<ISymbolicExpressionTreeNode, double>();
606            if (secondEMACache == null) secondEMACache = new Dictionary<ISymbolicExpressionTreeNode, double>();
607            if (RSIPositiveCache == null) RSIPositiveCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
608            if (RSINegativeCache == null) RSINegativeCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
609            if (RSICache == null) RSICache = new Dictionary<ISymbolicExpressionTreeNode, double>();
610            if (RSIOutputCache == null) RSIOutputCache = new Dictionary<ISymbolicExpressionTreeNode, double>();
611
612
613            var state = new InterpreterState(code, necessaryArgStackSize);
614            //Evaluate each row of the datase
615            foreach (var rowEnum in rows)
616            {
617                int row = rowEnum;
618                state.Reset();
619                if (row < initialTraining) yield return -1;
620                else yield return Evaluate(dataset, ref row, state);
621            }
622        }
623    }
624
625}
626
Note: See TracBrowser for help on using the repository browser.