@@ -61,6 +61,68 @@ def test_projected_model():
6161 assert isinstance (projected_model .centre , af .UniformPrior )
6262
6363
64+ def test_projected_model_moments ():
65+ """
66+ Regression test for PyAutoFit#1382: `projected_model` must convert the
67+ samples' linear importance weights to log weights before the message
68+ projection's weighted moment match.
69+
70+ The sample set mimics a nested-sampling run: a broad prior-exploration
71+ phase with negligible weights plus a concentrated posterior with almost
72+ all the weight. The projected prior's moments must match the posterior,
73+ not the prior-phase spread — with linear weights fed in as log weights,
74+ every sample counts almost equally and the projection lands near a
75+ prior bound.
76+ """
77+ rng = np .random .default_rng (1 )
78+
79+ posterior_mean = 2.05
80+ posterior_sigma = 0.03
81+
82+ prior_phase = rng .uniform (1.5 , 3.0 , size = 2000 )
83+ posterior_phase = rng .normal (posterior_mean , posterior_sigma , size = 500 )
84+ values = np .concatenate ([prior_phase , posterior_phase ])
85+
86+ weights = np .concatenate (
87+ [
88+ np .full (prior_phase .size , 1.0e-9 ),
89+ np .full (posterior_phase .size , (1.0 - prior_phase .size * 1.0e-9 ) / 500 ),
90+ ]
91+ )
92+
93+ model = af .Model (
94+ af .ex .Gaussian ,
95+ centre = af .UniformPrior (lower_limit = 1.5 , upper_limit = 3.0 ),
96+ )
97+ # normalization and sigma have UniformPrior(0, 1) under the test config, so
98+ # they get their own in-support draws; the moment assertions are on centre.
99+ unit_values = rng .uniform (0.05 , 0.95 , size = values .size )
100+ samples = af .Samples (
101+ model ,
102+ [
103+ af .Sample (
104+ - 1.0 ,
105+ - 1.0 ,
106+ weight = weight ,
107+ kwargs = {
108+ ("centre" ,): value ,
109+ ("normalization" ,): unit_value ,
110+ ("sigma" ,): unit_value ,
111+ },
112+ )
113+ for value , unit_value , weight in zip (values , unit_values , weights )
114+ ],
115+ )
116+ result = af .mock .MockResult (samples = samples )
117+
118+ projected_centre = result .projected_model .centre
119+
120+ assert projected_centre .mean == pytest .approx (posterior_mean , abs = 0.02 )
121+ assert float (np .sqrt (projected_centre .variance )) == pytest .approx (
122+ posterior_sigma , rel = 0.5
123+ )
124+
125+
64126def test_uniform_normal (x ):
65127 message = TransformedMessage (
66128 UniformNormalMessage ,
0 commit comments