Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
bff1343
log_prior_from_value in TruncatedNormalMessae
Nov 30, 2025
be2dbd0
log_prior_from_value in UniformPrior
Nov 30, 2025
a00bcff
remaining def log_prior_from_value
Nov 30, 2025
4874c65
fix xp pass
Nov 30, 2025
0629f55
Put xp code throughout messages
Nov 30, 2025
15d0878
lots of hjorrible hacks
Nov 30, 2025
601c5f1
GaussianPrior works
Nov 30, 2025
e5dda22
various message funcitons now use xp
Nov 30, 2025
6f28bba
integration tests work, cleaning up unit tests
Nov 30, 2025
c620830
hacks which push us most of the way through
Nov 30, 2025
6c78390
fix removing dodgy hacks
Nov 30, 2025
0bbb3df
use_jax made private
Nov 30, 2025
2cb4a04
include prior factors made private
Nov 30, 2025
fb9d8b9
fix issues with _use_jax now being private
Nov 30, 2025
ee14b5b
remove print statements
Nov 30, 2025
316c884
fixs png maker
Dec 2, 2025
58a7473
fix unit test
Dec 2, 2025
3ce01f4
fixes to figure of merit
Dec 9, 2025
193fec7
Merge pull request #1166 from rhayes777/feature/fix_figure_of_merit
Jammy2211 Dec 10, 2025
7313572
minor fixes
Dec 12, 2025
cecb125
'Updated version in __init__ to 2025.12.15.1
rhayes777 Dec 15, 2025
dabaa2a
'Updated version in __init__ to 2025.12.15.2
rhayes777 Dec 15, 2025
2e417c2
print staement works
Dec 16, 2025
322e341
specific message about CPU use if 0 VRAM
Dec 16, 2025
9c9f930
message for use_jax=False case
Dec 16, 2025
f66fce7
Merge branch 'main_build' of github.com:rhayes777/PyAutoFit into main…
Dec 16, 2025
a7fffaf
more tests
Dec 16, 2025
98452bc
'Updated version in __init__ to 2025.12.21.1
rhayes777 Dec 21, 2025
d0d03ba
'Updated version in __init__ to 2026.1.21.3
rhayes777 Jan 21, 2026
1ae3a9c
tested use of samples summary
Jan 28, 2026
79e284c
Merge pull request #1168 from rhayes777/feature/samples_summary_failsafe
Jammy2211 Jan 28, 2026
fda58cf
CPU JAX uses batch size 1
Jan 30, 2026
074b97b
update xp uses in fitness
Jan 30, 2026
49ad425
Merge pull request #1169 from rhayes777/feature/jax_cpu_batch_size_1
Jammy2211 Jan 30, 2026
6cedcfc
disable vmap for CPU
Jan 30, 2026
a51ba48
Update autofit/non_linear/search/nest/nautilus/search.py
Jammy2211 Jan 30, 2026
21fb4ab
Merge pull request #1170 from rhayes777/feature/jax_cpu_jit
Jammy2211 Jan 30, 2026
7a254da
use_vmap_jax now manually input
Jan 30, 2026
ddad828
use analysis_xp in fitness
Feb 18, 2026
a39b5a9
add expanded unit tests for model mapping API
Apr 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion autofit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,4 @@ def save_abc(pickler, obj):
pickle._Pickler.save_type(pickler, obj)


__version__ = "2025.11.5.1"
__version__ = "2026.1.21.3"
2 changes: 1 addition & 1 deletion autofit/aggregator/search_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def instance(self):
try:
return self.samples.max_log_likelihood()
except (AttributeError, NotImplementedError):
return None
return self.samples_summary.instance

@property
def id(self) -> str:
Expand Down
30 changes: 22 additions & 8 deletions autofit/aggregator/summary/aggregate_csv/column.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,34 @@ def value(self, row: "Row"):
result = {}

if ValueType.Median in self.value_types:
result[""] = row.median_pdf_sample_kwargs[self.path]
try:
result[""] = row.median_pdf_sample_kwargs[self.path]
except KeyError:
result[""] = None

if ValueType.MaxLogLikelihood in self.value_types:
result["max_lh"] = row.max_likelihood_kwargs[self.path]
try:
result["max_lh"] = row.max_likelihood_kwargs[self.path]
except KeyError:
result["max_lh"] = None

if ValueType.ValuesAt1Sigma in self.value_types:
lower, upper = row.values_at_sigma_1_kwargs[self.path]
result["lower_1_sigma"] = lower
result["upper_1_sigma"] = upper
try:
lower, upper = row.values_at_sigma_1_kwargs[self.path]
result["lower_1_sigma"] = lower
result["upper_1_sigma"] = upper
except KeyError:
result["lower_1_sigma"] = None
result["upper_1_sigma"] = None

