0

I have modeled my minimization problem on How to use the Eigen unsupported levenberg marquardt implementation? Deepfreeze's answer. However, I am not clear how we can pass additional information needed for minimization problem. I tried modifying operator() to include extra parameters but that gave me an error from LevenbergMarquardt.h file. My code is as follows, Thanks for your help in advance.

template<typename _Scalar, int NX = Eigen::Dynamic, int NY = Eigen::Dynamic>
struct Functor
{
    typedef _Scalar Scalar;
    enum {
        InputsAtCompileTime = NX,
        ValuesAtCompileTime = NY
    };
    typedef Eigen::Matrix<Scalar, InputsAtCompileTime, 1> InputType;
    typedef Eigen::Matrix<Scalar, ValuesAtCompileTime, 1> ValueType;
    typedef Eigen::Matrix<Scalar, ValuesAtCompileTime, InputsAtCompileTime> JacobianType;

    int m_inputs, m_values;

    Functor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}
    Functor(int inputs, int values) : m_inputs(inputs), m_values(values) {}

    int inputs() const { return m_inputs; }
    int values() const { return m_values; }

};

struct my_functor : Functor<double>
{
    my_functor(void) : Functor<double>(14,14) {}
    int operator()(const Eigen::VectorXd &x, Eigen::VectorXd &fvec) const
    {
        // These are the extra parameters I need to pass
        //which are used in generating fvec values
        double b = 0.005;
        int num_periods = 14;
        vector<double> spot_rates = { 0.073,0.0762,0.081,0.0845,0.092,0.0964,0.1012,0.1045,0.1075,0.1122,0.1155,0.1192,0.122,0.1232 };
        //End of extra parameters

        vector<double> vec(x.data(), x.data() + x.rows() * x.cols());
        vector<vector<double>> short_rates = bdt_short_rate_lattice(spot_rates[0], vec, b, num_periods);
        vector<vector<double>> bdt_elementary_prices = bdt_elementary_lattice(short_rates, 0.5);
        vector<double> bdt_zcb_prices;
        vector<double> bdt_spot_rates;
        for (int i = 1; i <= short_rates.size(); ++i) {
            bdt_zcb_prices.push_back(accumulate(bdt_elementary_prices[i].begin(), bdt_elementary_prices[i].end(), 0.0));
            bdt_spot_rates.push_back(pow((1.0 / bdt_zcb_prices.back()), (1.0 / i)) - 1.0);
        }
        for (int i = 0; i < bdt_spot_rates.size(); ++i) {
            fvec(i) = spot_rates[i] - bdt_spot_rates[i];                
        }

        return 0;
    }
};
suhasghorp
  • 157
  • 1
  • 2
  • 12
  • 1
    Store the extra parameters as member variable of your functor. You can pass it through the constructor or make the member variable public, or write a setter method. – chtz Aug 01 '19 at 18:33
  • Duh..I was looking at the code far too long. Thanks chtz. I modified the constructor as follows and it worked. `struct my_functor : Functor { double m_b; int m_num_periods; vector m_spot_rates; my_functor(double b, int num_periods, vector spot_rates) : Functor(14,14),m_b(b),m_num_periods(num_periods),m_spot_rates(spot_rates) {}` .... – suhasghorp Aug 01 '19 at 19:31
  • Feel free to write this as an answer – chtz Aug 01 '19 at 19:45

0 Answers0