# Indexing using a free random variable

**URL:** <https://discourse.pymc.io/t/indexing-using-a-free-random-variable/939>\
**Category:** Questions\
**Created:** [March 13, 2018, 10:26am UTC](https://discourse.pymc.io/t/indexing-using-a-free-random-variable/939 "2018-03-13T10:26:45Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![Rupam\_Acharyya](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/rupam_acharyya/32/1919_2.png) [@Rupam\_Acharyya](https://discourse.pymc.io/u/Rupam_Acharyya)\
**Post date:** [May 24, 2019, 8:25pm UTC](https://discourse.pymc.io/t/indexing-using-a-free-random-variable/939/21 "2019-05-24T20:25:55Z")

</div>

I had written a similar code using the above suggestion.

```
sigma_list = np.linspace(0.1,0.5,6)
obs =[1,2,3,5]
with pm.Model() as model:
    z = pm.Categorical('z', p=np.ones(6)/6)
    x = sigma_list[z]
    Y = pm.Normal('Y',mu=0,tau=x,observed=obs)
    trace=pm.sample(1000) 

```

But I get the following error:

```
IndexError Traceback (most recent call last)
<ipython-input-38-c73f2c1a7037> in <module>
     23 #z = pm.DiscreteUniform('z',lower =0,upper=4)
     24 z = pm.Categorical('z', p=np.ones(6)/6)
---> 25 x = sigma_list[z]
     26 Y = pm.Normal('Y',mu=0,tau=x,observed=obs)
     27 #like = pm.DensityDist('like', my_likelihood(x), observed=obs)

IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

```

Could you please tell me what is wrong here?

---

<div class="post-metadata">

**Author:** ![junpenglao](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/junpenglao/32/8_2.png) [@junpenglao](https://discourse.pymc.io/u/junpenglao)\
**Post date:** [May 25, 2019, 5:24am UTC](https://discourse.pymc.io/t/indexing-using-a-free-random-variable/939/22 "2019-05-25T05:24:12Z")

</div>

`z` is a theano tensor (all pymc3 random variables are theano tensors), and indexing a numpy array with a theano tensor is not allowed.  
Wrapping your numpy array into theano should fix it.

```auto
import theano
sigma_list = theano.shared(np.linspace(0.1,0.5,6))

```

---

<div class="post-metadata">

**Author:** ![Rupam\_Acharyya](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/rupam_acharyya/32/1919_2.png) [@Rupam\_Acharyya](https://discourse.pymc.io/u/Rupam_Acharyya)\
**Post date:** [May 25, 2019, 5:08pm UTC](https://discourse.pymc.io/t/indexing-using-a-free-random-variable/939/23 "2019-05-25T17:08:42Z")

</div>

Perfect. That works. Thanks for the quick reply.

---

<div class="post-metadata">

**Author:** ![aditya](https://avatars.discourse-cdn.com/v4/letter/a/df705f/32.png) [@aditya](https://discourse.pymc.io/u/aditya)\
**Post date:** [October 9, 2019, 10:59pm UTC](https://discourse.pymc.io/t/indexing-using-a-free-random-variable/939/24 "2019-10-09T22:59:52Z")

</div>

Having a similar question with a slightly different use case.

I have a tensor which stores a bunch of potential new alpha parameters for a given model (temp\_dirchlet\_info in the code sample). My model generates a free random variable index z\_ij and then tries to use the output of temp\_dirchlet\_info[z\_ij, j, :] as the alpha parameter in the Dirichlet. Pymc3 doesn’t like alpha as this subtensor - so was wondering if there was another approach to achieve the same effect.

Repro and error below

```auto
import pymc3 as pm
import numpy as np
import theano

#Some parameters
n_features = 5
n_cluster = 5
n_fval = 2
n_Points = 10

#Some fake data for now
in_dat = np.random.randint(0, n_fval, size = (nPoints, n_features))
#Dummy potential dirchlet alpha vectors
temp_dirchlet_info = np.random.random(size=(n_clusters, n_features, n_fval))
temp_dirchlet_info = theano.shared(temp_dirchlet_info)
with pm.Model() as m:
  #Sampleing per point
  for i in range(0, n_Points):
      #Point mixture
      pi_i = pm.Dirichlet(f"pi_{i}", a = alpha, shape = n_clusters)        
      for j in range(0, n_features):
        #Pick out cluster
        z_ij = pm.Categorical(f"z_{i}{j}", p=pi_i)
        print(z_ij)
        #Get distribution of feature values
        phi_sj = pm.Dirichlet(f"phi_{i}{j}", a = temp_dirchlet_info[z_ij, j])
        #Sample feature value 
        x_ij = pm.Categorical(f"x_{i}{j}", p = phi_sj, shape = 1, observed = in_data[i, j])

```

```auto
/usr/local/lib/python3.6/dist-packages/pymc3/distributions/distribution.py in __init__ (self, shape, dtype, testval, defaults, transform, broadcastable)
     61 self.shape = np.atleast_1d(shape)
     62 if False in (np.floor(self.shape) == self.shape):
---> 63 raise TypeError("Expected int elements in shape")
     64 self.dtype = dtype
     65 self.type = TensorType(self.dtype, self.shape, broadcastable)

TypeError: Expected int elements in shape

```

---

<div class="post-metadata">

**Author:** ![junpenglao](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.pymc.io/junpenglao/32/8_2.png) [@junpenglao](https://discourse.pymc.io/u/junpenglao)\
**Post date:** [October 10, 2019, 8:08am UTC](https://discourse.pymc.io/t/indexing-using-a-free-random-variable/939/25 "2019-10-10T08:08:20Z")

</div>

Looks like you are trying to do latent Dirichlet allocation. You should try to reparameterized your model into a marginalized version: [Frequently Asked Questions](https://discourse.pymc.io/t/frequently-asked-questions/74/15)

---

<div class="post-metadata">

**Author:** ![aditya](https://avatars.discourse-cdn.com/v4/letter/a/df705f/32.png) [@aditya](https://discourse.pymc.io/u/aditya)\
**Post date:** [October 13, 2019, 3:36pm UTC](https://discourse.pymc.io/t/indexing-using-a-free-random-variable/939/26 "2019-10-13T15:36:18Z")

</div>

@junpenglao - sort of! Looking at a slight modification of LDA

![image](https://canada1.discourse-cdn.com/flex036/uploads/pymc3/original/2X/1/1b7c01fcb785d2406a4859e7bfd0da8eff8e12fa.png)

The part of I’m having problem on is the $$x\_{ij} $$ - I tried to store the the $$\phi$$ vectors in an S x J matrix but that can’t really be indexed into - and creating each i,j on the fly seems a bit expensive - us there at least a way to compute x\_i from z\_i in this setup easily?

---

<div class="post-metadata">

**Author:** ![aditya](https://avatars.discourse-cdn.com/v4/letter/a/df705f/32.png) [@aditya](https://discourse.pymc.io/u/aditya)\
**Post date:** [October 16, 2019, 7:29pm UTC](https://discourse.pymc.io/t/indexing-using-a-free-random-variable/939/27 "2019-10-16T19:29:53Z")

</div>

Narrowed it down a bit - see below.  
`Preformatted text``

```auto
#Assuming input data is all discrete - one hot encoding - can be expanded once the one hot case is working
alpha = np.ones(n_clusters) 
max_n_val = 2 #Discrete one hot encoding 
num_values = [max_n_val] * n_features # Extend later 
f_ind = np.tile(np.arange(dat.shape[1]), nPoints)
x_index = np.repeat(np.arange(dat.shape[0]), dat.shape[1])

with pm.Model() as model:
    # Picking out the important features per cluster
    omega = pm.Bernoulli('omega', p=q, shape=(n_clusters, n_features))
    # Picking out prototypes per cluster
    ps = pm.DiscreteUniform('p', 1, nPoints, shape = n_clusters)
    #Pick dirchlet (mixing potentials) for each point (weight for each npoint, what's weighting goes to each cluster)
    pis = pm.Dirichlet('pi', a = alpha, shape = (nPoints, n_clusters))
    # For each feature for each point, sample a cluster from which to choose from. 
    z = pm.Categorical("z", p = pis[x_index, :], shape = (nPoints * n_features))
    phis_clusters = np.zeros((n_clusters, n_features, 2))
    #Generate the distribution of feature outcomes phi_s
    for s in range(n_clusters):
      for j in range(n_features):
        n_val = num_values[j]
        g_vc = np.zeros(n_val)
        # Note that this only really works right now for binary/discrete features - has to be a bit more 
        # general for the many discrete feature case and for the continous case will have to come up with something else
        for v in range(n_val):
          g_vc[v] = lam *(1 + c *(omega[s, j] == 1 and all_data[ps[s]][j] == v))
        phis_clusters[s, j] = g_vc    
    #Flatten
    phis_flat = np.reshape(phis_clusters, (phis_clusters.shape[0] * phis_clusters.shape[1], phis_clusters.shape[2]))
    phi_index = np.repeat(np.arange(phis_clusters.shape[0]), phis_clusters.shape[1])
    #Generate relevant dirchlet's for each cluster x feature pair
    g = pm.Dirichlet("g", a = phis_flat, shape = phis_flat.shape)
    # Cateogrical datapoints given the observed one hot encoding - for each x, sample based on the selected
    # cluster/feature
    x = pm.Categorical("x", p = g[z * n_features + f_ind], observed = np.reshape(dat, dat.shape[0] * dat.shape[1]))

```

Struggling with how to marginalize over z here - given that z is generated from a Dirichlet with some dimension k and then used to generate a Categorical variable from 0-k-1

[Previous page](https://discourse.pymc.io/t/indexing-using-a-free-random-variable/939.md?page=1)
