/** * Dense trust-region unconstrained minimization using Dogleg steps and BFGS to estimate the Hessian. * @param config Trust region configuration * @return The new optimization routine */ public static UnconstrainedMinimization doglegBFGS( @Nullable ConfigTrustRegion config ) { if( config == null ) config = new ConfigTrustRegion(); HessianBFGS hessian = new HessianBFGS_DDRM(true); TrustRegionUpdateDogleg_F64<DMatrixRMaj> update = new TrustRegionUpdateDogleg_F64<>(); UnconMinTrustRegionBFGS_F64 alg = new UnconMinTrustRegionBFGS_F64(update,hessian); alg.configure(config); return alg; }
/** * Dense trust-region unconstrained minimization using Dogleg steps and BFGS to estimate the Hessian. * @param config Trust region configuration * @return The new optimization routine */ public static UnconstrainedMinimization doglegBFGS( @Nullable ConfigTrustRegion config ) { if( config == null ) config = new ConfigTrustRegion(); HessianBFGS hessian = new HessianBFGS_DDRM(true); TrustRegionUpdateDogleg_F64<DMatrixRMaj> update = new TrustRegionUpdateDogleg_F64<>(); UnconMinTrustRegionBFGS_F64 alg = new UnconMinTrustRegionBFGS_F64(update,hessian); alg.configure(config); return alg; }
/** * Creates a sparse Schur Complement trust region optimization using dogleg steps. * * @see UnconLeastSqTrustRegionSchur_F64 * * @param config Trust region configuration * @return The new optimization routine */ public static UnconstrainedLeastSquaresSchur<DMatrixSparseCSC> doglegSchur( @Nullable ConfigTrustRegion config ) { if( config == null ) config = new ConfigTrustRegion(); HessianSchurComplement_DSCC hessian = new HessianSchurComplement_DSCC(); TrustRegionUpdateDogleg_F64<DMatrixSparseCSC> update = new TrustRegionUpdateDogleg_F64<>(); UnconLeastSqTrustRegionSchur_F64<DMatrixSparseCSC> alg = new UnconLeastSqTrustRegionSchur_F64<>(update,hessian); alg.configure(config); return alg; }
/** * Creates a sparse Schur Complement trust region optimization using dogleg steps. * * @see UnconLeastSqTrustRegionSchur_F64 * * @param config Trust region configuration * @return The new optimization routine */ public static UnconstrainedLeastSquaresSchur<DMatrixSparseCSC> doglegSchur( @Nullable ConfigTrustRegion config ) { if( config == null ) config = new ConfigTrustRegion(); HessianSchurComplement_DSCC hessian = new HessianSchurComplement_DSCC(); TrustRegionUpdateDogleg_F64<DMatrixSparseCSC> update = new TrustRegionUpdateDogleg_F64<>(); UnconLeastSqTrustRegionSchur_F64<DMatrixSparseCSC> alg = new UnconLeastSqTrustRegionSchur_F64<>(update,hessian); alg.configure(config); return alg; }
protected UnconMinTrustRegionBFGS_F64 createAlg() { TrustRegionUpdateDogleg_F64 dogleg = new TrustRegionUpdateDogleg_F64(); HessianBFGS_DDRM hessian = new HessianBFGS_DDRM(true); return new UnconMinTrustRegionBFGS_F64(dogleg,hessian); } }
/** * Creates a sparse trust region optimization using dogleg steps. * * @see UnconLeastSqTrustRegion_F64 * * @param config Trust region configuration * @return The new optimization routine */ public static UnconstrainedLeastSquares<DMatrixSparseCSC> dogleg( @Nullable ConfigTrustRegion config) { if( config == null ) config = new ConfigTrustRegion(); LinearSolverSparse<DMatrixSparseCSC,DMatrixRMaj> solver = LinearSolverFactory_DSCC.cholesky(FillReducing.NONE); HessianLeastSquares_DSCC hessian = new HessianLeastSquares_DSCC(solver); MatrixMath_DSCC math = new MatrixMath_DSCC(); TrustRegionUpdateDogleg_F64<DMatrixSparseCSC> update = new TrustRegionUpdateDogleg_F64<>(); UnconLeastSqTrustRegion_F64<DMatrixSparseCSC> alg = new UnconLeastSqTrustRegion_F64<>(update,hessian,math); alg.configure(config); return alg; }
/** * Creates a sparse trust region optimization using dogleg steps. * * @see UnconLeastSqTrustRegion_F64 * * @param config Trust region configuration * @return The new optimization routine */ public static UnconstrainedLeastSquares<DMatrixSparseCSC> dogleg( @Nullable ConfigTrustRegion config) { if( config == null ) config = new ConfigTrustRegion(); LinearSolverSparse<DMatrixSparseCSC,DMatrixRMaj> solver = LinearSolverFactory_DSCC.cholesky(FillReducing.NONE); HessianLeastSquares_DSCC hessian = new HessianLeastSquares_DSCC(solver); MatrixMath_DSCC math = new MatrixMath_DSCC(); TrustRegionUpdateDogleg_F64<DMatrixSparseCSC> update = new TrustRegionUpdateDogleg_F64<>(); UnconLeastSqTrustRegion_F64<DMatrixSparseCSC> alg = new UnconLeastSqTrustRegion_F64<>(update,hessian,math); alg.configure(config); return alg; }
/** * Creates a dense trust region least-squares optimization using dogleg steps. Solver works on the B=J<sup>T</sup>J matrix. * * @see UnconLeastSqTrustRegion_F64 * * @param config Trust region configuration * @return The new optimization routine */ public static UnconstrainedLeastSquares<DMatrixRMaj> dogleg( @Nullable ConfigTrustRegion config, boolean robust ) { if( config == null ) config = new ConfigTrustRegion(); LinearSolverDense<DMatrixRMaj> solver; if( robust ) solver = LinearSolverFactory_DDRM.leastSquaresQrPivot(true,false); else solver = LinearSolverFactory_DDRM.chol(100); HessianLeastSquares_DDRM hessian = new HessianLeastSquares_DDRM(solver); MatrixMath_DDRM math = new MatrixMath_DDRM(); TrustRegionUpdateDogleg_F64<DMatrixRMaj> update = new TrustRegionUpdateDogleg_F64<>(); UnconLeastSqTrustRegion_F64<DMatrixRMaj> alg = new UnconLeastSqTrustRegion_F64<>(update,hessian,math); alg.configure(config); return alg; }
/** * Creates a dense trust region least-squares optimization using dogleg steps. Solver works on the B=J<sup>T</sup>J matrix. * * @see UnconLeastSqTrustRegion_F64 * * @param config Trust region configuration * @return The new optimization routine */ public static UnconstrainedLeastSquares<DMatrixRMaj> dogleg( @Nullable ConfigTrustRegion config, boolean robust ) { if( config == null ) config = new ConfigTrustRegion(); LinearSolverDense<DMatrixRMaj> solver; if( robust ) solver = LinearSolverFactory_DDRM.leastSquaresQrPivot(true,false); else solver = LinearSolverFactory_DDRM.chol(100); HessianLeastSquares_DDRM hessian = new HessianLeastSquares_DDRM(solver); MatrixMath_DDRM math = new MatrixMath_DDRM(); TrustRegionUpdateDogleg_F64<DMatrixRMaj> update = new TrustRegionUpdateDogleg_F64<>(); UnconLeastSqTrustRegion_F64<DMatrixRMaj> alg = new UnconLeastSqTrustRegion_F64<>(update,hessian,math); alg.configure(config); return alg; }
@Override protected UnconstrainedMinimization createSearch() { ConfigTrustRegion config = new ConfigTrustRegion(); config.regionInitial = 100; TrustRegionUpdateDogleg_F64 dogleg = new TrustRegionUpdateDogleg_F64(); HessianBFGS_DDRM hessian = new HessianBFGS_DDRM(true); UnconMinTrustRegionBFGS_F64 tr = new UnconMinTrustRegionBFGS_F64(dogleg,hessian); tr.configure(config); return tr; } }
@Override protected UnconstrainedLeastSquaresSchur<DMatrixSparseCSC> createSearch(double minimumValue) { ConfigTrustRegion config = new ConfigTrustRegion(); // config.regionInitial = 1; config.hessianScaling = true; TrustRegionUpdateDogleg_F64<DMatrixSparseCSC> dogleg = new TrustRegionUpdateDogleg_F64<>(); HessianSchurComplement_DSCC hessian = new HessianSchurComplement_DSCC(); UnconLeastSqTrustRegionSchur_F64<DMatrixSparseCSC> tr = new UnconLeastSqTrustRegionSchur_F64<>(dogleg,hessian); tr.configure(config); // tr.setVerbose(true); return tr; } }
private static UnconLeastSqTrustRegion_F64<DMatrixRMaj> createSolver() { LinearSolverDense<DMatrixRMaj> solver = LinearSolverFactory_DDRM.chol(2); HessianLeastSquares_DDRM hessian = new HessianLeastSquares_DDRM(solver); TrustRegionUpdateDogleg_F64<DMatrixRMaj> alg = new TrustRegionUpdateDogleg_F64<>(); return new UnconLeastSqTrustRegion_F64<>(alg,hessian, new MatrixMath_DDRM()); }
@Override protected UnconstrainedLeastSquares<DMatrixSparseCSC> createSearch(double minimumValue) { ConfigTrustRegion config = new ConfigTrustRegion(); config.regionInitial = 1; LinearSolverSparse<DMatrixSparseCSC,DMatrixRMaj> solver = LinearSolverFactory_DSCC.cholesky(FillReducing.NONE); HessianLeastSquares_DSCC hessian = new HessianLeastSquares_DSCC(solver); TrustRegionUpdateDogleg_F64<DMatrixSparseCSC> alg = new TrustRegionUpdateDogleg_F64<>(); UnconLeastSqTrustRegion_F64<DMatrixSparseCSC> tr = new UnconLeastSqTrustRegion_F64<>( alg,hessian, new MatrixMath_DSCC()); tr.configure(config); // tr.setVerbose(true); return tr; } }
@Test public void cost() { double expected = 0.5*VectorVectorMult_DDRM.innerProd(residuals,residuals); TrustRegionUpdateDogleg_F64<DMatrixSparseCSC> dogleg = new TrustRegionUpdateDogleg_F64<>(); HessianSchurComplement_DSCC hessian = new HessianSchurComplement_DSCC(); UnconLeastSqTrustRegionSchur_F64<DMatrixSparseCSC> alg = new UnconLeastSqTrustRegionSchur_F64<>(dogleg,hessian); alg.setFunction(new MockFunction(),new MockJacobian()); alg.initialize(new double[N],1e-6,1e-8); double found = alg.cost(new DMatrixRMaj(N,1)); assertEquals(expected,found, UtilEjml.TEST_F64); }
/** * See if it correctly identifies a non SPD matrix */ @Test public void initializeUpdate_spd() { TrustRegionUpdateDogleg_F64<DMatrixRMaj> alg = new TrustRegionUpdateDogleg_F64<>(); MockTrustRegionBase owner = new MockTrustRegionBase(alg); alg.initialize(owner,2,0); owner.hessian().set(new double[][]{{1,0},{0,1}}); owner.gradientNorm = 1; owner.gradient.set(new double[][]{{1},{0}}); alg.initializeUpdate(); assertTrue(alg.positiveDefinite); owner.hessian().set(new double[][]{{0,1},{1,0}}); alg.initializeUpdate(); assertFalse(alg.positiveDefinite); }
@Test public void functionGradientHessian() { TrustRegionUpdateDogleg_F64<DMatrixSparseCSC> dogleg = new TrustRegionUpdateDogleg_F64<>(); HessianSchurComplement_DSCC hessian = new HessianSchurComplement_DSCC(); UnconLeastSqTrustRegionSchur_F64<DMatrixSparseCSC> alg = new UnconLeastSqTrustRegionSchur_F64<>(dogleg,hessian); alg.setFunction(new MockFunction(),new MockJacobian()); alg.initialize(new double[N],1e-6,1e-8); DMatrixRMaj x = new DMatrixRMaj(1,1); DMatrixRMaj g = new DMatrixRMaj(N,1); alg.functionGradientHessian(x,false,g,hessian); // Only the gradient is computed and returned. The hessian is saved internally DMatrixRMaj exp_g = new DMatrixRMaj(N,1); CommonOps_DSCC.multTransA(J,residuals,exp_g); assertTrue(MatrixFeatures_DDRM.isIdentical(exp_g,g,UtilEjml.TEST_F64)); }
@Test public void computeUpdate_cauchy_after() { TrustRegionUpdateDogleg_F64<DMatrixRMaj> alg = new TrustRegionUpdateDogleg_F64<>(); MockTrustRegionBase owner = new MockTrustRegionBase(alg); alg.initialize(owner,2,0); owner.hessian().set(new double[][]{{2,0.1},{0.1,1.5}}); // have Gn and cauchy lie along a line so the math is easy owner.gradientNorm = 2.1; setGradient(alg.owner.gradient,-1,0,owner.gradientNorm); CommonOps_DDRM.divide(owner.gradient,owner.gradientNorm,alg.direction); alg.gBg = owner.hessian.innerVectorHessian(alg.direction); alg.positiveDefinite = true; alg.distanceGN = 5; alg.distanceCauchy = 3; alg.stepCauchy.set(new double[][]{{3},{0}}); alg.stepGN.set(new double[][]{{5},{0}}); double radius = 2; DMatrixRMaj p = new DMatrixRMaj(2,1); alg.computeUpdate(p,radius); assertEquals(owner.computePredictedReduction(p),alg.getPredictedReduction(),UtilEjml.TEST_F64); assertEquals(radius, alg.getStepLength(), UtilEjml.TEST_F64); assertEquals(radius, NormOps_DDRM.normF(p), UtilEjml.TEST_F64); }
@Test public void computeUpdate_NegativeDefinite() { TrustRegionUpdateDogleg_F64<DMatrixRMaj> alg = new TrustRegionUpdateDogleg_F64<>(); MockTrustRegionBase owner = new MockTrustRegionBase(alg); alg.initialize(owner,2,0); double radius = 2; setGradient(alg.owner.gradient,-1,0,1000); alg.owner.gradientNorm = NormOps_DDRM.normF(alg.owner.gradient); CommonOps_DDRM.divide(owner.gradient,owner.gradientNorm,alg.direction); owner.hessian().set(new double[][]{{-2,0.1},{0.1,-1.5}}); alg.gBg = owner.hessian.innerVectorHessian(alg.direction); alg.positiveDefinite = false; alg.owner.fx = 1000; DMatrixRMaj p = new DMatrixRMaj(2,1); alg.computeUpdate(p,radius); assertEquals(2,p.get(0,0), UtilEjml.TEST_F64); assertEquals(0,p.get(1,0), UtilEjml.TEST_F64); assertEquals(owner.computePredictedReduction(p),alg.getPredictedReduction(),UtilEjml.TEST_F64); assertEquals(radius, alg.getStepLength(), UtilEjml.TEST_F64); assertEquals(radius, NormOps_DDRM.normF(p), UtilEjml.TEST_F64); }
/** * The Gauss-Newton step is inside the trust region so we will just use that */ @Test public void computeUpdate_gn_inside() { TrustRegionUpdateDogleg_F64<DMatrixRMaj> alg = new TrustRegionUpdateDogleg_F64<>(); MockTrustRegionBase owner = new MockTrustRegionBase(alg); alg.initialize(owner,2,0); alg.positiveDefinite = true; owner.hessian().set(new double[][]{{2,0.1},{0.1,1.5}}); setGradient(alg.owner.gradient,-1,0,1.5); alg.owner.gradientNorm = NormOps_DDRM.normF(alg.owner.gradient); alg.gBg = owner.hessian.innerVectorHessian(alg.direction); alg.stepGN.set(new double[][]{{1},{2}}); alg.distanceGN = NormOps_DDRM.normF(alg.stepGN); DMatrixRMaj p = new DMatrixRMaj(2,1); alg.computeUpdate(p,4); assertTrue(MatrixFeatures_DDRM.isIdentical(p,alg.stepGN,UtilEjml.TEST_F64)); assertEquals(owner.computePredictedReduction(p),alg.getPredictedReduction(),UtilEjml.TEST_F64); assertEquals(alg.distanceGN, alg.getStepLength(), UtilEjml.TEST_F64); assertEquals(alg.distanceGN, NormOps_DDRM.normF(p), UtilEjml.TEST_F64); }
@Test public void computeUpdate_cauchy_inside() { TrustRegionUpdateDogleg_F64<DMatrixRMaj> alg = new TrustRegionUpdateDogleg_F64<>(); MockTrustRegionBase owner = new MockTrustRegionBase(alg); alg.initialize(owner,2,0); // have Gn and cauchy lie along a line so the math is easy double radius = 2; owner.hessian().set(new double[][]{{2,0.1},{0.1,1.5}}); alg.owner.gradientNorm = 1.5; setGradient(alg.owner.gradient,-1,0,alg.owner.gradientNorm); CommonOps_DDRM.divide(owner.gradient,owner.gradientNorm,alg.direction); alg.gBg = owner.hessian.innerVectorHessian(alg.direction); alg.positiveDefinite = true; alg.stepGN.set(new double[][]{{5},{0}}); alg.distanceGN = 5; alg.stepCauchy.set(new double[][]{{1.5},{0}}); alg.distanceCauchy = NormOps_DDRM.normF(alg.stepCauchy); alg.gBg = 1; DMatrixRMaj p = new DMatrixRMaj(2,1); alg.computeUpdate(p,radius); assertEquals(2,p.get(0,0), UtilEjml.TEST_F64); assertEquals(0,p.get(1,0), UtilEjml.TEST_F64); assertEquals(owner.computePredictedReduction(p),alg.getPredictedReduction(),UtilEjml.TEST_F64); assertEquals(radius, alg.getStepLength(), UtilEjml.TEST_F64); assertEquals(radius, NormOps_DDRM.normF(p), UtilEjml.TEST_F64); }