Changeset 13288


Ignore:
Timestamp:
11/19/15 12:02:20 (3 years ago)
Author:
bburlacu
Message:

#2442: Removed time lagged symbols as they bring extra complexity in evaluating variables and a big performance penalty. Fixed interpretation of Psi, Power, Root, Square symbols.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionCompiledTreeInterpreter.cs

    r13251 r13288  
    4646    private static readonly MethodInfo Sqrt = typeof(Math).GetMethod("Sqrt", new[] { typeof(double) });
    4747    private static readonly MethodInfo Floor = typeof(Math).GetMethod("Floor", new[] { typeof(double) });
     48    private static readonly MethodInfo Round = typeof(Math).GetMethod("Round", new[] { typeof(double) });
    4849    private static readonly MethodInfo Exp = typeof(Math).GetMethod("Exp", new[] { typeof(double) });
    4950    private static readonly MethodInfo Log = typeof(Math).GetMethod("Log", new[] { typeof(double) });
    5051    private static readonly MethodInfo IsNaN = typeof(double).GetMethod("IsNaN");
     52    private static readonly MethodInfo IsAlmost = typeof(DoubleExtensions).GetMethod("IsAlmost");
    5153    private static readonly MethodInfo Gamma = typeof(alglib).GetMethod("gammafunction", new[] { typeof(double) });
    5254    private static readonly MethodInfo Psi = typeof(alglib).GetMethod("psi", new[] { typeof(double) });
     
    159161            var indexExpr = Expression.Constant(variableIndices[variableName]);
    160162            var valuesExpr = Expression.ArrayIndex(columns, indexExpr);
    161             var variableValue = Expression.Property(valuesExpr, Indexer, row);
    162             return Expression.Multiply(variableWeight, variableValue);
     163            return Expression.Multiply(variableWeight, Expression.Property(valuesExpr, Indexer, row));
    163164          }
    164165        case OpCodes.Add: {
     
    215216        case OpCodes.Square: {
    216217            var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);
    217             return Expression.Power(arg, Expression.Constant(2));
     218            return Expression.Power(arg, Expression.Constant(2.0));
    218219          }
    219220        case OpCodes.Power: {
    220221            var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);
    221222            var power = MakeExpr(node.GetSubtree(1), variableIndices, row, columns);
    222             return Expression.Power(arg, Expression.Call(Floor, power));
     223            return Expression.Power(arg, Expression.Call(Round, power));
    223224          }
    224225        case OpCodes.SquareRoot: {
     
    229230            var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);
    230231            var power = MakeExpr(node.GetSubtree(1), variableIndices, row, columns);
    231             return Expression.Power(arg, Expression.Divide(Expression.Constant(1.0), power));
     232            return Expression.Power(arg, Expression.Divide(Expression.Constant(1.0), Expression.Call(Round, power)));
    232233          }
    233234        case OpCodes.Exp: {
     
    269270                Expression.Assign(result, Expression.Constant(double.NaN)),
    270271                Expression.IfThenElse(
    271                   Expression.AndAlso(Expression.LessThanOrEqual(arg, Expression.Constant(0.0)),
    272                     Expression.Equal(Expression.Subtract(floor, arg), Expression.Constant(0.0))),
     272                  Expression.AndAlso(
     273                    Expression.LessThanOrEqual(arg, Expression.Constant(0.0)),
     274                    Expression.Call(IsAlmost, Expression.Subtract(floor, arg), Expression.Constant(0.0))),
    273275                  Expression.Assign(result, Expression.Constant(double.NaN)),
    274276                  Expression.Assign(result, psi))
     
    297299            var arg = MakeExpr(node.GetSubtree(0), variableIndices, row, columns);
    298300            var isNaN = Expression.Call(IsNaN, arg);
    299             var expIntegrapEi =
    300               Expression.Call(ExponentialIntegralEi, arg);
     301            var expIntegrapEi = Expression.Call(ExponentialIntegralEi, arg);
    301302            var result = Expression.Variable(typeof(double));
    302303            var expr = Expression.Block(
     
    357358            var shi = Expression.Variable(typeof(double));
    358359            var chi = Expression.Variable(typeof(double));
    359             var hypSinCosIntegrals = Expression.Call(HyperbolicSineCosineIntegrals, arg, shi, chi);
    360360            var block = Expression.Block(
    361361              new[] { shi, chi },
    362               hypSinCosIntegrals,
     362              Expression.Call(HyperbolicSineCosineIntegrals, arg, shi, chi),
    363363              shi
    364364              );
     
    378378            var shi = Expression.Variable(typeof(double));
    379379            var chi = Expression.Variable(typeof(double));
    380             var hypSinCosIntegrals = Expression.Call(HyperbolicSineCosineIntegrals, arg, shi, chi);
    381380            var block = Expression.Block(
    382381              new[] { shi, chi },
    383               hypSinCosIntegrals,
     382              Expression.Call(HyperbolicSineCosineIntegrals, arg, shi, chi),
    384383              chi
    385384              );
     
    470469            var isNaN = Expression.Call(IsNaN, arg);
    471470            var result = Expression.Variable(typeof(double));
    472             var norm = Expression.Call(NormalDistribution, arg);
    473 
    474             var expr = Expression.Block(new[] { result },
    475               Expression.IfThenElse(isNaN, Expression.Assign(result, Expression.Constant(double.NaN)),
    476                 Expression.Assign(result, norm)), result);
    477 
    478             return expr;
     471            return Expression.Block(
     472              new[] { result },
     473              Expression.IfThenElse(
     474                isNaN,
     475                Expression.Assign(result, Expression.Constant(double.NaN)),
     476                Expression.Assign(result, Expression.Call(NormalDistribution, arg))),
     477              result);
    479478          }
    480479        case OpCodes.Erf: {
     
    482481            var isNaN = Expression.Call(IsNaN, arg);
    483482            var result = Expression.Variable(typeof(double));
    484             var erf = Expression.Call(ErrorFunction, arg);
    485 
    486             var expr = Expression.Block(new[] { result },
    487               Expression.IfThenElse(isNaN, Expression.Assign(result, Expression.Constant(double.NaN)),
    488                 Expression.Assign(result, erf)), result);
    489 
    490             return expr;
     483            return Expression.Block(
     484              new[] { result },
     485              Expression.IfThenElse(
     486                isNaN,
     487                Expression.Assign(result, Expression.Constant(double.NaN)),
     488                Expression.Assign(result, Expression.Call(ErrorFunction, arg))),
     489              result);
    491490          }
    492491        case OpCodes.Bessel: {
     
    494493            var isNaN = Expression.Call(IsNaN, arg);
    495494            var result = Expression.Variable(typeof(double));
    496             var bessel = Expression.Call(Bessel, arg);
    497             var expr = Expression.Block(
     495            return Expression.Block(
    498496              new[] { result },
    499497              Expression.IfThenElse(
    500498                isNaN,
    501499                Expression.Assign(result, Expression.Constant(double.NaN)),
    502                 Expression.Assign(result, bessel)),
     500                Expression.Assign(result, Expression.Call(Bessel, arg))),
    503501              result);
    504 
    505             return expr;
    506502          }
    507503        case OpCodes.IfThenElse: {
     
    628624            var indexExpr = Expression.Constant(variableIndices[variableName]);
    629625            var valuesExpr = Expression.ArrayIndex(columns, indexExpr);
    630             var variableValue = Expression.ArrayIndex(valuesExpr, row);
     626            var variableValue = Expression.Property(valuesExpr, Indexer, row);
    631627            var variableThreshold = Expression.Constant(variableConditionTreeNode.Threshold);
    632628            var variableSlope = Expression.Constant(variableConditionTreeNode.Slope);
     
    643639              );
    644640          }
    645         case OpCodes.LagVariable: {
    646             var laggedVariableTreeNode = (LaggedVariableTreeNode)node;
    647             var lag = Expression.Constant(laggedVariableTreeNode.Lag);
    648             var variableWeight = Expression.Constant(laggedVariableTreeNode.Weight);
    649             var variableName = laggedVariableTreeNode.VariableName;
    650             var indexExpr = Expression.Constant(variableIndices[variableName]);
    651             var valuesExpr = Expression.ArrayIndex(columns, indexExpr);
    652             var variableValue = Expression.Property(valuesExpr, Indexer, Expression.Add(row, lag));
    653             return Expression.Multiply(variableWeight, variableValue);
    654           }
    655         case OpCodes.TimeLag: {
    656             var timeLagTreeNode = (LaggedTreeNode)node;
    657             var lag = Expression.Constant(timeLagTreeNode.Lag);
    658             return MakeExpr(timeLagTreeNode.GetSubtree(0), variableIndices, Expression.Add(row, lag), columns);
    659           }
    660         case OpCodes.Integral: {
    661             var timeLagTreeNode = (LaggedTreeNode)node;
    662             var subtree = node.GetSubtree(0);
    663             var sum = MakeExpr(subtree, variableIndices, row, columns);
    664             var sign = Expression.Constant(Math.Sign(timeLagTreeNode.Lag));
    665             var lag = Expression.Add(row, sign);
    666             for (int i = 0; i < Math.Abs(timeLagTreeNode.Lag); ++i) {
    667               sum = Expression.Add(sum, MakeExpr(subtree, variableIndices, lag, columns));
    668               lag = Expression.Add(lag, sign);
    669             }
    670             return sum;
    671           }
    672         case OpCodes.Derivative: {
    673             var subtree = node.GetSubtree(0);
    674             var f0 = MakeExpr(subtree, variableIndices, row, columns);
    675             var f1 = MakeExpr(subtree, variableIndices, Expression.Subtract(row, Expression.Constant(1)), columns);
    676             var f3 = MakeExpr(subtree, variableIndices, Expression.Subtract(row, Expression.Constant(3)), columns);
    677             var f4 = MakeExpr(subtree, variableIndices, Expression.Subtract(row, Expression.Constant(4)), columns);
    678 
    679             var result = f0;
    680             result = Expression.Add(result, Expression.Multiply(Expression.Constant(2.0), f1));
    681             result = Expression.Subtract(result, Expression.Multiply(Expression.Constant(2.0), f3));
    682             result = Expression.Subtract(result, f4);
    683             return Expression.Divide(result, Expression.Constant(8.0));
    684           }
    685641        default:
    686642          throw new NotSupportedException("Unsupported symbol: " + node.Symbol);
     
    688644      #endregion
    689645    }
    690     // util stuff
    691     private static Func<T, R> GetField<T, R>(string fieldName) {
    692       ParameterExpression param = Expression.Parameter(typeof(T), "arg");
    693       MemberExpression member = Expression.Field(param, fieldName);
    694       LambdaExpression lambda = Expression.Lambda(typeof(Func<T, R>), member, param);
    695       Func<T, R> compiled = (Func<T, R>)lambda.Compile();
    696       return compiled;
    697     }
    698646  }
    699647}
Note: See TracChangeset for help on using the changeset viewer.