Model solution
This commit is contained in:
parent
5726b1d50a
commit
ad0553ce6e
@ -1,4 +1,5 @@
|
||||
from pathfinder.model.oscillating.oscillating_dipole import OscillatingDipole, OscillatingDipoleArrangement
|
||||
from pathfinder.model.oscillating.dot import DotMeasurement
|
||||
from pathfinder.model.oscillating.model import DotOscillatingDipoleModel
|
||||
|
||||
__all__ = ['DotMeasurement', 'OscillatingDipole', 'OscillatingDipoleArrangement']
|
||||
__all__ = ['DotMeasurement', 'OscillatingDipole', 'OscillatingDipoleArrangement', 'DotOscillatingDipoleModel']
|
||||
|
44
pathfinder/model/oscillating/model.py
Normal file
44
pathfinder/model/oscillating/model.py
Normal file
@ -0,0 +1,44 @@
|
||||
from typing import Callable, Sequence
|
||||
import numpy
|
||||
import scipy.optimize
|
||||
from pathfinder.model.oscillating.dot import DotMeasurement
|
||||
|
||||
|
||||
class DotOscillatingDipoleModel():
|
||||
'''
|
||||
Model of n static oscillating with a collection of voltage measurements
|
||||
at dots at different positions and frequencies.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
dots : Sequence[DotMeasurement]
|
||||
A collection of dots representing a series of measured noise spectrum values.
|
||||
n: int
|
||||
The number of dipoles to assume.
|
||||
'''
|
||||
def __init__(self, dots: Sequence[DotMeasurement], n: int) -> None:
|
||||
self.dots = dots
|
||||
self.m = len(dots)
|
||||
self.n = n
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'DotOscillatingDipoleModel({repr(list(self.dots))}, {self.n})'
|
||||
|
||||
def costs(self) -> Callable[[numpy.ndarray], numpy.ndarray]:
|
||||
def costs_to_return(pt: numpy.ndarray) -> numpy.ndarray:
|
||||
return numpy.array([dot.cost(pt) for dot in self.dots])
|
||||
|
||||
return costs_to_return
|
||||
|
||||
def jac(self) -> Callable[[numpy.ndarray], numpy.ndarray]:
|
||||
def jac_to_return(pts: numpy.ndarray) -> numpy.ndarray:
|
||||
return numpy.array([dot.jac(pts) for dot in self.dots])
|
||||
|
||||
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)
|
||||
return scipy.optimize.least_squares(self.costs(), initial, jac=self.jac(), ftol=1e-15, gtol=3e-16)
|
35
tests/model/oscillating/test_oscmodel.py
Normal file
35
tests/model/oscillating/test_oscmodel.py
Normal file
@ -0,0 +1,35 @@
|
||||
import numpy
|
||||
import pathfinder.model.oscillating as model
|
||||
|
||||
|
||||
def test_dotdipolemodel_repr():
|
||||
mod = model.DotOscillatingDipoleModel((), 1)
|
||||
assert repr(mod) == "DotOscillatingDipoleModel([], 1)"
|
||||
|
||||
|
||||
def test_dotdipolemodel_m():
|
||||
mod = model.DotOscillatingDipoleModel([model.DotMeasurement(1, (-1, -1, -1), 11), model.DotMeasurement(2, (0, 0, 0), 3)], 1)
|
||||
assert mod.m == 2
|
||||
|
||||
|
||||
def test_dotdipolemodel_cost():
|
||||
mod = model.DotOscillatingDipoleModel([model.DotMeasurement(.05, (-1, -1, -1), 11), model.DotMeasurement(.002, (0, 0, 0), 3)], 1)
|
||||
costs = mod.costs()
|
||||
jac = mod.jac()
|
||||
|
||||
pt_to_test = numpy.array((1, 2, 3, 4, 5, 6, 7))
|
||||
expected_cost = [-0.04998578036712978, -0.00191383161468913]
|
||||
expected_jacobian = [
|
||||
[
|
||||
3.742008650059147e-6, 4.4904103800709765e-6, 5.238812110082806e-6,
|
||||
-3.12967996186765e-6, -3.1568945702317167e-6, -3.184109178595783e-6,
|
||||
8.603475350051953e-7
|
||||
], [
|
||||
0.000021542096327717702, 0.000026927620409647127, 0.000032313144491576555,
|
||||
-0.000021472154456523818, -0.0000228010500092077, -0.000024129945561891588,
|
||||
-8.489496089740964e-6
|
||||
]
|
||||
]
|
||||
|
||||
numpy.testing.assert_allclose(costs(pt_to_test), expected_cost, err_msg="Costs aren't as expected.")
|
||||
numpy.testing.assert_allclose(jac(pt_to_test), expected_jacobian, err_msg="Jacobian aren't as expected.")
|
Reference in New Issue
Block a user