#region License Information /* HeuristicLab * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Encodings.RealVectorEncoding; using HeuristicLab.Operators; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Problems.TestFunctions; using HeuristicLab.Analysis; namespace HeuristicLab.Algorithms.GradientDescent { public class LevenbergMarquardtMove : SingleSuccessorOperator { private const string EvaluatorParameterName = "Evaluator"; private const string ResultsParameterName = "Results"; private const string RealVectorParameterName = "RealVector"; private const string QualityParameterName = "Quality"; private const string QualityResultsName = "Quality"; public ILookupParameter EvaluatorParameter { get { return (ILookupParameter)Parameters[EvaluatorParameterName]; } } public ILookupParameter RealVectorParameter { get { return (ILookupParameter)Parameters[RealVectorParameterName]; } } public ILookupParameter ResultParameter { get { return (ILookupParameter)Parameters[ResultsParameterName]; } } public ILookupParameter QualityParameter { get { return (ILookupParameter)Parameters[QualityParameterName]; } } [StorableConstructor] protected LevenbergMarquardtMove(bool deserializing) : base(deserializing) { } protected LevenbergMarquardtMove(LevenbergMarquardtMove original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new LevenbergMarquardtMove(this, cloner); } public LevenbergMarquardtMove() : base() { Parameters.Add(new LookupParameter(EvaluatorParameterName, "")); Parameters.Add(new LookupParameter(RealVectorParameterName, "")); Parameters.Add(new LookupParameter(ResultsParameterName, "")); Parameters.Add(new LookupParameter(QualityParameterName, "")); } public override IOperation Apply() { double epsg = 0; double epsf = 0; double epsx = 0; int maxits = 0; double diffstep = .1; double[] solution = RealVectorParameter.ActualValue.ToArray(); alglib.minlmstate state; alglib.minlmreport report; alglib.minlmcreatev(solution.Length, solution, diffstep, out state); alglib.minlmsetcond(state, epsg, epsf, epsx, maxits); alglib.minlmsetxrep(state, true); alglib.minlmoptimize(state, CreateCallBack(EvaluatorParameter.ActualValue), CreateReportProgress(ResultParameter.ActualValue), null); alglib.minlmresults(state, out solution, out report); RealVectorParameter.ActualValue = new RealVector(solution); return base.Apply(); } private alglib.ndimensional_fvec CreateCallBack(ISingleObjectiveTestFunctionProblemEvaluator evaluator) { return (double[] arg, double[] fi, object obj) => { RealVector r = new RealVector(arg); RealVectorParameter.ActualValue = r; IExecutionContext context = (IExecutionContext)ExecutionContext.CreateChildOperation(evaluator); evaluator.Execute(context, CancellationToken); QualityParameter.ExecutionContext = context; fi[0] = QualityParameter.ActualValue.Value; }; } private alglib.ndimensional_rep CreateReportProgress(ResultCollection results) { return (double[] arg, double func, object obj) => { if (!results.ContainsKey(QualityResultsName)) { DataTable table = new DataTable(QualityResultsName); table.Rows.Add(new DataRow("Quality")); results.Add(new Result(QualityResultsName, table)); } DataTable resultsTable = (DataTable)results[QualityResultsName].Value; resultsTable.Rows["Quality"].Values.Add(func); }; } } }