makeinputs #11

Merged
deepak merged 3 commits from makeinputs into master 2022-03-27 22:25:58 +00:00
9 changed files with 236 additions and 16 deletions

4
pdme/inputs/__init__.py Normal file
View File

@ -0,0 +1,4 @@
from pdme.inputs.dot_inputs import inputs_with_frequency_range, input_pairs_with_frequency_range
__all__ = ['inputs_with_frequency_range', 'input_pairs_with_frequency_range']

13
pdme/inputs/dot_inputs.py Normal file
View File

@ -0,0 +1,13 @@
import numpy
import numpy.typing
import itertools
from typing import Sequence, Tuple
def inputs_with_frequency_range(dots: Sequence[numpy.typing.ArrayLike], frequency_range: Sequence[float]) -> Sequence[Tuple[numpy.typing.ArrayLike, float]]:
return list(itertools.chain(*[[(dot, f) for f in frequency_range] for dot in dots]))
def input_pairs_with_frequency_range(dots: Sequence[numpy.typing.ArrayLike], frequency_range: Sequence[float]) -> Sequence[Tuple[numpy.typing.ArrayLike, numpy.typing.ArrayLike, float]]:
all_pairs = itertools.combinations(dots, 2)
return list(itertools.chain(*[[(dot1, dot2, f) for f in frequency_range] for (dot1, dot2) in all_pairs]))

View File

@ -1,4 +1,7 @@
from pdme.measurement.dot_measure import DotMeasurement
from pdme.measurement.dot_measure import DotMeasurement, DotRangeMeasurement
from pdme.measurement.dot_pair_measure import DotPairMeasurement, DotPairRangeMeasurement
from pdme.measurement.oscillating_dipole import OscillatingDipole, OscillatingDipoleArrangement
from pdme.measurement.input_types import DotInput, DotPairInput
__all__ = ['DotMeasurement', 'DotRangeMeasurement', 'OscillatingDipole', 'OscillatingDipoleArrangement']
__all__ = ['DotMeasurement', 'DotRangeMeasurement', 'DotPairMeasurement', 'DotPairRangeMeasurement', 'OscillatingDipole', 'OscillatingDipoleArrangement', 'DotInput', 'DotPairInput']

View File

@ -0,0 +1,58 @@
from dataclasses import dataclass
import numpy
import numpy.typing
@dataclass
class DotPairMeasurement():
'''
Representation of a dot measuring oscillating dipoles.
Parameters
----------
v : float
The voltage measured at the dot.
r1 : numpy.ndarray
The position of the first dot.
r2 : numpy.ndarray
The position of the second dot.
f : float
The measurement frequency.
'''
v: float
r1: numpy.ndarray
r2: numpy.ndarray
f: float
def __post_init__(self) -> None:
self.r1 = numpy.array(self.r1)
self.r2 = numpy.array(self.r2)
@dataclass
class DotPairRangeMeasurement():
'''
Representation of a dot measuring oscillating dipoles.
Parameters
----------
v_low : float
The lower range of voltage measured at the dot.
v_high : float
The upper range of voltage measured at the dot.
r1 : numpy.ndarray
The position of the first dot.
r2 : numpy.ndarray
The position of the second dot.
f : float
The measurement frequency.
'''
v_low: float
v_high: float
r1: numpy.ndarray
r2: numpy.ndarray
f: float
def __post_init__(self) -> None:
self.r1 = numpy.array(self.r1)
self.r2 = numpy.array(self.r2)

View File

@ -0,0 +1,22 @@
import numpy.typing
from typing import Tuple, Sequence, Union
from pdme.measurement.dot_measure import DotRangeMeasurement
from pdme.measurement.dot_pair_measure import DotPairRangeMeasurement
DotInput = Tuple[numpy.typing.ArrayLike, float]
DotPairInput = Tuple[numpy.typing.ArrayLike, numpy.typing.ArrayLike, float]
def dot_inputs_to_array(dot_inputs: Sequence[DotInput]) -> numpy.ndarray:
return numpy.array([numpy.append(numpy.array(input[0]), input[1]) for input in dot_inputs])
def dot_pair_inputs_to_array(pair_inputs: Sequence[DotPairInput]) -> numpy.ndarray:
return numpy.array([[numpy.append(numpy.array(input[0]), input[2]), numpy.append(numpy.array(input[1]), input[2])] for input in pair_inputs])
def dot_range_measurements_low_high_arrays(dot_range_measurements: Union[Sequence[DotRangeMeasurement], Sequence[DotPairRangeMeasurement]]) -> Tuple[numpy.ndarray, numpy.ndarray]:
lows = [measurement.v_low for measurement in dot_range_measurements]
highs = [measurement.v_high for measurement in dot_range_measurements]
return (numpy.array(lows), numpy.array(highs))

View File

