@Test public void computeUpdate_positiveDefinite() { double radius = 2; MockOwner owner = new MockOwner(null); TrustRegionUpdateCauchy_F64<DMatrixRMaj> alg = new TrustRegionUpdateCauchy_F64<>(); alg.initialize(owner,2,-1); DMatrixRMaj p = new DMatrixRMaj(2,1); // Unconstrained solution is way outside the region bounds. Make sure this contrains it owner.hessian().set(new double[][]{{2,0.1},{0.1,1.5}}); owner.gradientNorm = 1000; setGradient(owner.gradient,0.1,0.4,owner.gradientNorm); CommonOps_DDRM.divide(owner.gradient,owner.gradientNorm,alg.direction); alg.gBg = owner.hessian.innerVectorHessian(alg.direction); 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); // should be inside the bounds owner.gradientNorm = 0.1; setGradient(owner.gradient,0.1,0.4,owner.gradientNorm); alg.computeUpdate(p,radius); double n = NormOps_DDRM.normF(p); assertTrue(n > 0 && n < radius); double expectedRadius = owner.gradientNorm/alg.gBg; assertEquals(owner.computePredictedReduction(p),alg.getPredictedReduction(),UtilEjml.TEST_F64); assertEquals(expectedRadius, alg.getStepLength(), UtilEjml.TEST_F64); assertEquals(expectedRadius, NormOps_DDRM.normF(p), UtilEjml.TEST_F64); }
@Test public void computeUpdate_negativeDefinite() { MockOwner owner = new MockOwner(null); TrustRegionUpdateCauchy_F64<DMatrixRMaj> alg = new TrustRegionUpdateCauchy_F64<>(); alg.initialize(owner,2,-1); owner.gradientNorm = 0.1; setGradient(owner.gradient,0.1,0.4,owner.gradientNorm); 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); DMatrixRMaj p = new DMatrixRMaj(2,1); // should hit the boundary owner.fx = 1000; alg.computeUpdate(p,2); assertEquals(owner.computePredictedReduction(p),alg.getPredictedReduction(),UtilEjml.TEST_F64); assertEquals(2, alg.getStepLength(), UtilEjml.TEST_F64); assertEquals(2, NormOps_DDRM.normF(p), 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); }
/** * 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_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); }
@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); }