if ValueType.ValuesAt3Sigma in self.value_types:
lower, upper = row.values_at_sigma_3_kwargs[self.path]
result["lower_3_sigma"] = lower
result["upper_3_sigma"] = upper
try:
lower, upper = row.values_at_sigma_3_kwargs[self.path]
result["lower_3_sigma"] = lower
result["upper_3_sigma"] = upper
except KeyError:
result["lower_3_sigma"] = None
result["upper_3_sigma"] = None

return result

Expand Down
30 changes: 5 additions & 25 deletions autofit/aggregator/summary/aggregate_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,11 @@ def subplot_filename(subplot: Enum) -> str:
)


class SubplotFit(Enum):
"""
The subplots that can be extracted from the subplot_fit image.

The values correspond to the position of the subplot in the 4x3 grid.
"""

Data = (0, 0)
DataSourceScaled = (1, 0)
SignalToNoiseMap = (2, 0)
ModelData = (3, 0)
LensLightModelData = (0, 1)
LensLightSubtractedImage = (1, 1)
SourceModelData = (2, 1)
SourcePlaneZoomed = (3, 1)
NormalizedResidualMap = (0, 2)
NormalizedResidualMapOneSigma = (1, 2)
ChiSquaredMap = (2, 2)
SourcePlaneNoZoom = (3, 2)


