11
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
# See the License for the specific language governing permissions and
13
13
# limitations under the License.
14
+
14
15
import numpy as np
15
16
16
17
from pytensor .tensor .random import normal
@@ -171,15 +172,15 @@ def setup_class(self):
171
172
r"$\text{mu} \sim \operatorname{Deterministic}(f(\text{beta},~\text{alpha}))$" ,
172
173
r"$\text{beta} \sim \operatorname{Normal}(0,~10)$" ,
173
174
r"$\text{Z} \sim \operatorname{MultivariateNormal}(f(),~f())$" ,
174
- r"$\text{nb_with_p_n } \sim \operatorname{NegativeBinomial}(10,~\text{nbp})$" ,
175
+ r"$\text{nb\_with\_p\_n } \sim \operatorname{NegativeBinomial}(10,~\text{nbp})$" ,
175
176
r"$\text{zip} \sim \operatorname{MarginalMixture}(f(),~\operatorname{DiracDelta}(0),~\operatorname{Poisson}(5))$" ,
176
177
r"$\text{w} \sim \operatorname{Dirichlet}(\text{<constant>})$" ,
177
178
(
178
- r"$\text{nested_mix } \sim \operatorname{MarginalMixture}(\text{w},"
179
+ r"$\text{nested\_mix } \sim \operatorname{MarginalMixture}(\text{w},"
179
180
r"~\operatorname{MarginalMixture}(f(),~\operatorname{DiracDelta}(0),~\operatorname{Poisson}(5)),"
180
181
r"~\operatorname{Censored}(\operatorname{Bernoulli}(0.5),~-1,~1))$"
181
182
),
182
- r"$\text{Y_obs } \sim \operatorname{Normal}(\text{mu},~\text{sigma})$" ,
183
+ r"$\text{Y\_obs } \sim \operatorname{Normal}(\text{mu},~\text{sigma})$" ,
183
184
r"$\text{pot} \sim \operatorname{Potential}(f(\text{beta},~\text{alpha}))$" ,
184
185
r"$\text{pred} \sim \operatorname{Deterministic}(f(\text{<normal>}))" ,
185
186
],
@@ -189,11 +190,11 @@ def setup_class(self):
189
190
r"$\text{mu} \sim \operatorname{Deterministic}$" ,
190
191
r"$\text{beta} \sim \operatorname{Normal}$" ,
191
192
r"$\text{Z} \sim \operatorname{MultivariateNormal}$" ,
192
- r"$\text{nb_with_p_n } \sim \operatorname{NegativeBinomial}$" ,
193
+ r"$\text{nb\_with\_p\_n } \sim \operatorname{NegativeBinomial}$" ,
193
194
r"$\text{zip} \sim \operatorname{MarginalMixture}$" ,
194
195
r"$\text{w} \sim \operatorname{Dirichlet}$" ,
195
- r"$\text{nested_mix } \sim \operatorname{MarginalMixture}$" ,
196
- r"$\text{Y_obs } \sim \operatorname{Normal}$" ,
196
+ r"$\text{nested\_mix } \sim \operatorname{MarginalMixture}$" ,
197
+ r"$\text{Y\_obs } \sim \operatorname{Normal}$" ,
197
198
r"$\text{pot} \sim \operatorname{Potential}$" ,
198
199
r"$\text{pred} \sim \operatorname{Deterministic}" ,
199
200
],
@@ -256,7 +257,7 @@ def test_model_latex_repr_three_levels_model():
256
257
"$$" ,
257
258
"\\ begin{array}{rcl}" ,
258
259
"\\ text{mu} &\\ sim & \\ operatorname{Normal}(0,~5)\\ \\ \\ text{sigma} &\\ sim & "
259
- "\\ operatorname{HalfCauchy}(0,~2.5)\\ \\ \\ text{censored_normal } &\\ sim & "
260
+ "\\ operatorname{HalfCauchy}(0,~2.5)\\ \\ \\ text{censored \\ _normal } &\\ sim & "
260
261
"\\ operatorname{Censored}(\\ operatorname{Normal}(\\ text{mu},~\\ text{sigma}),~-2,~2)" ,
261
262
"\\ end{array}" ,
262
263
"$$" ,
@@ -316,3 +317,22 @@ def random(rng, mu, size):
316
317
317
318
str_repr = model .str_repr (include_params = False )
318
319
assert str_repr == "\n " .join (["x ~ CustomDistNormal" , "y ~ CustomRandomNormal" ])
320
+
321
+
322
+ class TestLatexRepr :
323
+ @staticmethod
324
+ def simple_model () -> Model :
325
+ with Model () as simple_model :
326
+ error = HalfNormal ("error" , 0.5 )
327
+ alpha_a = Normal ("alpha_a" , 0 , 1 )
328
+ Normal ("y" , alpha_a , error )
329
+ return simple_model
330
+
331
+ def test_latex_escaped_underscore (self ):
332
+ """
333
+ Ensures that all underscores in model variable names are properly escaped for LaTeX representation
334
+ """
335
+ model = self .simple_model ()
336
+ model_str = model .str_repr (formatting = "latex" )
337
+ assert "\\ _" in model_str
338
+ assert "_" not in model_str .replace ("\\ _" , "" )
0 commit comments