Skip to content

Commit c744db2

Browse files
authored
Merge pull request #1161 from rhayes777/feature/xp_no_autofit_import
Feature/xp no autofit import
2 parents 3328335 + df81d94 commit c744db2

42 files changed

Lines changed: 289 additions & 278 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

autofit/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from autoconf import jax_wrapper
12
from autoconf.dictable import register_parser
23
from . import conf
34

autofit/config/general.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
jax:
2-
use_jax: false # If True, PyAutoFit uses JAX internally, whereas False uses normal Numpy.
31
updates:
42
iterations_per_quick_update: 1e99 # Non-linear search iterations between every quick update, which just displays the maximum likelihood model fit.
53
iterations_per_full_update: 1e99 # Non-linear search iterations between every full update, which outputs all visuals and result fits (e.g. model.result, search.summary), this exits the search and can be slow.

autofit/example/analysis.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import numpy as np
22
from typing import Dict, Optional
33

4-
from autoconf.jax_wrapper import numpy as xp
5-
64
import autofit as af
75

86
from autofit.example.result import ResultExample
@@ -38,7 +36,7 @@ class Analysis(af.Analysis):
3836

3937
LATENT_KEYS = ["gaussian.fwhm"]
4038

41-
def __init__(self, data: np.ndarray, noise_map: np.ndarray):
39+
def __init__(self, data: np.ndarray, noise_map: np.ndarray, use_jax=False):
4240
"""
4341
In this example the `Analysis` object only contains the data and noise-map. It can be easily extended,
4442
for more complex data-sets and model fitting problems.
@@ -51,12 +49,12 @@ def __init__(self, data: np.ndarray, noise_map: np.ndarray):
5149
A 1D numpy array containing the noise values of the data, used for computing the goodness of fit
5250
metric.
5351
"""
54-
super().__init__()
52+
super().__init__(use_jax=use_jax)
5553

5654
self.data = data
5755
self.noise_map = noise_map
5856

59-
def log_likelihood_function(self, instance: af.ModelInstance) -> float:
57+
def log_likelihood_function(self, instance: af.ModelInstance, xp=np) -> float:
6058
"""
6159
Determine the log likelihood of a fit of multiple profiles to the dataset.
6260
@@ -98,14 +96,15 @@ def model_data_1d_from(self, instance: af.ModelInstance) -> np.ndarray:
9896
The model data of the profiles.
9997
"""
10098

101-
xvalues = xp.arange(self.data.shape[0])
102-
model_data_1d = xp.zeros(self.data.shape[0])
99+
xvalues = self._xp.arange(self.data.shape[0])
100+
model_data_1d = self._xp.zeros(self.data.shape[0])
103101

104102
try:
105103
for profile in instance:
106104
try:
107105
model_data_1d += profile.model_data_from(
108-
xvalues=xvalues
106+
xvalues=xvalues,
107+
xp=self._xp
109108
)
110109
except AttributeError:
111110
pass

autofit/example/model.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
import numpy as np
33
from typing import Tuple
44

5-
from autoconf.jax_wrapper import numpy as xp
6-
75
"""
86
The `Gaussian` class in this module is the model components that is fitted to data using a non-linear search. The
97
inputs of its __init__ constructor are the parameters which can be fitted for.
@@ -47,7 +45,7 @@ def fwhm(self) -> float:
4745
the free parameters of the model which we are interested and may want to store the full samples information
4846
on (e.g. to create posteriors).
4947
"""
50-
return 2 * xp.sqrt(2 * xp.log(2)) * self.sigma
48+
return 2 * np.sqrt(2 * np.log(2)) * self.sigma
5149

5250
def _tree_flatten(self):
5351
return (self.centre, self.normalization, self.sigma), None
@@ -64,7 +62,7 @@ def __eq__(self, other):
6462
and self.sigma == other.sigma
6563
)
6664

67-
def model_data_from(self, xvalues: np.ndarray) -> np.ndarray:
65+
def model_data_from(self, xvalues: np.ndarray, xp=np) -> np.ndarray:
6866
"""
6967
Calculate the normalization of the profile on a 1D grid of Cartesian x coordinates.
7068
@@ -82,7 +80,7 @@ def model_data_from(self, xvalues: np.ndarray) -> np.ndarray:
8280
xp.exp(-0.5 * xp.square(xp.divide(transformed_xvalues, self.sigma))),
8381
)
8482

85-
def f(self, x: float):
83+
def f(self, x: float, xp=np):
8684
return (
8785
self.normalization
8886
/ (self.sigma * xp.sqrt(2 * math.pi))
@@ -137,7 +135,7 @@ def __init__(
137135
self.normalization = normalization
138136
self.rate = rate
139137

140-
def model_data_from(self, xvalues: np.ndarray) -> np.ndarray:
138+
def model_data_from(self, xvalues: np.ndarray, xp=np) -> np.ndarray:
141139
"""
142140
Calculate the 1D Gaussian profile on a 1D grid of Cartesian x coordinates.
143141

