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
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#ifndef _TEST_FUNCTIONS
#define _TEST_FUNCTIONS

#include <Eigen/Eigen>
#include <string>
#include <sstream>

#include "Tools/Math/Common.h"

// implementing some test functions from "Damping Parameter In Marquardt's Mehtod", Hans Bruun Nielsen
namespace nielsen {
    class Rosenbrock {
    public:
        Rosenbrock(){}

        Eigen::Vector2d operator()(const Eigen::Matrix<double, 2, 1>& parameter) const;

        size_t getNumberOfResudials() const{
            return 2;
        }

        std::string getName(){
            return "Rosenbrock";
        }
    };
}

// implementing some test functions from https://en.wikipedia.org/wiki/Test_functions_for_optimization
namespace wikipedia {

    template <int N>
    class Rosenbrock {
    public:
        Rosenbrock(){}

        Eigen::Matrix<double, N, 1> operator ()(const Eigen::Matrix<double, N, 1>& parameter) const {
            Eigen::Matrix<double, N, 1> f;
            for( int i = 0; i < N-2; i++){
                f(i,0) = 100*std::pow(parameter(i+1,0)-parameter(i,0)*parameter(i,0), 2) + std::pow(1 - parameter(i,0), 2);
            }
            f(N-2,0) = 100*std::pow(parameter(N-1,0)-parameter(N-2,0)*parameter(N-1,0), 2);
            f(N-1,0) = std::pow(1 - parameter(N-1,0), 2);

            return f;
        }

        size_t getNumberOfResudials() const{
            return N;
        }

        std::string getName(){
            std::stringstream ss;
            ss << "Rosenbrock " << N << std::endl;
            return ss.str();
        }
    };

    typedef Rosenbrock<2> Rosenbrock2;
    typedef Rosenbrock<3> Rosenbrock3;
    typedef Rosenbrock<7> Rosenbrock7;

    class Himmelblau {
    public:
        Himmelblau(){}

        Eigen::Vector2d operator()(const Eigen::Vector2d &p) const;

        size_t getNumberOfResudials() const{
            return 2;
        }

        std::string getName(){
            return "Himmelblau";
        }

        /* known minima
         * f (  3.0     ,  2.0     ) = 0.0
         * f ( −2.805118,  3.131312) = 0.0
         * f ( −3.779310, −3.283186) = 0.0
         * f (  3.584428, −1.848126) = 0.0
         */
    };

    template <int N>
    class Rastrigin {
    public:
        Rastrigin(){}

        Eigen::Matrix<double, N, 1> operator ()(const Eigen::Matrix<double, N, 1>& p) const {
            Eigen::Matrix<double, N, 1> f;
            for( int i = 0; i < N-1; i++){
                f(i,0) = p(i,0) * p(i,0) - 10 * std::cos(2 * Math::pi * p(i,0));
            }
            f(N-1,0) = 10 * N + p(N-1,0) * p(N-1,0) - 10 * std::cos(2 * Math::pi * p(N-1,0));

            return f;
        }

        size_t getNumberOfResudials() const{
            return N;
        }

        std::string getName(){
            std::stringstream ss;
            ss << "Rastrigin " << N << std::endl;
            return ss.str();
        }
    };

    typedef Rastrigin<2> Rastrigin2;
    typedef Rastrigin<3> Rastrigin3;
    typedef Rastrigin<7> Rastrigin7;
}

namespace fitting {

    class Linear {
    public:
        Eigen::Vector2d x[5];
        Linear():
            x {Eigen::Vector2d(-2,-2),
               Eigen::Vector2d(-1,-1),
               Eigen::Vector2d(0,0),
               Eigen::Vector2d(1,1),
               Eigen::Vector2d(2,2)}
        {}

        Eigen::Matrix<double, 6, 1> operator ()(const Eigen::Matrix<double, 3, 1>& p) const {
            Eigen::Vector2d s(p(0),p(1));
            Eigen::Vector2d ortho_n(-std::sin(p(2)), std::cos(p(2)));

            Eigen::Matrix<double, 6, 1> r;
            for( int i = 0; i < 5; ++i){
                Eigen::Vector2d c = x[i] - s;
                r(i) = ortho_n.transpose() * c;
            }

            r(5) = p.transpose() * p;

            return r;
        }

        size_t getNumberOfResudials() const{
            return 6;
        }

        std::string getName(){
            std::stringstream ss;
            ss << "Linear Fitting" << std::endl;
            return ss.str();
        }
    };
}
#endif