Skip to content

Feature request: vectorized phi() #3383

Open

Description

@ksvanhorn

Stan has a vectorized $\Phi(x)$ (standard cumulative distribution function) but lacks a corresponding vectorized $\varphi(x)$ (standard normal density). You can't get this using std_normal_lpdf(), as it sums the log density values; I'm asking for something that returns a vectorized result.

One use case for a vectorized $\Phi(x)$ is in computing a quasi-hinge function based on $\Phi(x)$:

$h(x) = x \Phi(x) + \varphi(x)$.

This function has range $(0,\infty)$ with $h(x) \to 0$ as $x\to -\infty$, $h(x)/x \to 1$ as $x\to \infty$, and $h'(x) = \Phi(x)$.

Activity

  1. bob-carpenter commented on Jul 6, 2023

    @bob-carpenter
    Member

    We do have a vectorized erf(), so a standard normal is just a factor of sqrt(2) away. Did you want the same signatures as we provide for erf()? That'd be

    vector phi(vector);
    row_vector phi(row_vector);
    matrix phi(matrix);
    real[] phi(real[]);
    ...

    There are other feature requests asking us to supply vectorized versions of all of our probability functions. They're useful for things like log likelihoods for leave-one-out cross-validation.

  2. rok-cesnovar commented on Jul 7, 2023

    @rok-cesnovar
    Member

    The Phi function supports the following signatures in the latest few versions:

    Phi(int) => real
    Phi(real) => real
    Phi(vector) => vector
    Phi(row_vector) => row_vector
    Phi(matrix) => matrix
    Phi(array[] int) => array[] real
    Phi(array[] real) => array[] real
    Phi(array[] vector) => array[] vector
    Phi(array[] row_vector) => array[] row_vector
    Phi(array[] matrix) => array[] matrix
    Phi(array[,] int) => array[,] real
    Phi(array[,] real) => array[,] real
    Phi(array[,] vector) => array[,] vector
    Phi(array[,] row_vector) => array[,] row_vector
    Phi(array[,] matrix) => array[,] matrix
    Phi(array[,,] int) => array[,,] real
    Phi(array[,,] real) => array[,,] real
    Phi(array[,,] vector) => array[,,] vector
    Phi(array[,,] row_vector) => array[,,] row_vector
    Phi(array[,,] matrix) => array[,,] matrix
    Phi(array[,,,] int) => array[,,,] real
    Phi(array[,,,] real) => array[,,,] real
    Phi(array[,,,] vector) => array[,,,] vector
    Phi(array[,,,] row_vector) => array[,,,] row_vector
    Phi(array[,,,] matrix) => array[,,,] matrix
    Phi(array[,,,,] int) => array[,,,,] real
    Phi(array[,,,,] real) => array[,,,,] real
    Phi(array[,,,,] vector) => array[,,,,] vector
    Phi(array[,,,,] row_vector) => array[,,,,] row_vector
    Phi(array[,,,,] matrix) => array[,,,,] matrix
    Phi(array[,,,,,] int) => array[,,,,,] real
    Phi(array[,,,,,] real) => array[,,,,,] real
    Phi(array[,,,,,] vector) => array[,,,,,] vector
    Phi(array[,,,,,] row_vector) => array[,,,,,] row_vector
    Phi(array[,,,,,] matrix) => array[,,,,,] matrix
    Phi(array[,,,,,,] int) => array[,,,,,,] real
    Phi(array[,,,,,,] real) => array[,,,,,,] real
    Phi(array[,,,,,,] vector) => array[,,,,,,] vector
    Phi(array[,,,,,,] row_vector) => array[,,,,,,] row_vector
    Phi(array[,,,,,,] matrix) => array[,,,,,,] matrix
  3. bob-carpenter commented on Jul 7, 2023

    @bob-carpenter
    Member

    Thanks @rok-cesnovar. This is the list you get from using the automatic vectorization of a unary function, which will be an easy way to implement this. Better to provide an analytic gradient for reverse mode. Callingstd_normal_lpdf function to implement unary standard normal is probably too heavy.

  4. transferred this issue fromstan-dev/stanon Sep 1, 2026
  5. SteveBronder commented on Sep 1, 2026

    @SteveBronder
    Collaborator

    Related, I have #2751 which vectorizes the normal_lpdf in a way that allows for a scalar or vector return.

    One thing we could do is, if we can agree on the form/code for the normal_lpdf in that branch then this is a good thing to have a swarm of claude's apply through the math library.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions