Hello, 

I am using the LevenbergMarquardtOptimizer and am receiving very strange 
results. Running the below code, it appears as though the 
LevenbergMarquardtOptimizer is diverging rather than converging. In Matlab I 
run the equivalent code, and the algorithm correctly converges. Is there some 
bounds that can be set on the algorithm so it does not diverge?

Java Code:
RealVector theta_pr = createZerosVector(9);
double[] gravity = new double[selectedAccData.getColumnDimension()];
Arrays.fill(gravity, Math.pow(9.81744, 2));

LeastSquaresProblem problem = new LeastSquaresBuilder()
        .start(new double[]{0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01,0.01})
        .model(costFunc)
        .target(gravity)
        .lazyEvaluation(false)
        .maxEvaluations(150000)
        .maxIterations(6000)
        .build();

LeastSquaresOptimizer.Optimum optimum = new LevenbergMarquardtOptimizer()
        .withCostRelativeTolerance(1.0e-10)
        .optimize(problem);
private MultivariateJacobianFunction costFunc = new 
MultivariateJacobianFunction() {
    @Override
    public Pair<RealVector, RealMatrix> value(RealVector point) {

        double E1 = point.getEntry(0);
        double E2 = point.getEntry(1);
        double E3 = point.getEntry(2);
        double E4 = point.getEntry(3);
        double E5 = point.getEntry(4);
        double E6 = point.getEntry(5);
        double E7 = point.getEntry(6);
        double E8 = point.getEntry(7);
        double E9 = point.getEntry(8);
        
        RealVector value = new 
ArrayRealVector(selectedAccData.getColumnDimension());
        RealMatrix jacobian = new 
Array2DRowRealMatrix(selectedAccData.getColumnDimension(), 9);

        RealMatrix misalignmentMatrix = MatrixUtils.createRealMatrix(new 
double[][]{{1, -E1, E2}, {0, 1, -E3}, {0 ,0, 1}});
        RealMatrix scalingMatrix = MatrixUtils.createRealDiagonalMatrix(new 
double[]{E4, E5, E6});
        RealMatrix dMatrix = MatrixUtils.createRealDiagonalMatrix(new 
double[]{E7, E8, E9});
        RealMatrix oMatrix = 
createOnesMatrix(3,selectedAccData.getColumnDimension());
        RealMatrix a_bar = 
misalignmentMatrix.multiply(scalingMatrix).multiply(selectedAccData).subtract(dMatrix.multiply(oMatrix));

        for (int i = 0; i < selectedAccData.getColumnDimension(); ++i) {

            double modelI = 
(Math.pow(a_bar.getEntry(0,i),2)+Math.pow(a_bar.getEntry(1,i),2)+Math.pow(a_bar.getEntry(2,i),2));
            value.setEntry(i, modelI);

            double a1 = selectedAccData.getEntry(0,i);
            double a2 = selectedAccData.getEntry(1,i);
            double a3 = selectedAccData.getEntry(2,i);

            jacobian.setEntry(i, 0, 2*E5*a2*(E7 - E4*a1 + E1*E5*a2 - E2*E6*a3));
            jacobian.setEntry(i, 1, -2*E6*a3*(E7 - E4*a1 + E1*E5*a2 - 
E2*E6*a3));
            jacobian.setEntry(i, 2, 2*E6*a3*(E8 - E5*a2 + E3*E6*a3));
            jacobian.setEntry(i, 3, -2*a1*(E7 - E4*a1 + E1*E5*a2 - E2*E6*a3));
            jacobian.setEntry(i, 4, 2*E1*a2*(E7 - E4*a1 + E1*E5*a2 - E2*E6*a3) 
- 2*a2*(E8 - E5*a2 + E3*E6*a3));
            jacobian.setEntry(i, 5, 2*E3*a3*(E8 - E5*a2 + E3*E6*a3) - 
2*E2*a3*(E7 - E4*a1 + E1*E5*a2 - E2*E6*a3) - 2*a3*(E9 - E6*a3));
            jacobian.setEntry(i, 6, 2*E7 - 2*E4*a1 + 2*E1*E5*a2 - 2*E2*E6*a3);
            jacobian.setEntry(i, 7, 2*E8 - 2*E5*a2 + 2*E3*E6*a3);
            jacobian.setEntry(i, 8, 2*E9 - 2*E6*a3);
        }

        return new Pair<>(value, jacobian);
    }
};

Equivalent Matlab Code:
theta_pr = [0, 0, 0, 0, 0, 0, 0, 0, 0];
ObjectiveFunction = @(theta_pr) costFunc(theta_pr, selectedAccData);
options = optimset('MaxFunEvals', 150000, 'MaxIter', 6000, 'TolFun', 10^(-10));
[theta_pr rsnorm] = lsqnonlin(ObjectiveFunction, theta_pr, [], [], options);
function [ res_vector ] = costFunc( E, a_hat )

misalignmentMatrix = [1, -E(1), E(2); 0, 1, -E(3); 0, 0, 1];
scalingMtrix = diag([E(4), E(5), E(6)]);

a_bar = misalignmentMatrix*scalingMtrix*(a_hat) - (diag([E(7), E(8), 
E(9)])*ones(3, length(a_hat)));

residuals = zeros(length(a_bar(1,:)), 1);

for i = 1:length(a_bar(1,:))
residuals(i,1) = 9.81744^2 - (a_bar(1,i)^2 + a_bar(2,i)^2 + a_bar(3,i)^2)
end

        res_vector = residuals;

end

If this is not the correct forum to be asking this, or if there is a better way 
to communicate and share my code, please let me know.

Thank you, 

Marshall

Reply via email to