| 114 | // ---------------------------------------------------------------------------------------- |
| 115 | |
| 116 | int main() try |
| 117 | { |
| 118 | // Set the starting point to (4,8). This is the point the optimization algorithm |
| 119 | // will start out from and it will move it closer and closer to the function's |
| 120 | // minimum point. So generally you want to try and compute a good guess that is |
| 121 | // somewhat near the actual optimum value. |
| 122 | column_vector starting_point = {4, 8}; |
| 123 | |
| 124 | // The first example below finds the minimum of the rosen() function and uses the |
| 125 | // analytical derivative computed by rosen_derivative(). Since it is very easy to |
| 126 | // make a mistake while coding a function like rosen_derivative() it is a good idea |
| 127 | // to compare your derivative function against a numerical approximation and see if |
| 128 | // the results are similar. If they are very different then you probably made a |
| 129 | // mistake. So the first thing we do is compare the results at a test point: |
| 130 | cout << "Difference between analytic derivative and numerical approximation of derivative: " |
| 131 | << length(derivative(rosen)(starting_point) - rosen_derivative(starting_point)) << endl; |
| 132 | |
| 133 | |
| 134 | cout << "Find the minimum of the rosen function()" << endl; |
| 135 | // Now we use the find_min() function to find the minimum point. The first argument |
| 136 | // to this routine is the search strategy we want to use. The second argument is the |
| 137 | // stopping strategy. Below I'm using the objective_delta_stop_strategy which just |
| 138 | // says that the search should stop when the change in the function being optimized |
| 139 | // is small enough. |
| 140 | |
| 141 | // The other arguments to find_min() are the function to be minimized, its derivative, |
| 142 | // then the starting point, and the last is an acceptable minimum value of the rosen() |
| 143 | // function. That is, if the algorithm finds any inputs to rosen() that gives an output |
| 144 | // value <= -1 then it will stop immediately. Usually you supply a number smaller than |
| 145 | // the actual global minimum. So since the smallest output of the rosen function is 0 |
| 146 | // we just put -1 here which effectively causes this last argument to be disregarded. |
| 147 | |
| 148 | find_min(bfgs_search_strategy(), // Use BFGS search algorithm |
| 149 | objective_delta_stop_strategy(1e-7), // Stop when the change in rosen() is less than 1e-7 |
| 150 | rosen, rosen_derivative, starting_point, -1); |
| 151 | // Once the function ends the starting_point vector will contain the optimum point |
| 152 | // of (1,1). |
| 153 | cout << "rosen solution:\n" << starting_point << endl; |
| 154 | |
| 155 | |
| 156 | // Now let's try doing it again with a different starting point and the version |
| 157 | // of find_min() that doesn't require you to supply a derivative function. |
| 158 | // This version will compute a numerical approximation of the derivative since |
| 159 | // we didn't supply one to it. |
| 160 | starting_point = {-94, 5.2}; |
| 161 | find_min_using_approximate_derivatives(bfgs_search_strategy(), |
| 162 | objective_delta_stop_strategy(1e-7), |
| 163 | rosen, starting_point, -1); |
| 164 | // Again the correct minimum point is found and stored in starting_point |
| 165 | cout << "rosen solution:\n" << starting_point << endl; |
| 166 | |
| 167 | |
| 168 | // Here we repeat the same thing as above but this time using the L-BFGS |
| 169 | // algorithm. L-BFGS is very similar to the BFGS algorithm, however, BFGS |
| 170 | // uses O(N^2) memory where N is the size of the starting_point vector. |
| 171 | // The L-BFGS algorithm however uses only O(N) memory. So if you have a |
| 172 | // function of a huge number of variables the L-BFGS algorithm is probably |
| 173 | // a better choice. |
nothing calls this directly
no test coverage detected