@ -1,11 +1,10 @@
from dataclasses import dataclass
import numpy
import numpy.typing
from typing import Sequence, List, Tuple
from typing import Sequence, List
from pdme.measurement.dot_measure import DotMeasurement, DotRangeMeasurement
DotInput = Tuple[numpy.typing.ArrayLike, float]
from pdme.measurement.dot_pair_measure import DotPairMeasurement, DotPairRangeMeasurement
from pdme.measurement.input_types import DotInput, DotPairInput
@dataclass
@ -53,15 +52,8 @@ class OscillatingDipole():
def _b(self, f: float) -> float:
return (1 / numpy.pi) * (self.w / (f**2 + self.w**2))
def dot_inputs_to_array(dot_inputs: Sequence[DotInput]) -> numpy.ndarray:
return numpy.array([numpy.append(numpy.array(input[0]), input[1]) for input in dot_inputs])
def dot_range_measurements_low_high_arrays(dot_range_measurements: Sequence[DotRangeMeasurement]) -> Tuple[numpy.ndarray, numpy.ndarray]:
lows = [measurement.v_low for measurement in dot_range_measurements]
highs = [measurement.v_high for measurement in dot_range_measurements]
return (numpy.array(lows), numpy.array(highs))
def s_for_dot_pair(self, r1: numpy.ndarray, r2: numpy.ndarray, f: float) -> float:
return self._alpha(r1) * self._alpha(r2) * self._b(f)
class OscillatingDipoleArrangement():
@ -80,12 +72,24 @@ class OscillatingDipoleArrangement():
f = dot_input[1]
return DotMeasurement(sum([dipole.s_at_position(r, f) for dipole in self.dipoles]), r, f)
def get_dot_pair_measurement(self, dot_pair_input: DotPairInput) -> DotPairMeasurement:
r1 = numpy.array(dot_pair_input[0])
r2 = numpy.array(dot_pair_input[1])
f = dot_pair_input[2]
return DotPairMeasurement(sum([dipole.s_for_dot_pair(r1, r2, f) for dipole in self.dipoles]), r1, r2, f)
def get_dot_measurements(self, dot_inputs: Sequence[DotInput]) -> List[DotMeasurement]:
'''
For a series of points, each with three coordinates and a frequency, return a list of the corresponding DotMeasurements.
'''
return [self.get_dot_measurement(dot_input) for dot_input in dot_inputs]
def get_dot_pair_measurements(self, dot_pair_inputs: Sequence[DotPairInput]) -> List[DotPairMeasurement]:
'''
For a series of pairs of points, each with three coordinates and a frequency, return a list of the corresponding DotPairMeasurements.
'''
return [self.get_dot_pair_measurement(dot_pair_input) for dot_pair_input in dot_pair_inputs]
def get_percent_range_dot_measurement(self, dot_input: DotInput, low_percent: float, high_percent: float) -> DotRangeMeasurement:
r = numpy.array(dot_input[0])
f = dot_input[1]
@ -93,6 +97,18 @@ class OscillatingDipoleArrangement():
def get_percent_range_dot_measurements(self, dot_inputs: Sequence[DotInput], low_percent: float, high_percent: float) -> List[DotRangeMeasurement]:
'''
For a series of points, each with three coordinates and a frequency, and also a lower error range and upper error range, return a list of the corresponding DotRangeMeasurements.
For a series of pairs of points, each with three coordinates and a frequency, and also a lower error range and upper error range, return a list of the corresponding DotPairRangeMeasurements.
'''
return [self.get_percent_range_dot_measurement(dot_input, low_percent, high_percent) for dot_input in dot_inputs]
def get_percent_range_dot_pair_measurement(self, pair_input: DotPairInput, low_percent: float, high_percent: float) -> DotPairRangeMeasurement:
r1 = numpy.array(pair_input[0])
r2 = numpy.array(pair_input[1])
f = pair_input[2]
return DotPairRangeMeasurement(low_percent * sum([dipole.s_for_dot_pair(r1, r2, f) for dipole in self.dipoles]), high_percent * sum([dipole.s_for_dot_pair(r1, r2, f) for dipole in self.dipoles]), r1, r2, f)
def get_percent_range_dot_pair_measurements(self, pair_inputs: Sequence[DotPairInput], low_percent: float, high_percent: float) -> List[DotPairRangeMeasurement]:
'''
For a series of pairs of points, each with three coordinates and a frequency, and also a lower error range and upper error range, return a list of the corresponding DotPairRangeMeasurements.
'''
return [self.get_percent_range_dot_pair_measurement(pair_input, low_percent, high_percent) for pair_input in pair_inputs]

View File

