-
Notifications
You must be signed in to change notification settings - Fork 1.5k
/
GaussOptimization.cs
77 lines (69 loc) · 2.76 KB
/
GaussOptimization.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.Collections.Generic;
using System.Linq;
namespace Algorithms.Other;
/// <summary>
/// The Gaussian method (coordinate descent method) refers to zero-order methods in which only the value
/// of the function Q(X) at different points in the space of variables is used to organize the search
/// for the extremum. This reduces the overall computational cost of finding the extremum. Also in
/// the Gaussian method, the procedures for finding and moving the operating point are simplified as
/// much as possible.
/// </summary>
public class GaussOptimization
{
/// <summary>
/// Implementation of function extremum search by the Gauss optimization algorithm.
/// </summary>
/// <param name="func">Function for which extremum has to be found.</param>
/// <param name="n">This parameter identifies how much step size will be decreased each iteration.</param>
/// <param name="step">The initial shift step.</param>
/// <param name="eps">This value is used to control the accuracy of the optimization. In case if the error is less than eps,
/// optimization will be stopped.</param>
/// <param name="x1">The first function parameter.</param>
/// <param name="x2">The second function parameter.</param>
/// <returns>A tuple of coordinates of function extremum.</returns>
public (double X1, double X2) Optimize(
Func<double, double, double> func,
double n,
double step,
double eps,
double x1,
double x2)
{
// The initial value of the error
double error = 1;
while (Math.Abs(error) > eps)
{
// Calculation of the function with coordinates that are calculated with shift
double bottom = func(x1, x2 - step);
double top = func(x1, x2 + step);
double left = func(x1 - step, x2);
double right = func(x1 + step, x2);
// Determination of the best option.
var possibleFunctionValues = new List<double> { bottom, top, left, right };
double maxValue = possibleFunctionValues.Max();
double maxValueIndex = possibleFunctionValues.IndexOf(maxValue);
// Error evaluation
error = maxValue - func(x1, x2);
// Coordinates update for the best option
switch (maxValueIndex)
{
case 0:
x2 -= step;
break;
case 1:
x2 += step;
break;
case 2:
x1 -= step;
break;
default:
x1 += step;
break;
}
// Step reduction
step /= n;
}
return (x1, x2);
}
}