From 4011a5c69862a7744ed27adcb5f924e71cd09f8d Mon Sep 17 00:00:00 2001 From: Deepak Date: Sun, 29 Aug 2021 15:38:41 -0500 Subject: [PATCH] Adds better test for static dipole as well as calculating dot measurements --- pathfinder/model/__init__.py | 4 ++-- pathfinder/model/dot.py | 7 ++----- pathfinder/model/staticdipole.py | 33 +++++++++++++++++++++++++++++--- tests/model/test_staticdipole.py | 23 ++++++++++++++++++++++ 4 files changed, 57 insertions(+), 10 deletions(-) create mode 100644 tests/model/test_staticdipole.py diff --git a/pathfinder/model/__init__.py b/pathfinder/model/__init__.py index 65ff72d..1425108 100644 --- a/pathfinder/model/__init__.py +++ b/pathfinder/model/__init__.py @@ -1,5 +1,5 @@ from pathfinder.model.dot import DotMeasurement from pathfinder.model.model import DotDipoleModel -from pathfinder.model.staticdipole import StaticDipole +from pathfinder.model.staticdipole import StaticDipoleArrangement, StaticDipole -__all__ = ['DotMeasurement', 'DotDipoleModel', 'StaticDipole'] +__all__ = ['DotMeasurement', 'DotDipoleModel', 'StaticDipoleArrangement', 'StaticDipole'] diff --git a/pathfinder/model/dot.py b/pathfinder/model/dot.py index a59b23d..b8f0b3e 100644 --- a/pathfinder/model/dot.py +++ b/pathfinder/model/dot.py @@ -2,8 +2,6 @@ from dataclasses import dataclass import numpy import numpy.typing -from pathfinder.model.staticdipole import StaticDipole - @dataclass class DotMeasurement(): @@ -38,9 +36,8 @@ class DotMeasurement(): p = pt[0:3] # hardcoded here because chances s = pt[3:6] # are we'll only ever work in 3d. - dipole = StaticDipole(p, s) - - return dipole.v_at_position(self.r) + diff = self.r - s + return p.dot(diff) / (numpy.linalg.norm(diff)**3) def cost(self, pts: numpy.ndarray) -> float: # 6 because dipole in 3d has 6 degrees of freedom. diff --git a/pathfinder/model/staticdipole.py b/pathfinder/model/staticdipole.py index 0e9c09a..14f12be 100644 --- a/pathfinder/model/staticdipole.py +++ b/pathfinder/model/staticdipole.py @@ -1,6 +1,8 @@ from dataclasses import dataclass import numpy import numpy.typing +from typing import Sequence, List +from pathfinder.model.dot import DotMeasurement @dataclass @@ -20,12 +22,37 @@ class StaticDipole(): def __post_init__(self) -> None: ''' - Coerce the inputs into numpy arrays. + Coerce the inputs into numpy arrays. ''' self.p = numpy.array(self.p) self.s = numpy.array(self.s) - def v_at_position(self, r: numpy.typing.ArrayLike) -> float: - + def v_at_position(self, r: numpy.ndarray) -> float: + ''' + Mirrors the same function in pathfinder.model.dot. + ''' diff = r - self.s return self.p.dot(diff) / (numpy.linalg.norm(diff)**3) + + +class StaticDipoleArrangement(): + ''' + A collection of static dipoles, which we are interested in being able to characterise. + + Parameters + -------- + dipoles : Sequence[StaticDipole] + ''' + def __init__(self, dipoles): + self.dipoles = dipoles + + def get_dot_measurement(self, dot_position: numpy.typing.ArrayLike) -> DotMeasurement: + r = numpy.array(dot_position) + return DotMeasurement(sum([dipole.v_at_position(r) for dipole in self.dipoles]), r) + + def get_dot_measurements(self, dot_positions: Sequence[numpy.typing.ArrayLike]) -> List[DotMeasurement]: + ''' + For a series of points, each with three coordinates, return + ''' + + return [self.get_dot_measurement(dot_position) for dot_position in dot_positions] diff --git a/tests/model/test_staticdipole.py b/tests/model/test_staticdipole.py new file mode 100644 index 0000000..3ee1298 --- /dev/null +++ b/tests/model/test_staticdipole.py @@ -0,0 +1,23 @@ +import numpy +import pathfinder.model as model + + +def test_static_dipole(): + d1 = model.StaticDipole((1, 2, 3), (4, 5, 6)) + d2 = model.StaticDipole((4, 5, 6), (1, 2, 3)) + dipoles = model.StaticDipoleArrangement([d1, d2]) + + dot_position1 = (-1, -1, -1) + expected_v1 = -0.3338923121348659 + + numpy.testing.assert_allclose(dipoles.get_dot_measurement(dot_position1).v, expected_v1, err_msg="Voltage at dot isn't as expected.") + numpy.testing.assert_allclose(dipoles.get_dot_measurement(dot_position1).r, dot_position1, err_msg="Dot isn't where expected.") + + # test multiple dots + dot_position2 = (-1, -1, -5) + expected_v2 = -0.1254445237566694 + + both_measurements = dipoles.get_dot_measurements([dot_position1, dot_position2]) + measured_voltages = numpy.sort([m.v for m in both_measurements]) + expected_measured_voltages = numpy.sort([expected_v1, expected_v2]) + numpy.testing.assert_allclose(measured_voltages, expected_measured_voltages, err_msg="Didn't get the measured voltages expected")