Changeset 8730


Ignore:
Timestamp:
10/04/12 11:43:38 (7 years ago)
Author:
gkronber
Message:

#1962: disabled optimized button if the model contains non-differentiable functions. Added support for exact differentiation for additional function symbols (sin, cos, tan, square, norm, erf)

Location:
trunk/sources
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression.Views/3.4/InteractiveSymbolicRegressionSolutionSimplifierView.cs

    r8727 r8730  
    122122    }
    123123
     124    protected override void OnModelChanged() {
     125      base.OnModelChanged();
     126      btnOptimizeConstants.Enabled =
     127        SymbolicRegressionConstantOptimizationEvaluator.CanOptimizeConstants(Content.Model.SymbolicExpressionTree);
     128    }
     129    protected override void OnContentChanged() {
     130      base.OnContentChanged();
     131      base.OnModelChanged();
     132      btnOptimizeConstants.Enabled =
     133        SymbolicRegressionConstantOptimizationEvaluator.CanOptimizeConstants(Content.Model.SymbolicExpressionTree);
     134    }
     135
     136
    124137    protected override void btnOptimizeConstants_Click(object sender, EventArgs e) {
    125138      var model = Content.Model;
  • trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/Evaluators/SymbolicRegressionConstantOptimizationEvaluator.cs

    r8704 r8730  
    157157    }
    158158
     159    // create function factory for arctangent
     160    private readonly Func<Term, UnaryFunc> arctan = UnaryFunc.Factory(
     161        x => Math.Atan(x),      // evaluate
     162        x => 1 / (1 + x * x));  // derivative of atan
     163
     164    private static readonly Func<Term, UnaryFunc> sin = UnaryFunc.Factory(
     165      x => Math.Sin(x),
     166      x => Math.Cos(x));
     167    private static readonly Func<Term, UnaryFunc> cos = UnaryFunc.Factory(
     168      x => Math.Cos(x),
     169      x => -Math.Sin(x));
     170    private static readonly Func<Term, UnaryFunc> tan = UnaryFunc.Factory(
     171      x => Math.Tan(x),
     172      x => 1 + Math.Tan(x) * Math.Tan(x));
     173    private static readonly Func<Term, UnaryFunc> square = UnaryFunc.Factory(
     174      x => x * x,
     175      x => 2 * x);
     176    private static readonly Func<Term, UnaryFunc> erf = UnaryFunc.Factory(
     177      x => alglib.errorfunction(x),
     178      x => 2.0 * Math.Exp(-(x * x)) / Math.Sqrt(Math.PI));
     179
     180    private static readonly Func<Term, UnaryFunc> norm = UnaryFunc.Factory(
     181      x => alglib.normaldistribution(x),
     182      x => -(Math.Exp(-(x * x)) * Math.Sqrt(Math.Exp(x * x)) * x) / Math.Sqrt(2 * Math.PI)
     183      );
     184
     185
    159186    public static double OptimizeConstants(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree tree, IRegressionProblemData problemData,
    160187      IEnumerable<int> rows, bool applyLinearScaling, int maxIterations, double upperEstimationLimit = double.MaxValue, double lowerEstimationLimit = double.MinValue, IntValue evaluatedTrees = null, IntValue evaluatedTreeNodes = null) {
     
    216243
    217244      }
     245      catch (ArithmeticException) {
     246        return 0.0;
     247      }
    218248      catch (alglib.alglibexception) {
    219249        return 0.0;
     
    345375          return true;
    346376        }
     377      } if (node.Symbol is Sine) {
     378        AutoDiff.Term t;
     379        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     380          term = null;
     381          return false;
     382        } else {
     383          term = sin(t);
     384          return true;
     385        }
     386      } if (node.Symbol is Cosine) {
     387        AutoDiff.Term t;
     388        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     389          term = null;
     390          return false;
     391        } else {
     392          term = cos(t);
     393          return true;
     394        }
     395      } if (node.Symbol is Tangent) {
     396        AutoDiff.Term t;
     397        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     398          term = null;
     399          return false;
     400        } else {
     401          term = tan(t);
     402          return true;
     403        }
     404      }
     405      if (node.Symbol is Square) {
     406        AutoDiff.Term t;
     407        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     408          term = null;
     409          return false;
     410        } else {
     411          term = square(t);
     412          return true;
     413        }
     414      } if (node.Symbol is Erf) {
     415        AutoDiff.Term t;
     416        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     417          term = null;
     418          return false;
     419        } else {
     420          term = erf(t);
     421          return true;
     422        }
     423      } if (node.Symbol is Norm) {
     424        AutoDiff.Term t;
     425        if (!TryTransformToAutoDiff(node.GetSubtree(0), variables, parameters, variableNames, out t)) {
     426          term = null;
     427          return false;
     428        } else {
     429          term = norm(t);
     430          return true;
     431        }
    347432      }
    348433      if (node.Symbol is StartSymbol) {
     
    363448      return false;
    364449    }
     450
     451    public static bool CanOptimizeConstants(ISymbolicExpressionTree tree) {
     452      var containsUnknownSymbol = (
     453        from n in tree.Root.GetSubtree(0).IterateNodesPrefix()
     454        where
     455         !(n.Symbol is Variable) &&
     456         !(n.Symbol is Constant) &&
     457         !(n.Symbol is Addition) &&
     458         !(n.Symbol is Subtraction) &&
     459         !(n.Symbol is Multiplication) &&
     460         !(n.Symbol is Division) &&
     461         !(n.Symbol is Logarithm) &&
     462         !(n.Symbol is Exponential) &&
     463         !(n.Symbol is Sine) &&
     464         !(n.Symbol is Cosine) &&
     465         !(n.Symbol is Tangent) &&
     466         !(n.Symbol is Square) &&
     467         !(n.Symbol is Erf) &&
     468         !(n.Symbol is Norm) &&
     469         !(n.Symbol is StartSymbol)
     470        select n).
     471      Any();
     472      return !containsUnknownSymbol;
     473    }
    365474  }
    366475}
Note: See TracChangeset for help on using the changeset viewer.