How to sample a symmetric matrix with parameters at particular locations?

This is the simplest way I can think of to generate a symmetric matrix with desired sparsity and independent, normally-distributed entries. The basic idea is that we take the upper triangular matrix, add it to its transpose to create a binary mask, and use this mask to zero out elements of a symmetric matrix. We make sure it is symmetric by summing a matrix with its transpose. Then, since the sum of independent normals is also normal, we are guaranteed to have normally-distributed elements in the entries of K. If you want to tweak the standard deviation of the prior for those entires, you’ll just have to remember that the variance of the sum is the sum of the variances. One downside of this approach is that it samples extra variables in K_raw which are unused since we immediately zero them out in the operation mask * K_raw.

import pymc3 as pm
import numpy as np

d = 4

# This is the upper triangular matrix like in the CSV file
tri  = np.triu(np.ones([d,d]), k=1)

# We convert this into a mask for the symmetric matrix
mask = tri + tri.T + np.eye(d)
zero_locations = [(0,1), (1,2), (2,3)]

for row, col in zero_locations:
    mask[row, col] = 0
    mask[col, row] = 0

with pm.Model():
    K_raw = pm.HalfNormal('K_raw', shape=[d,d])
    K     = pm.Deterministic('K', mask * (K_raw + K_raw.T))
    trace = pm.sample()
1 Like