@ -0,0 +1,31 @@
import pdme.inputs
def test_inputs_with_frequency_range():
dot1 = [1, 2, 3]
dot2 = [2, 4, 6]
frequencies = [5, 7, 9]
expected = [
([1, 2, 3], 5), ([1, 2, 3], 7), ([1, 2, 3], 9), ([2, 4, 6], 7), ([2, 4, 6], 9), ([2, 4, 6], 5)
]
actual = pdme.inputs.inputs_with_frequency_range([dot1, dot2], frequencies)
assert sorted(actual) == sorted(expected), "Did not actually match dot inputs!"
def test_input_pairs_with_frequency_range():
dot1 = [1, 2, 3]
dot2 = [2, 4, 6]
frequencies = [5, 7, 9]
expected = [
([1, 2, 3], [2, 4, 6], 5), ([1, 2, 3], [2, 4, 6], 7), ([1, 2, 3], [2, 4, 6], 9)
]
actual = pdme.inputs.input_pairs_with_frequency_range([dot1, dot2], frequencies)
assert sorted(actual) == sorted(expected), "Did not actually match dot inputs!"

View File

@ -22,6 +22,34 @@ def test_static_dipole():
numpy.testing.assert_allclose(measurement.v, expected_v1 + expected_v2, err_msg="Voltage at dot isn't as expected.")
def test_dipole_dot_pair():
d1 = pdme.measurement.OscillatingDipole((1, 2, 3), (4, 5, 6), 7)
dipoles = pdme.measurement.OscillatingDipoleArrangement([d1])
dot_position1 = (-1, -1, -1)
dot_position2 = (1, 2, 3)
dot_frequency = 8
expected_sij = 0.000083328037100902801698
numpy.testing.assert_allclose(d1.s_for_dot_pair(dot_position1, dot_position2, dot_frequency), expected_sij, err_msg="Sij for dot pair isn't as expected.")
numpy.testing.assert_allclose([m.v for m in dipoles.get_dot_pair_measurements([(dot_position1, dot_position2, dot_frequency)])], [expected_sij], err_msg="Sij for dot pair isn't as expected via dipole.")
def test_range_pairs():
d1 = pdme.measurement.OscillatingDipole((1, 2, 3), (4, 5, 6), 7)
dipoles = pdme.measurement.OscillatingDipoleArrangement([d1])
dot_position1 = (-1, -1, -1)
dot_position2 = (1, 2, 3)
dot_frequency = 8
expected_sij = 0.000083328037100902801698
actuals = dipoles.get_percent_range_dot_pair_measurements([(dot_position1, dot_position2, dot_frequency)], 0.5, 1.5)
assert len(actuals) == 1, "should have only been one pair"
actual = actuals[0]
numpy.testing.assert_allclose([actual.v_low, actual.v_high], expected_sij * numpy.array([0.5, 1.5]), err_msg="Sij for dot pair isn't as expected via dipole with range.")
def test_range_dipole_measurements():
d1 = pdme.measurement.OscillatingDipole((1, 2, 3), (4, 5, 6), 7)
d2 = pdme.measurement.OscillatingDipole((2, 5, 3), (4, -5, -6), 2)

View File

@ -0,0 +1,45 @@
import numpy
import pdme.measurement.input_types
from pdme.measurement.dot_measure import DotRangeMeasurement
from pdme.measurement.dot_pair_measure import DotPairRangeMeasurement
def test_inputs_to_array():
i1 = ([1, 2, 3], 5)
i2 = ([-1, 4, -2], 9)
actual = pdme.measurement.input_types.dot_inputs_to_array([i1, i2])
expected = numpy.array([[1, 2, 3, 5], [-1, 4, -2, 9]])
numpy.testing.assert_allclose(actual, expected, err_msg="Didn't convert to array properly")
def test_pair_inputs_to_array():
i1 = ([1, 2, 3], [-1, 4, -2], 5)
i2 = ([-1, 4, -2], [6, 7, 8], 9)
actual = pdme.measurement.input_types.dot_pair_inputs_to_array([i1, i2])
expected = numpy.array([
[[1, 2, 3, 5], [-1, 4, -2, 5]],
[[-1, 4, -2, 9], [6, 7, 8, 9]],
])
numpy.testing.assert_allclose(actual, expected, err_msg="Didn't convert to array properly")
def test_ranges_to_array():
m1 = DotRangeMeasurement(1, 2, 100, 1000)
m2 = DotRangeMeasurement(0.5, 3, 100, 1000)
actual_lows, actual_highs = pdme.measurement.input_types.dot_range_measurements_low_high_arrays([m1, m2])
numpy.testing.assert_allclose(actual_lows, [1, 0.5], err_msg="Lows were wrong")
numpy.testing.assert_allclose(actual_highs, [2, 3], err_msg="Highs were wrong")
def test_pair_ranges_to_array():
m1 = DotPairRangeMeasurement(1, 2, 100, 1000, 10000)
m2 = DotPairRangeMeasurement(0.5, 3, 100, 1000, 10000)
actual_lows, actual_highs = pdme.measurement.input_types.dot_range_measurements_low_high_arrays([m1, m2])
numpy.testing.assert_allclose(actual_lows, [1, 0.5], err_msg="Lows were wrong")
numpy.testing.assert_allclose(actual_highs, [2, 3], err_msg="Highs were wrong")