autofit/graphical/declarative/abstract.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ class AbstractDeclarativeFactor(Analysis, ABC):
1919
optimiser: AbstractFactorOptimiser
2020
_plates: Tuple[Plate, ...] = ()
2121

22-
def __init__(self, include_prior_factors=False):
22+
def __init__(self, include_prior_factors=False, use_jax : bool = False):
2323
self.include_prior_factors = include_prior_factors
2424

25+
super().__init__(use_jax=use_jax)
26+
2527
@property
2628
@abstractmethod
2729
def name(self):

autofit/graphical/declarative/collection.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,15 @@
1111
from autofit.mapper.model import ModelInstance
1212
from autofit.mapper.prior_model.prior_model import Model
1313

14-
from autoconf.jax_wrapper import register_pytree_node_class
1514
from ...non_linear.combined_result import CombinedResult
1615

17-
18-
@register_pytree_node_class
1916
class FactorGraphModel(AbstractDeclarativeFactor):
2017
def __init__(
2118
self,
2219
*model_factors: Union[AbstractDeclarativeFactor, HierarchicalFactor],
2320
name=None,
2421
include_prior_factors=True,
22+
use_jax : bool = False
2523
):
2624
"""
2725
A collection of factors that describe models, which can be
@@ -36,6 +34,7 @@ def __init__(
3634
"""
3735
super().__init__(
3836
include_prior_factors=include_prior_factors,
37+
use_jax=use_jax,
3938
)
4039
self._model_factors = list(model_factors)
4140
self._name = name or namer(self.__class__.__name__)

autofit/graphical/declarative/factor/analysis.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
from autofit.non_linear.paths.abstract import AbstractPaths
1111
from .abstract import AbstractModelFactor
1212

13-
from autoconf.jax_wrapper import register_pytree_node_class
14-
1513

1614
class FactorCallable:
1715
def __init__(
@@ -45,8 +43,6 @@ def __call__(self, **kwargs: np.ndarray) -> float:
4543
instance = self.prior_model.instance_for_arguments(arguments)
4644
return self.analysis.log_likelihood_function(instance)
4745

48-
49-
@register_pytree_node_class
5046
class AnalysisFactor(AbstractModelFactor):
5147
@property
5248
def prior_model(self):

autofit/graphical/declarative/factor/hierarchical.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ def __call__(self, **kwargs):
144144

145145
class _HierarchicalFactor(AbstractModelFactor):
146146
def __init__(
147-
self, distribution_model: HierarchicalFactor, drawn_prior: Prior,
147+
self, distribution_model: HierarchicalFactor, drawn_prior: Prior, use_jax : bool = False
148148
):
149149
"""
150150
A factor that links a variable to a parameterised distribution.
@@ -159,6 +159,7 @@ def __init__(
159159
"""
160160
self.distribution_model = distribution_model
161161
self.drawn_prior = drawn_prior
162+
self.use_jax = use_jax
162163

163164
prior_variable_dict = {prior.name: prior for prior in distribution_model.priors}
164165

autofit/graphical/factor_graphs/factor.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from copy import deepcopy
22
from inspect import getfullargspec
3-
import jax
43
from typing import Tuple, Dict, Any, Callable, Union, List, Optional, TYPE_CHECKING
54

65
import numpy as np
@@ -285,6 +284,8 @@ def _set_jacobians(
285284
numerical_jacobian=True,
286285
jacfwd=True,
287286
):
287+
import jax
288+
288289
self._vjp = vjp
289290
self._jacfwd = jacfwd
290291
if vjp or factor_vjp:
@@ -327,6 +328,7 @@ def __call__(self, values: VariableData) -> FactorValue:
327328
return self._cache[key]
328329

329330
def _jax_factor_vjp(self, *args) -> Tuple[Any, Callable]:
331+
import jax
330332
return jax.vjp(self._factor, *args)
331333

332334
_factor_vjp = _jax_factor_vjp

autofit/graphical/laplace/newton.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ def take_quasi_newton_step(
240240
) -> Tuple[Optional[float], OptimisationState]:
241241
""" """
242242
state.search_direction = search_direction(state, **(search_direction_kws or {}))
243-
if state.search_direction.vecnorm(np.Inf) == 0:
243+
if state.search_direction.vecnorm(np.inf) == 0:
244244
# if gradient is zero then at maximum already
245245
return 0.0, state
246246

0 commit comments

Comments
 (0)