How to use map function on a column vector?

Suppose I have a vector of length N, how can I map each element in the vector with a given function and get a vector of length N as output?
Let f(x, a, b) = gamma_cdf(x, a, b)

vector[N] z;

Desired output:

output_vector : [f(z[1], a, b), f(z[2], a, b),......, f(z[N], a, b)]

Thank You

Probably:

vector [N] output;

for (i in 1 : N) {
  output[i] = gamma_cdf(z[i], a, b);  
}

I don’t think the *_cdf functions are vectorised.

Edit - the new title suggests you want to use map_rect? Is this correct?

Yes, I actually want to use the map_rect with the function gamma_cdf.

Is there any way to vectorise this, as the above method would be computationally challenging?

@hhau’s code above, even though it’s a loop, can be run inside a map_rect function, but there is no currently exposed signature for gamma_cdf(or, as @hhau points out, any *_cdf) that returns a vector. Generally, you can roll your own cdf that returns a vector, but in the particular case, calculating a gamma cdf requires calculating the lower incomplete gamma function, and Stan’s exposed gamma_p does not operate on vectors. I don’t know if there would be another way.

Thanks for the explaination @hhau and @ssp3nc3r
What if the function was different? Can we apply map_rect to the below function?

real Hill(real t, real ec, real slope) {
    return 1 / (1 + (t / ec)^(-slope));
  }

Where t is an element in the vector “v” and “ec”, “slope” are constants?

I find it valuable to start with an example in the Stan manual and create small experiments. For example, try to compile the map_rect example in the Stan manual as is:

and then add your hypothetical Hill function. You will see that you can call the Hill function within the example lr function:

functions {
  real Hill(real t, real ec, real slope) {
    return 1 / (1 + (t / ec)^(-slope));
  }
  
  vector lr(vector beta, vector theta, real[] x, int[] y) {
    
    real t = beta[1];
    real ec = theta[1];
    real slope = 1;
    real myHill;
    real lp;
    
    myHill = Hill(t, ec, slope);
    
    lp = bernoulli_logit_lpmf(y | beta[1]
                                       + to_vector(x) * beta[2]);
    return [lp]';
  }
}

The above, of course, doesn’t do anything with your function because I don’t know your goals. But small experiments can be valuable.

1 Like