Integer values with pm.Data()

Hi, is it possible to use integer values within pm.Data() for indexing?

In the below example model3 fails using pm.Data() whilst model1 and model2 work fine.

pymc version 3.7
theano version 1.0.4

import pymc3 as pm
import theano.tensor as tt
import numpy as np

N = 24
y = np.random.normal(size=N)
idx = np.round(np.random.rand(N)).astype(np.int)
y += 5*idx

with pm.Model() as model1:
    mus = pm.Uniform('mu', lower=-10, upper=10, shape=2)
    mu = mus[idx]
    obs = pm.Normal('obs', mu=mu, sigma=1, observed=y)
    trace1 = pm.sample()
print( 'model1\n', pm.summary(trace1).round(2) )

y_shared = tt.as_tensor_variable(y)
idx_shared = tt.as_tensor_variable(idx)
with pm.Model() as model2:
    mus = pm.Uniform('mu', lower=-10, upper=10, shape=2)
    mu = mus[idx_shared]
    obs = pm.Normal('obs', mu=mu, sigma=1, observed=y_shared)
    trace2 = pm.sample()
print( 'model2\n', pm.summary(trace2).round(2) )

with pm.Model() as model3:
    y_data = pm.Data('y_data', y)
    idx_data = pm.Data('idx_data', idx)
    mus = pm.Uniform('mu', lower=-10, upper=10, shape=2)
    mu = mus[idx_data]
    obs = pm.Normal('obs', mu=mu, sigma=1, observed=y_data)
    trace3 = pm.sample()
print( 'model3', pm.summary(trace3).round(2) )

It fails with TypeError

TypeError                                 Traceback (most recent call last)
<ipython-input-11-b3737dabc94c> in <module>
     28     idx_data = pm.Data('idx_data', idx)
     29     mus = pm.Uniform('mu', lower=-10, upper=10, shape=2)
---> 30     mu = mus[idx_data]
     31     obs = pm.Normal('obs', mu=mu, sigma=1, observed=y_data)
     32     trace3 = pm.sample()

~/miniconda3/lib/python3.6/site-packages/theano/tensor/var.py in __getitem__(self, args)
    568                             TensorVariable, TensorConstant,
    569                             theano.tensor.sharedvar.TensorSharedVariable))):
--> 570                 return self.take(args[axis], axis)
    571             else:
    572                 return theano.tensor.subtensor.advanced_subtensor(self, *args)

~/miniconda3/lib/python3.6/site-packages/theano/tensor/var.py in take(self, indices, axis, mode)
    612 
    613     def take(self, indices, axis=None, mode='raise'):
--> 614         return theano.tensor.subtensor.take(self, indices, axis, mode)
    615 
    616     # COPYING

~/miniconda3/lib/python3.6/site-packages/theano/tensor/subtensor.py in take(a, indices, axis, mode)
   2448             return advanced_subtensor1(a.flatten(), indices)
   2449         elif axis == 0:
-> 2450             return advanced_subtensor1(a, indices)
   2451         else:
   2452             if axis < 0:

~/miniconda3/lib/python3.6/site-packages/theano/gof/op.py in __call__(self, *inputs, **kwargs)
    613         """
    614         return_list = kwargs.pop('return_list', False)
--> 615         node = self.make_node(*inputs, **kwargs)
    616 
    617         if config.compute_test_value != 'off':

~/miniconda3/lib/python3.6/site-packages/theano/tensor/subtensor.py in make_node(self, x, ilist)
   1701         ilist_ = theano.tensor.as_tensor_variable(ilist)
   1702         if ilist_.type.dtype not in theano.tensor.integer_dtypes:
-> 1703             raise TypeError('index must be integers')
   1704         if ilist_.type.ndim != 1:
   1705             raise TypeError('index must be vector')

TypeError: index must be integers
1 Like

Could you raise an issue on Github, I dont think we should be doing upcasting in pm.Data

In fact it has already been raised as https://github.com/pymc-devs/pymc3/issues/3493