Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Division by zero in Cauchy.h #18

Closed
xthan opened this issue Jan 16, 2021 · 4 comments
Closed

Division by zero in Cauchy.h #18

xthan opened this issue Jan 16, 2021 · 4 comments

Comments

@xthan
Copy link

xthan commented Jan 16, 2021

Dear Yixuan,

Thanks for sharing the great code. I found that in some rare cases, the variable fpp in Cauchy.h may happen to be zero, which leads to NaN results:

deltatmin = -fp / fpp;

@yixuan
Copy link
Owner

yixuan commented Jan 26, 2021

Thanks for the report. I'm a bit busy recently, but I'll look into this issue when I get some time.

@yixuan
Copy link
Owner

yixuan commented Apr 3, 2021

I read the original paper on L-BFGS-B again, and noticed that fpp is guaranteed to be positive mathematically, so in your case there may be some numerical issues. Could you provide a simple example to reproduce the problem?

@xthan
Copy link
Author

xthan commented Apr 10, 2021

Here is an example modified from https://github.com/yixuan/LBFGSpp/blob/master/example-quadratic.cpp, which should be able to reproduce the problem during the optimization.


#include <Eigen/Core>
#include <LBFGSB.h>
#include <iostream>

using Eigen::VectorXd;
using Eigen::MatrixXd;
using namespace LBFGSpp;

double foo(const VectorXd& x, VectorXd& grad)
{
    const int n = x.size();
    VectorXd d(n);
    for(int i = 0; i < n; i++)
        d[i] = i + 1;
    double f = 20. * (x - d).squaredNorm();
    grad.noalias() = 20. * 2.0 * (x - d);
    std::cout << "fx:" << f << std::endl;

    return f;
}

int main()
{
    const int n = 33;
    LBFGSBParam<double> param;
    LBFGSBSolver<double> solver(param);

    VectorXd lb = VectorXd::Constant(n, -30.0);
    VectorXd ub = VectorXd::Constant(n, 30.0);

    // Initial guess
    VectorXd x = VectorXd::Constant(n, 1.);

    // x will be overwritten to be the best point found
    double fx;
    int niter = solver.minimize(foo, x, fx, lb, ub);

    std::cout << niter << " iterations" << std::endl;
    std::cout << "x = \n" << x.transpose() << std::endl;
    std::cout << "f(x) = " << fx << std::endl;

    return 0;
}

@yixuan
Copy link
Owner

yixuan commented Jun 13, 2021

This issue has been fixed in 880a8da.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants