Skip to content

Commit 5d7e99a

Browse files
Run the pre-commit
1 parent 3fe3550 commit 5d7e99a

File tree

2 files changed

+36
-52
lines changed

2 files changed

+36
-52
lines changed

pymc/distributions/multivariate.py

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2158,7 +2158,7 @@ def make_node(self, rng, size, mu, W, alpha, tau, W_is_valid):
21582158
@classmethod
21592159
def rng_fn(cls, rng, mu, W, alpha, tau, W_is_valid, size=None):
21602160
"""Sample from the CAR distribution.
2161-
2161+
21622162
Parameters
21632163
----------
21642164
rng : numpy.random.Generator
@@ -2175,7 +2175,7 @@ def rng_fn(cls, rng, mu, W, alpha, tau, W_is_valid, size=None):
21752175
Flag indicating whether W is a valid adjacency matrix
21762176
size : tuple, optional
21772177
Size of the samples to generate
2178-
2178+
21792179
Returns
21802180
-------
21812181
ndarray
@@ -2186,26 +2186,21 @@ def rng_fn(cls, rng, mu, W, alpha, tau, W_is_valid, size=None):
21862186

21872187
if np.any(alpha >= 1) or np.any(alpha <= -1):
21882188
raise ValueError("the domain of alpha is: -1 < alpha < 1")
2189-
2189+
21902190
W = np.asarray(W)
21912191
N = W.shape[0]
2192-
2192+
21932193
# Construct the precision matrix
21942194
D = np.diag(W.sum(axis=1))
21952195
Q = tau * (D - alpha * W)
2196-
2196+
21972197
# Convert precision to covariance matrix
21982198
cov = np.linalg.inv(Q)
2199-
2199+
22002200
# Generate samples using multivariate_normal with covariance matrix
22012201
mean = np.zeros(N) if mu is None else np.asarray(mu)
2202-
2203-
return stats.multivariate_normal.rvs(
2204-
mean=mean,
2205-
cov=cov,
2206-
size=size,
2207-
random_state=rng
2208-
)
2202+
2203+
return stats.multivariate_normal.rvs(mean=mean, cov=cov, size=size, random_state=rng)
22092204

22102205

22112206
car = CARRV()
@@ -2342,8 +2337,6 @@ def logp(value, mu, W, alpha, tau, W_is_valid):
23422337
W_is_valid,
23432338
msg="-1 < alpha < 1, tau > 0, W is a symmetric adjacency matrix.",
23442339
)
2345-
2346-
23472340

23482341

23492342
class ICARRV(RandomVariable):
@@ -2358,7 +2351,7 @@ def __call__(self, W, sigma, zero_sum_stdev, size=None, **kwargs):
23582351
@classmethod
23592352
def rng_fn(cls, rng, W, sigma, zero_sum_stdev, size=None):
23602353
"""Sample from the ICAR distribution.
2361-
2354+
23622355
Parameters
23632356
----------
23642357
rng : numpy.random.Generator
@@ -2371,34 +2364,31 @@ def rng_fn(cls, rng, W, sigma, zero_sum_stdev, size=None):
23712364
Controls how strongly to enforce the zero-sum constraint
23722365
size : tuple, optional
23732366
Size of the samples to generate
2374-
2367+
23752368
Returns
23762369
-------
23772370
ndarray
23782371
Samples from the ICAR distribution
23792372
"""
23802373
W = np.asarray(W)
23812374
N = W.shape[0]
2382-
2375+
23832376
# Construct the precision matrix (graph Laplacian)
23842377
D = np.diag(W.sum(axis=1))
23852378
Q = D - W
2386-
2379+
23872380
# Add regularization for the zero eigenvalue based on zero_sum_stdev
2388-
zero_sum_precision = 1.0 / (zero_sum_stdev * N)**2
2381+
zero_sum_precision = 1.0 / (zero_sum_stdev * N) ** 2
23892382
Q_reg = Q + zero_sum_precision * np.ones((N, N)) / N
2390-
2383+
23912384
# Convert precision to covariance matrix
23922385
cov = np.linalg.inv(Q_reg)
2393-
2386+
23942387
# Generate samples using multivariate_normal with covariance matrix
23952388
mean = np.zeros(N)
2396-
2389+
23972390
return sigma * stats.multivariate_normal.rvs(
2398-
mean=mean,
2399-
cov=cov,
2400-
size=size,
2401-
random_state=rng
2391+
mean=mean, cov=cov, size=size, random_state=rng
24022392
)
24032393

24042394

tests/distributions/test_multivariate.py

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2253,28 +2253,25 @@ class TestCAR:
22532253
def test_car_rng_fn(self):
22542254
"""Test the random number generator for the CAR distribution."""
22552255
# Create a simple adjacency matrix for a grid
2256-
W = np.array([
2257-
[0, 1, 0, 1],
2258-
[1, 0, 1, 0],
2259-
[0, 1, 0, 1],
2260-
[1, 0, 1, 0]
2261-
], dtype=np.int32) # Explicitly set dtype
2262-
2256+
W = np.array(
2257+
[[0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 1, 0]], dtype=np.int32
2258+
) # Explicitly set dtype
2259+
22632260
rng = np.random.default_rng(42)
22642261
mu = np.array([1.0, 2.0, 3.0, 4.0])
22652262
alpha = 0.7
22662263
tau = 0.5
2267-
2264+
22682265
# Generate samples - use W directly instead of tensor
22692266
car_dist = pm.CAR.dist(mu=mu, W=W, alpha=alpha, tau=tau)
22702267
car_samples = np.array([draw(car_dist, random_seed=rng) for _ in range(1000)])
2271-
2268+
22722269
# Test shape
22732270
assert car_samples.shape == (1000, 4)
2274-
2271+
22752272
# Test mean
22762273
assert np.allclose(car_samples.mean(axis=0), mu, atol=0.1)
2277-
2274+
22782275
# Test covariance structure - neighbors should be more correlated
22792276
sample_corr = np.corrcoef(car_samples.T)
22802277
for i in range(4):
@@ -2316,34 +2313,31 @@ def test_icar_logp(self):
23162313
def test_icar_rng_fn(self):
23172314
"""Test the random number generator for the ICAR distribution."""
23182315
# Create a simple adjacency matrix for a grid
2319-
W = np.array([
2320-
[0, 1, 0, 1],
2321-
[1, 0, 1, 0],
2322-
[0, 1, 0, 1],
2323-
[1, 0, 1, 0]
2324-
], dtype=np.int32) # Explicitly set dtype
2325-
2326-
rng = np.random.default_rng(42)
2316+
W = np.array(
2317+
[[0, 1, 0, 1], [1, 0, 1, 0], [0, 1, 0, 1], [1, 0, 1, 0]], dtype=np.int32
2318+
) # Explicitly set dtype
2319+
2320+
rng = np.random.default_rng(42)
23272321
sigma = 2.0
23282322
zero_sum_stdev = 0.001
2329-
2323+
23302324
# Use W directly instead of converting to tensor
23312325
icar_dist = pm.ICAR.dist(W=W, sigma=sigma, zero_sum_stdev=zero_sum_stdev)
23322326
icar_samples = np.array([draw(icar_dist, random_seed=rng) for _ in range(1000)])
2333-
2327+
23342328
# Test shape
23352329
assert icar_samples.shape == (1000, 4)
2336-
2330+
23372331
# Test approximate zero-sum constraint
23382332
assert np.abs(icar_samples.sum(axis=1).mean()) < 0.1
2339-
2333+
23402334
# Test variance scale - expect variance ≈ sigma^2 * (N-1)/N due to constraint
23412335
var_scale = (W.shape[0] - 1) / W.shape[0] # Degrees of freedom adjustment
23422336
expected_var = sigma**2 * var_scale
23432337
observed_var = np.var(icar_samples, axis=1).mean()
2344-
2338+
23452339
# Use a more generous tolerance to account for the zero sum constraint's impact on variance
2346-
assert np.abs(observed_var - expected_var) < 2.0
2340+
assert np.abs(observed_var - expected_var) < 2.0
23472341

23482342
@pytest.mark.parametrize(
23492343
"W,msg",

0 commit comments

Comments
 (0)