public void OptimizationSimplex() { //Rosenbrock banana function //f(a,b)=100*(b-a^2)^2+(1-a)^2 //The minimum is at (1,1) and the function value is 0. //using DotNumerics.Optimization; Simplex simplex = new Simplex(); double[] initialGuess = new double[2]; initialGuess[0] = 0.1; initialGuess[1] = 2; double[] minimum = simplex.ComputeMin(BananaFunction, initialGuess); ObjectDumper.Write("Simplex Method."); ObjectDumper.Write("a = " + minimum[0].ToString() + ", b = " + minimum[1].ToString()); //f(a,b) = 100*(b-a^2)^2 + (1-a)^2 //private double BananaFunction(double[] x) //{ // double f = 0; // f = 100 * Math.Pow((x[1] - x[0] * x[0]), 2) + Math.Pow((1 - x[0]), 2); // return f; //} }
public void OptimizationSimplexConstrained() { //This example minimize the function //f(x0,x2,...,xn)= (x0-0)^2+(x1-1)^2+...(xn-n)^2 //The minimum is at (0,1,2,3...,n) for the unconstrained case. //using DotNumerics.Optimization; Simplex simplex = new Simplex(); int numVariables = 5; OptBoundVariable[] variables = new OptBoundVariable[numVariables]; //Constrained Minimization on the interval (-10,10), initial Guess=-2; for (int i = 0; i < numVariables; i++) { variables[i] = new OptBoundVariable("x" + i.ToString(), -2, -10, 10); } double[] minimum = simplex.ComputeMin(ObjetiveFunction, variables); ObjectDumper.Write("Simplex Method. Constrained Minimization on the interval (-10,10)"); for (int i = 0; i < minimum.Length; i++) { ObjectDumper.Write("x" + i.ToString() + " = " + minimum[i].ToString()); } //Constrained Minimization on the interval (-10,3), initial Guess=-2; for (int i = 0; i < numVariables; i++) { variables[i].UpperBound = 3; } minimum = simplex.ComputeMin(ObjetiveFunction, variables); ObjectDumper.Write("Simplex Method. Constrained Minimization on the interval (-10,3)"); for (int i = 0; i < minimum.Length; i++) { ObjectDumper.Write("x" + i.ToString() + " = " + minimum[i].ToString()); } //f(x0,x2,...,xn)= (x0-0)^2+(x1-1)^2+...(xn-n)^2 //private double ObjetiveFunction(double[] x) //{ // int numVariables = 5; // double f = 0; // for (int i = 0; i < numVariables; i++) f += Math.Pow(x[i] - i, 2); // return f; //} }
public double[] StartMapping(SpotParsInitBox spotParsInitBox, string minimizator, double tau) { OptBoundVariable[] x = new OptBoundVariable[spotParsInitBox.SpotsNumber * 4]; for (int i = 0; i < x.Length; i++) { x[i] = new OptBoundVariable(); } for (int q = 0; q < this.lcObs.Length; q++) { this.modellers[q].StarM.RemoveAllSpots(); for (int s = 0; s < spotParsInitBox.SpotsNumber; s++) { this.modellers[q].StarM.AddUniformCircularSpot( spotParsInitBox.spots[s].longitude * Math.PI / 180, spotParsInitBox.spots[s].colatutude * Math.PI / 180, spotParsInitBox.spots[s].radius * Math.PI / 180, spotParsInitBox.spots[s].teff, spotParsInitBox.spots[s].beltsCount, spotParsInitBox.spots[s].nearEquatorialPatchesCount); } } this.fixedParsMask = new bool[x.Length]; for (int s = 0; s < spotParsInitBox.SpotsNumber; s++) { x[0 + s * 4].InitialGuess = spotParsInitBox.spots[s].longitude * Math.PI / 180; x[0 + s * 4].UpperBound = spotParsInitBox.spots[s].longitudeUpperLimit * Math.PI / 180; x[0 + s * 4].LowerBound = spotParsInitBox.spots[s].longitudeLowerLimit * Math.PI / 180; x[0 + s * 4].Fixed = spotParsInitBox.spots[s].longitudeFixed; this.fixedParsMask[0 + s * 4] = spotParsInitBox.spots[s].longitudeFixed; x[1 + s * 4].InitialGuess = spotParsInitBox.spots[s].colatutude * Math.PI / 180; x[1 + s * 4].UpperBound = spotParsInitBox.spots[s].colatitudeUpperLimit * Math.PI / 180; x[1 + s * 4].LowerBound = spotParsInitBox.spots[s].colatitudeLowerLimit * Math.PI / 180; x[1 + s * 4].Fixed = spotParsInitBox.spots[s].colatitudeFixed; this.fixedParsMask[1 + s * 4] = spotParsInitBox.spots[s].colatitudeFixed; x[2 + s * 4].InitialGuess = spotParsInitBox.spots[s].radius * Math.PI / 180; x[2 + s * 4].UpperBound = spotParsInitBox.spots[s].radiusUpperLimit * Math.PI / 180; x[2 + s * 4].LowerBound = spotParsInitBox.spots[s].radiusLowerLimit * Math.PI / 180; x[2 + s * 4].Fixed = spotParsInitBox.spots[s].radiusFixed; this.fixedParsMask[2 + s * 4] = spotParsInitBox.spots[s].radiusFixed; x[3 + s * 4].InitialGuess = spotParsInitBox.spots[s].teff; x[3 + s * 4].UpperBound = spotParsInitBox.spots[s].teffUpperLimit; x[3 + s * 4].LowerBound = spotParsInitBox.spots[s].teffLowerLimit; x[3 + s * 4].Fixed = spotParsInitBox.spots[s].teffFixed; this.fixedParsMask[3 + s * 4] = spotParsInitBox.spots[s].teffFixed; } double[] res = new double[4]; if (minimizator == "Simplex") { Simplex simplex = new Simplex(); res = simplex.ComputeMin(this.Khi2, x); } if (minimizator == "TN") { //DotNumerics.Optimization.TruncatedNewton tn = new TruncatedNewton(); DotNumerics.Optimization.L_BFGS_B bfgs = new L_BFGS_B(); //tn.SearchSeverity = 1; //res = tn.ComputeMin(this.Khi2, this.GradKhi2, x); res = bfgs.ComputeMin(this.Khi2, this.GradKhi2, x); } if (minimizator == "LM") { LevenbergMaquard gn = new LevenbergMaquard(); gn.MinimizedFunction = this.ResudalVector; double[] step = new double[x.Length]; double[] xinit = new double[x.Length]; bool[] isFixed = new bool[x.Length]; double[] lowLimits = new double[x.Length]; double[] highLimits = new double[x.Length]; for (int i = 0; i < xinit.Length; i++) { xinit[i] = x[i].InitialGuess; isFixed[i] = x[i].Fixed; lowLimits[i] = x[i].LowerBound; highLimits[i] = x[i].UpperBound; if (i != 0 && (i + 1) % 4 == 0) { step[i] = 10; // step for temperature; } else { step[i] = 0.02; } } gn.StepForDer = step; gn.IterMax = 100; gn.Tau = tau; res = gn.ComputeMin(xinit, isFixed, lowLimits, highLimits); } this.khi2 = this.Khi2(res); this.GenerateModLightCurve(); return(res); }
public PIDTuningTool(Shared.Flowsheet fs, DynamicsIntegratorControl intcontrol) : base() { Flowsheet = fs; intc = intcontrol; Padding = new Eto.Drawing.Padding(5); Spacing = new Size(5, 5); Padding = new Eto.Drawing.Padding(5); Spacing = new Size(10, 10); var leftcontainer = new DynamicLayout { Width = 300 }; leftcontainer.CreateAndAddLabelRow("Schedule"); var schlist = Flowsheet.DynamicsManager.ScheduleList.Values.ToList(); var cbSchedule = leftcontainer.CreateAndAddDropDownRow("Schedule", schlist.Select((x) => x.Description).ToList(), 0, (dd, e) => schedule = schlist[dd.SelectedIndex]); leftcontainer.CreateAndAddLabelRow("Controllers"); leftcontainer.CreateAndAddDescriptionRow("Select the PID Controllers to tune."); var listb = new CheckBoxList() { Height = 200 }; foreach (var obj in Flowsheet.SimulationObjects.Values.Where((x) => x.ObjectClass == Interfaces.Enums.SimulationObjectClass.Controllers)) { listb.Items.Add(obj.GraphicObject.Tag, obj.Name); } leftcontainer.CreateAndAddControlRow(listb); leftcontainer.CreateAndAddNumericEditorRow("Maximum Iterations", iterations, 5, 100, 0, (ns, e) => { iterations = (int)ns.Value; }); var btnRun = leftcontainer.CreateAndAddButtonRow("Begin Tuning", null, null); var btnCancel = leftcontainer.CreateAndAddButtonRow("Cancel", null, (btn, e) => Abort = true); txtResults = new TextArea { ReadOnly = true, Wrap = true }; Rows.Add(new TableRow(leftcontainer, new Scrollable { Content = txtResults })); btnRun.Click += (s, e) => { Flowsheet.RunCodeOnUIThread(() => { txtResults.Text = ""; if (!Flowsheet.DynamicMode) { txtResults.Text += "Error: Dynamic Mode is not activated. Activate Dynamic Mode and try again."; return; } intc.cbsc.SelectedIndex = cbSchedule.SelectedIndex; var schedule = Flowsheet.DynamicsManager.ScheduleList[Flowsheet.DynamicsManager.CurrentSchedule]; List <OptSimplexBoundVariable> vars = new List <OptSimplexBoundVariable>(); List <PIDController> controllers = new List <PIDController>(); foreach (var item in listb.SelectedKeys) { var controller = (PIDController)Flowsheet.SimulationObjects[item]; controllers.Add(controller); vars.Add(new OptSimplexBoundVariable(controller.Kp, 0.0, controller.Kp * 10)); vars.Add(new OptSimplexBoundVariable(controller.Ki, 0.0, 100.0)); vars.Add(new OptSimplexBoundVariable(controller.Kd, 0.0, 100.0)); } btnRun.Enabled = false; btnCancel.Enabled = true; Simplex simplex = new Simplex(); simplex.MaxFunEvaluations = iterations; Abort = false; int counter = 1; if (schedule.InitialFlowsheetStateID == "" | schedule.UseCurrentStateAsInitial) { txtResults.Text += "The selected schedule must have a valid initial state to start from."; btnRun.Enabled = true; btnCancel.Enabled = false; return; } var result = simplex.ComputeMin(x => { if (Abort) { return(0.0); } Flowsheet.RunCodeOnUIThread(() => { txtResults.Text += (string.Format("Beginning Iteration #{0}...\n", counter)); }); intc.RestoreState(schedule.InitialFlowsheetStateID); var i = 0; foreach (var controller in controllers) { controller.Kp = x[i]; controller.Ki = x[i + 1]; controller.Kd = x[i + 2]; Flowsheet.RunCodeOnUIThread(() => { txtResults.Text += (string.Format("Controller: {0} - Kp = {1}, Ki = {2}, Kd = {3}\n", controller.GraphicObject.Tag, controller.Kp, controller.Ki, controller.Kd)); }); i += 3; } intc.RunIntegrator(false, true); var totalerror = controllers.Select(c => c.CumulativeError).ToArray().AbsSumY(); Flowsheet.RunCodeOnUIThread(() => { txtResults.Text += (string.Format("Total Error: {0}\n", totalerror)); txtResults.CaretIndex = txtResults.Text.Length - 1; }); Application.Instance.RunIteration(); counter += 1; return(totalerror); }, vars.ToArray()); if (Abort) { txtResults.Text += (string.Format("Tuning aborted by the user. Results:\n")); } else { txtResults.Text += (string.Format("Tuning finished successfully. Results:\n")); } var j = 0; foreach (var controller in controllers) { controller.Kp = result[j]; controller.Ki = result[j + 1]; controller.Kd = result[j + 2]; txtResults.Text += (string.Format("Controller: {0} - Kp = {1}, Ki = {2}, Kd = {3}\n", controller.GraphicObject.Tag, controller.Kp, controller.Ki, controller.Kd)); j += 3; } btnRun.Enabled = true; btnCancel.Enabled = false; Flowsheet.UpdateInterface(); }); }; }