Any way to assign values to objects specified by index?

#1

Pretty sure the answer is ‘no’ but thought I’d see if there’s any bright ideas.
I have a set of N objects (matrices, vectors, whatever – different structures) and a vector of values. I’d like to assign the vector of values to the N objects, according to a corresponding vector of indices representing the object and indices within the object to assign to.

I currently do this separately for each of the N objects, but it’s ugly.

0 Likes

#2

It’s a bit hard to tell what you’re asking for. If you posted the code for your current “ugly” solution, that may clarify things.

0 Likes

#3

Not sure if everything is correct but this gives the idea. I’d like to create bob and jane without repeated code / separate loops.

functions{
  real tform(real rawpar, int whichtransform){
    real tpar;
    if(whichtransform==1) tpar = exp(rawpar) else tpar = inv_logit(tpar)
    return(tpar)
  }
}
data{
  int npars;
  matrix[4,4] bobstructure;
  matrix[3,4] janestructure;
}
parameters{
  vector[npars] rawparvec;
}
transformed parameters{
  matrix[2,2] bob;
  vector[3] jane;
  
  for(rowi in 1:nrows(bobstructure)){
    bob[ bobstructure[rowi,1], bobstructure[rowi,2] ] = 
      tform( rawparvec[bobstructure[rowi,3]], bobstructure[rowi,4] )
  }
  
  for(rowi in 1:nrows(janestructure)){
    jane[ janestructure[rowi,1], janestructure[rowi,2] ] = 
      tform( rawparvec[janestructure[rowi,3]], janestructure[rowi,4] )
  }
}
0 Likes

#4

Aside from the tpar = inv_logit(tpar) bit, which I gather is supposed to be tpar = inv_logit(rawpar), and using two indices to index into a vector (which I gather is not something that happens in your real code), I don’t see anything that looks particularly ugly. About the only repetition in the code that I see is the structure of the for loops, and I don’t think there’s much that you can do about that.

0 Likes

#5

it’s a small example to explain the question – do you really need me to copy the bob and jane creation loops a bunch of times, and do extra checks etc on the inside of the loop, to show how it looks? Arrays are handy for basically the same reason. I guess in the end I’m asking about a list like functionality, which clearly doesn’t exist, but I’d still be happy to hear other ideas.

0 Likes

#6

I don’t think this is possible without some number of: lists / function applicators / dynamic types. You could switch all your data structures to n-d arrays and write some kind of function that takes the arrays and applies the tform function. but then your transformed parameters block just looks like

transformed parameters {
  matrix[2,2] bob;
  vector[3] jane;

  bob = sort_of_function_apply(bobstructure, rawparvec);
  jane = sort_of_function_apply(janestructure, rawparvec); 
}

where yo do all the computation you are currently doing inside that function.

You loose all the type information though / end up having to write loops instead of using matrix multiplications where possible.

Edit: I don’t actually think you can do this either, because you need to declare in the function signature the number of dimensions of the n-d array. Probably not possible.

0 Likes