def test_solve_with_finite_differences(self): """ Minimize a function for which analytic derivatives are not provided. Provides test coverage for the finite-differencing options. """ #for solver in [least_squares_serial_solve]: for solver in solvers: if solver == serial_solve: continue for abs_step in [0, 1.0e-7]: rel_steps = [0, 1.0e-7] if abs_step == 0: rel_steps = [1.0e-7] for rel_step in rel_steps: for diff_method in ["forward", "centered"]: logger.debug(f'solver={solver} diff_method={diff_method} ' \ f'abs_step={abs_step} rel_step={rel_step}') b = Beale() b.set_dofs([0.1, -0.2]) prob = LeastSquaresProblem([(b, 0, 1)], diff_method=diff_method, abs_step=abs_step, rel_step=rel_step) #least_squares_serial_solve(prob, grad=True) solver(prob, grad=True) np.testing.assert_allclose(prob.x, [3, 0.5]) np.testing.assert_allclose(prob.f(), [0, 0, 0], atol=1e-10)
def test_failures(self): """ Verify that the expected residuals are returned in cases where the objective function evaluations fail. """ o1 = Failer() r1 = Rosenbrock() fail_val = 1.0e6 prob1 = LeastSquaresProblem([(r1.terms, 0, 1), (o1, 0, 1)], fail=fail_val) # First evaluation should not fail. f = prob1.f() print(f) np.testing.assert_allclose(f, [-1, 0, 1, 1, 1]) # Second evaluation should fail. f = prob1.f() print(f) np.testing.assert_allclose(f, np.full(5, fail_val)) # Third evaluation should not fail. f = prob1.f() print(f) np.testing.assert_allclose(f, [-1, 0, 1, 1, 1])
def test_supply_tuples(self): """ Test basic usage """ # Objective function f(x) = ((x - 3) / 2) ** 2 iden1 = Identity() term1 = (iden1.J, 3, 0.25) prob = LeastSquaresProblem([term1]) self.assertAlmostEqual(prob.objective(), 2.25) self.assertAlmostEqual(prob.objective(), sum(t.f_out() for t in prob.terms)) self.assertEqual(len(prob.dofs.f()), 1) self.assertAlmostEqual(prob.dofs.f()[0], 0) self.assertEqual(len(prob.f()), 1) self.assertAlmostEqual(prob.f()[0], -1.5) self.assertAlmostEqual(prob.objective_from_shifted_f(prob.f()), 2.25) self.assertAlmostEqual(prob.objective_from_unshifted_f(prob.dofs.f()), 2.25) iden1.set_dofs([10]) self.assertAlmostEqual(prob.objective(), 12.25) self.assertAlmostEqual(prob.objective(), sum(t.f_out() for t in prob.terms)) self.assertAlmostEqual(prob.objective_from_shifted_f(prob.f()), 12.25) self.assertAlmostEqual(prob.objective_from_unshifted_f(prob.dofs.f()), 12.25) self.assertAlmostEqual(prob.objective([0]), 2.25) self.assertAlmostEqual(prob.objective([10]), 12.25) self.assertEqual(prob.dofs.all_owners, [iden1]) self.assertEqual(prob.dofs.dof_owners, [iden1]) # Objective function # f(x,y) = ((x - 3) / 2) ** 2 + ((y + 4) / 5) ** 2 iden2 = Identity() term2 = (iden2.J, -4, 0.04) prob = LeastSquaresProblem([term1, term2]) self.assertAlmostEqual(prob.objective(), 12.89) self.assertAlmostEqual(prob.objective(), sum(t.f_out() for t in prob.terms)) self.assertEqual(len(prob.f()), 2) self.assertAlmostEqual(prob.objective_from_shifted_f(prob.f()), 12.89) self.assertAlmostEqual(prob.objective_from_unshifted_f(prob.dofs.f()), 12.89) iden1.set_dofs([5]) iden2.set_dofs([-7]) self.assertAlmostEqual(prob.objective(), 1.36) self.assertAlmostEqual(prob.objective(), sum(t.f_out() for t in prob.terms)) self.assertEqual(len(prob.f()), 2) self.assertAlmostEqual(prob.objective_from_shifted_f(prob.f()), 1.36) self.assertAlmostEqual(prob.objective_from_unshifted_f(prob.dofs.f()), 1.36) self.assertAlmostEqual(prob.objective([10, 0]), 12.89) self.assertAlmostEqual(prob.objective([5, -7]), 1.36) self.assertEqual(prob.dofs.dof_owners, [iden1, iden2]) self.assertEqual(prob.dofs.all_owners, [iden1, iden2])
def test_vmec_failure(self): """ Verify that failures of VMEC are correctly caught and represented by large values of the objective function. """ for j in range(2): filename = os.path.join(TEST_DIR, 'input.li383_low_res') vmec = Vmec(filename) # Use the objective function from # stellopt_scenarios_2DOF_targetIotaAndVolume: if j == 0: prob = LeastSquaresProblem([(vmec.iota_axis, 0.41, 1), (vmec.volume, 0.15, 1)]) fail_val = 1e12 else: # Try a custom failure value fail_val = 2.0e30 prob = LeastSquaresProblem([(vmec.iota_axis, 0.41, 1), (vmec.volume, 0.15, 1)], fail=fail_val) r00 = vmec.boundary.get_rc(0, 0) # The first evaluation should succeed. f = prob.f() print(f[0], f[1]) correct_f = [-0.004577338528148067, 2.8313872701632925] # Don't worry too much about accuracy here. np.testing.assert_allclose(f, correct_f, rtol=0.1) # Now set a crazy boundary shape to make VMEC fail. This # boundary causes VMEC to hit the max number of iterations # without meeting ftol. vmec.boundary.set_rc(0, 0, 0.2) vmec.need_to_run_code = True f = prob.f() print(f) np.testing.assert_allclose(f, np.full(2, fail_val)) # Restore a reasonable boundary shape. VMEC should work again. vmec.boundary.set_rc(0, 0, r00) vmec.need_to_run_code = True f = prob.f() print(f) np.testing.assert_allclose(f, correct_f, rtol=0.1) # Now set a self-intersecting boundary shape. This causes VMEC # to fail with "ARNORM OR AZNORM EQUAL ZERO IN BCOVAR" before # it even starts iterating. orig_mode = vmec.boundary.get_rc(1, 3) vmec.boundary.set_rc(1, 3, 0.5) vmec.need_to_run_code = True f = prob.f() print(f) np.testing.assert_allclose(f, np.full(2, fail_val)) # Restore a reasonable boundary shape. VMEC should work again. vmec.boundary.set_rc(1, 3, orig_mode) vmec.need_to_run_code = True f = prob.f() print(f) np.testing.assert_allclose(f, correct_f, rtol=0.1)