diff --git a/pathfinder/model/oscillating/model.py b/pathfinder/model/oscillating/model.py index be782d8..4c476c2 100644 --- a/pathfinder/model/oscillating/model.py +++ b/pathfinder/model/oscillating/model.py @@ -37,8 +37,6 @@ class DotOscillatingDipoleModel(): return jac_to_return def sol(self, initial_dipole=(0.1, 0.1, 0.1), initial_position=(.1, .1, .1), initial_frequency=1, use_root=True): - initial = numpy.tile(numpy.concatenate((initial_dipole, initial_position, initial_frequency)), self.n) - if use_root and self.m == 7 * self.n: - # We are perfectly specified - return scipy.optimize.root(self.costs(), initial, jac=self.jac(), tol=1e-12) + initial = numpy.tile(numpy.concatenate((initial_dipole, initial_position, initial_frequency), axis=None), self.n) + return scipy.optimize.least_squares(self.costs(), initial, jac=self.jac(), ftol=1e-15, gtol=3e-16) diff --git a/tests/model/oscillating/test_osc_model_sol.py b/tests/model/oscillating/test_osc_model_sol.py new file mode 100644 index 0000000..d61f4e1 --- /dev/null +++ b/tests/model/oscillating/test_osc_model_sol.py @@ -0,0 +1,42 @@ +import numpy +import pathfinder.model.oscillating + + +def chunk_n_sort(pts): + pt_length = 6 + chunked_pts = [pts[i: i + pt_length] for i in range(0, len(pts), pt_length)] + + return sorted(chunked_pts, key=lambda x: x[0]) + + +def print_result(msg, result): + print(msg) + print(f"\tResult: {chunk_n_sort(result.x)}") + print(f"\tSuccess: {result.success}. {result.message}") + try: + print(f"\tFunc evals: {result.nfev}") + except AttributeError: + pass + try: + print(f"\tJacb evals: {result.njev}") + except AttributeError: + pass + + +def test_one_dipole_six_dot_two_frequencies(): + # setup + dot_inputs = [ + ([0, 0, .01], 5), ([-1, 0, -.01], 5), ([-2, 0, 0], 5), ([-1, -1, 0], 5), ([-1, -1, 1], 5), ([0, -2, 0], 5), + ([0, 0, .01], 1), ([-1, 0, -.01], 1), ([-2, 0, 0], 1), ([-1, -1, 0], 1), ([-1, -1, 1], 1), ([0, -2, 0], 1) + ] + dipole = pathfinder.model.oscillating.OscillatingDipole([1, 2, 3], [0, 4, -1], 7) + expected_result = numpy.array([1, 2, 3, 0, 4, -1, 7]) + dipole_arrangement = pathfinder.model.oscillating.OscillatingDipoleArrangement([dipole]) + dot_measurements = dipole_arrangement.get_dot_measurements(dot_inputs) + + model = pathfinder.model.oscillating.DotOscillatingDipoleModel(dot_measurements, 1) + res = model.sol() + + print_result("one oscillating dipole six dots", res) + assert res.success, "The solution for a single dipole and six dots should have succeeded." + numpy.testing.assert_allclose(res.x, expected_result, err_msg="Dipole wasn't as expected.", rtol=1e-6, atol=1e-6)