class SubplotFitImage:
def __init__(
self,
image: Image.Image,
suplot_type: Type[SubplotFit] = SubplotFit,
suplot_type,
):
"""
The subplot_fit image associated with one fit.
Expand Down Expand Up @@ -173,7 +152,7 @@ def output_to_folder(
self,
folder: Path,
name: Union[str, List[str]],
subplots: List[Union[SubplotFit, List[Image.Image], Callable]],
subplots: List[Union[List[Image.Image], Callable]],
subplot_width: Optional[int] = sys.maxsize,
):
"""
Expand Down Expand Up @@ -226,7 +205,7 @@ def output_to_folder(
def _matrix_for_result(
i: int,
result: SearchOutput,
subplots: List[Union[SubplotFit, List[Image.Image], Callable]],
subplots: List[Union[List[Image.Image], Callable]],
subplot_width: int = sys.maxsize,
) -> List[List[Image.Image]]:
"""
Expand Down Expand Up @@ -272,7 +251,8 @@ class name but using snake_case.
_images[subplot_type] = SubplotFitImage(
result.image(
subplot_filename(subplot_),
)
),
subplot_type
)
return _images[subplot_type]

Expand Down
6 changes: 3 additions & 3 deletions autofit/graphical/declarative/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class AbstractDeclarativeFactor(Analysis, ABC):
_plates: Tuple[Plate, ...] = ()

def __init__(self, include_prior_factors=False, use_jax : bool = False):
self.include_prior_factors = include_prior_factors
self._include_prior_factors = include_prior_factors

super().__init__(use_jax=use_jax)

Expand Down Expand Up @@ -63,7 +63,7 @@ def prior_counts(self) -> List[Tuple[Prior, int]]:
for prior in factor.prior_model.priors:
counter[prior] += 1
return [
(prior, count + 1 if self.include_prior_factors else count)
(prior, count + 1 if self._include_prior_factors else count)
for prior, count in counter.items()
]

Expand Down Expand Up @@ -96,7 +96,7 @@ def graph(self) -> DeclarativeFactorGraph:
The complete graph made by combining all factors and priors
"""
factors = [model for model in self.model_factors]
if self.include_prior_factors:
if self._include_prior_factors:
factors += self.prior_factors
# noinspection PyTypeChecker
return DeclarativeFactorGraph(factors)
Expand Down
2 changes: 1 addition & 1 deletion autofit/graphical/declarative/collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def __init__(
def tree_flatten(self):
return (
(self._model_factors,),
(self._name, self.include_prior_factors),
(self._name, self._include_prior_factors),
)

@classmethod
Expand Down
2 changes: 1 addition & 1 deletion autofit/graphical/declarative/factor/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def __init__(
factor, **prior_variable_dict,
name=name or namer(self.__class__.__name__),
)
self.include_prior_factors = include_prior_factors
self._include_prior_factors = include_prior_factors

@property
def info(self) -> str:
Expand Down
9 changes: 6 additions & 3 deletions autofit/graphical/declarative/factor/hierarchical.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from autofit.messages import NormalMessage
from autofit.non_linear.paths.abstract import AbstractPaths
from autofit.tools.namer import namer

from .abstract import AbstractModelFactor


Expand All @@ -19,6 +20,7 @@ def __init__(
distribution: Type[Prior],
optimiser=None,
name: Optional[str] = None,
use_jax : bool = False,
**kwargs,
):
"""
Expand Down Expand Up @@ -70,6 +72,7 @@ def __init__(
self._name = name or namer(self.__class__.__name__)
self._factors = list()
self.optimiser = optimiser
self._use_jax = use_jax

@property
def name(self):
Expand Down Expand Up @@ -144,7 +147,7 @@ def __call__(self, **kwargs):

class _HierarchicalFactor(AbstractModelFactor):
def __init__(
self, distribution_model: HierarchicalFactor, drawn_prior: Prior, use_jax : bool = False
self, distribution_model: HierarchicalFactor, drawn_prior: Prior,
):
"""
A factor that links a variable to a parameterised distribution.
Expand All @@ -159,7 +162,7 @@ def __init__(
"""
self.distribution_model = distribution_model
self.drawn_prior = drawn_prior
self.use_jax = use_jax
self._use_jax = distribution_model._use_jax

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

Expand Down Expand Up @@ -188,7 +191,7 @@ def variable(self):
return self.drawn_prior

def log_likelihood_function(self, instance):
return instance.distribution_model.message(instance.drawn_prior)
return instance.distribution_model.message(instance.drawn_prior, xp=self._xp)

@property
def priors(self) -> Set[Prior]:
Expand Down
5 changes: 4 additions & 1 deletion autofit/mapper/prior/arithmetic/assertion.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from abc import ABC
import numpy as np
from typing import Optional, Dict

from autofit.mapper.prior.arithmetic.compound import CompoundPrior, Compound
Expand All @@ -24,7 +25,7 @@ def __le__(self, other):


class GreaterThanLessThanAssertion(ComparisonAssertion):
def _instance_for_arguments(self, arguments, ignore_assertions=False):
def _instance_for_arguments(self, arguments, ignore_assertions=False, xp=np):
"""
Assert that the value in the dictionary associated with the lower
prior is lower than the value associated with the greater prior.
Expand Down Expand Up @@ -55,6 +56,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
"""
Assert that the value in the dictionary associated with the lower
Expand Down Expand Up @@ -90,6 +92,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
return self.assertion_1.instance_for_arguments(
arguments,
Expand Down
10 changes: 10 additions & 0 deletions autofit/mapper/prior/arithmetic/compound.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
return self.left_for_arguments(
arguments,
Expand All @@ -237,6 +238,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
return self.left_for_arguments(
arguments,
Expand All @@ -256,6 +258,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
return self.left_for_arguments(
arguments,
Expand All @@ -275,6 +278,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
return self.left_for_arguments(
arguments,
Expand All @@ -294,6 +298,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
return self.left_for_arguments(
arguments,
Expand All @@ -313,6 +318,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
return self.left_for_arguments(
arguments,
Expand Down Expand Up @@ -396,6 +402,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
return -self.prior.instance_for_arguments(
arguments,
Expand All @@ -412,6 +419,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
return abs(
self.prior.instance_for_arguments(
Expand All @@ -430,6 +438,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
return np.log(
self.prior.instance_for_arguments(
Expand All @@ -448,6 +457,7 @@ def _instance_for_arguments(
self,
arguments,
ignore_assertions=False,
xp=np,
):
return np.log10(
self.prior.instance_for_arguments(
Expand Down
2 changes: 2 additions & 0 deletions autofit/mapper/prior/gaussian.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import numpy as np
from typing import Optional

from autofit.messages.normal import NormalMessage
Expand Down Expand Up @@ -46,6 +47,7 @@ def __init__(
>>> prior = GaussianPrior(mean=1.0, sigma=2.0)
>>> physical_value = prior.value_for(unit=0.5) # Returns ~1.0 (mean)
"""

super().__init__(
message=NormalMessage(
mean=mean,
Expand Down
2 changes: 1 addition & 1 deletion autofit/mapper/prior/log_gaussian.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def value_for(self, unit: float) -> float:
def parameter_string(self) -> str:
return f"mean = {self.mean}, sigma = {self.sigma}"

def log_prior_from_value(self, value):
def log_prior_from_value(self, value, xp=np):
if value <= 0:
return float("-inf")

Expand Down
2 changes: 1 addition & 1 deletion autofit/mapper/prior/log_uniform.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def with_limits(cls, lower_limit: float, upper_limit: float) -> "LogUniformPrior

__identifier_fields__ = ("lower_limit", "upper_limit")

def log_prior_from_value(self, value) -> float:
def log_prior_from_value(self, value, xp=np) -> float:
"""
Returns the log prior of a physical value, so the log likelihood of a model evaluation can be converted to a
posterior as log_prior + log_likelihood.
Expand Down
3 changes: 2 additions & 1 deletion autofit/mapper/prior/uniform.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import numpy as np
from typing import Optional, Tuple

from autofit.messages.normal import UniformNormalMessage
Expand Down Expand Up @@ -128,7 +129,7 @@ def value_for(self, unit: float) -> float:
round(super().value_for(unit), 14)
)

def log_prior_from_value(self, value):
def log_prior_from_value(self, value, xp=np):
"""
Returns the log prior of a physical value, so the log likelihood of a model evaluation can be converted to a
posterior as log_prior + log_likelihood.
Expand Down
Loading
Loading