From ceaa22ea92267b6f8fa63a99ea72ddcf88c3eb49 Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Thu, 13 Oct 2022 12:43:19 -0400 Subject: [PATCH 1/2] Add std_normal_log_qf and std_normal_qf The latter is just a synonym for inv_Phi --- src/middle/Stan_math_signatures.ml | 4 + src/stan_math_backend/Expression_gen.ml | 8 +- .../math/functions/inv_phi.stan | 25 ---- .../math/matrix/inv_Phi.stan | 11 +- .../math/matrix/std_normal_log_qf.stan | 136 ++++++++++++++++++ .../math/matrix/std_normal_qf.stan | 136 ++++++++++++++++++ 6 files changed, 289 insertions(+), 31 deletions(-) delete mode 100644 test/integration/good/function-signatures/math/functions/inv_phi.stan create mode 100644 test/integration/good/function-signatures/math/matrix/std_normal_log_qf.stan create mode 100644 test/integration/good/function-signatures/math/matrix/std_normal_qf.stan diff --git a/src/middle/Stan_math_signatures.ml b/src/middle/Stan_math_signatures.ml index 0e7ffd5096..13ecf71143 100644 --- a/src/middle/Stan_math_signatures.ml +++ b/src/middle/Stan_math_signatures.ml @@ -419,6 +419,10 @@ let math_sigs = ; ([basic_vectorized], "sinh", [DDeepVectorized], SoA) ; ([basic_vectorized], "sqrt", [DDeepVectorized], SoA) ; ([basic_vectorized], "square", [DDeepVectorized], SoA) + (* TODO: Eventually will want to move _qf to be part of the distribution list above *) + ; ([basic_vectorized], "std_normal_qf", [DDeepVectorized], SoA) + (* std_normal_qf is an alias for inv_Phi *) + ; ([basic_vectorized], "std_normal_log_qf", [DDeepVectorized], SoA) ; ([basic_vectorized], "step", [DReal], SoA) ; ([basic_vectorized], "tan", [DDeepVectorized], SoA) ; ([basic_vectorized], "tanh", [DDeepVectorized], SoA) diff --git a/src/stan_math_backend/Expression_gen.ml b/src/stan_math_backend/Expression_gen.ml index 91c9c03319..09702ee709 100644 --- a/src/stan_math_backend/Expression_gen.ml +++ b/src/stan_math_backend/Expression_gen.ml @@ -127,6 +127,9 @@ let fn_renames = ; (FnNegInf, "stan::math::negative_infinity") ; (FnResizeToMatch, "stan::math::resize_to_match") ; (FnNaN, "std::numeric_limits::quiet_NaN") ] + @ [ ("lmultiply", "stan::math::multiply_log") + ; ("lchoose", "stan::math::binomial_coefficient_log") + ; ("std_normal_qf", "stan::math::inv_Phi") ] |> String.Map.of_alist_exn let map_rect_calls = Int.Table.create () @@ -263,11 +266,6 @@ and gen_operator_app op ppf es_in = and gen_misc_special_math_app (f : string) (mem_pattern : Mem_pattern.t) (ret_type : UnsizedType.returntype option) = match f with - | "lmultiply" -> - Some (fun ppf es -> pp_binary_f ppf "stan::math::multiply_log" es) - | "lchoose" -> - Some - (fun ppf es -> pp_binary_f ppf "stan::math::binomial_coefficient_log" es) | "target" -> Some (fun ppf _ -> pf ppf "stan::math::get_lp(lp__, lp_accum__)") | "get_lp" -> Some (fun ppf _ -> pf ppf "stan::math::get_lp(lp__, lp_accum__)") | f when Map.mem fn_renames f -> diff --git a/test/integration/good/function-signatures/math/functions/inv_phi.stan b/test/integration/good/function-signatures/math/functions/inv_phi.stan deleted file mode 100644 index caf19e3e53..0000000000 --- a/test/integration/good/function-signatures/math/functions/inv_phi.stan +++ /dev/null @@ -1,25 +0,0 @@ -data { - int d_int; - real d_real; -} -transformed data { - int transformed_data_int; - real transformed_data_real; - - transformed_data_real = inv_Phi(d_int); - transformed_data_real = inv_Phi(d_real); -} -parameters { - real p_real; - real y_p; -} -transformed parameters { - real transformed_param_real; - - transformed_param_real = inv_Phi(d_int); - transformed_param_real = inv_Phi(d_real); - transformed_param_real = inv_Phi(p_real); -} -model { - y_p ~ normal(0,1); -} diff --git a/test/integration/good/function-signatures/math/matrix/inv_Phi.stan b/test/integration/good/function-signatures/math/matrix/inv_Phi.stan index efbc3bffc8..7b90a2d326 100644 --- a/test/integration/good/function-signatures/math/matrix/inv_Phi.stan +++ b/test/integration/good/function-signatures/math/matrix/inv_Phi.stan @@ -1,5 +1,6 @@ data { int d_int; + real d_real; array[d_int] int d_int_array; array[d_int] real d_real_array; matrix[d_int, d_int] d_matrix; @@ -23,6 +24,7 @@ data { array[3, 4, 5] matrix[2, 3] x5w; } transformed data { + real transformed_data_real; matrix[d_int, d_int] transformed_data_matrix; vector[d_int] transformed_data_vector; row_vector[d_int] transformed_data_row_vector; @@ -41,6 +43,8 @@ transformed data { array[3, 4, 5] row_vector[2] trans_x4w; array[3, 4, 5] matrix[2, 3] trans_x5w; + transformed_data_real = inv_Phi(d_int); + transformed_data_real = inv_Phi(d_real); transformed_data_matrix = inv_Phi(d_matrix); transformed_data_vector = inv_Phi(d_vector); transformed_data_row_vector = inv_Phi(d_row_vector); @@ -83,6 +87,8 @@ parameters { array[3, 4, 5] matrix[2, 3] p_x5w; } transformed parameters { + real transformed_param_real; + matrix[d_int, d_int] transformed_param_matrix; vector[d_int] transformed_param_vector; row_vector[d_int] transformed_param_row_vector; @@ -100,6 +106,10 @@ transformed parameters { array[3, 4, 5] row_vector[2] trans_p_x4w; array[3, 4, 5] matrix[2, 3] trans_p_x5w; + transformed_param_real = inv_Phi(d_int); + transformed_param_real = inv_Phi(d_real); + transformed_param_real = inv_Phi(p_real); + transformed_param_matrix = inv_Phi(d_matrix); transformed_param_vector = inv_Phi(d_vector); transformed_param_row_vector = inv_Phi(d_row_vector); @@ -124,4 +134,3 @@ transformed parameters { model { y_p ~ normal(0, 1); } - diff --git a/test/integration/good/function-signatures/math/matrix/std_normal_log_qf.stan b/test/integration/good/function-signatures/math/matrix/std_normal_log_qf.stan new file mode 100644 index 0000000000..e9e7b1fb9c --- /dev/null +++ b/test/integration/good/function-signatures/math/matrix/std_normal_log_qf.stan @@ -0,0 +1,136 @@ +data { + int d_int; + real d_real; + array[d_int] int d_int_array; + array[d_int] real d_real_array; + matrix[d_int, d_int] d_matrix; + vector[d_int] d_vector; + row_vector[d_int] d_row_vector; + + array[3] vector[2] x3y; + array[3] row_vector[2] x4y; + array[3] matrix[2, 3] x5y; + + array[3, 4] int x1z; + array[3, 4] real x2z; + array[3, 4] vector[2] x3z; + array[3, 4] row_vector[2] x4z; + array[3, 4] matrix[2, 3] x5z; + + array[3, 4, 5] int x1w; + array[3, 4, 5] real x2w; + array[3, 4, 5] vector[2] x3w; + array[3, 4, 5] row_vector[2] x4w; + array[3, 4, 5] matrix[2, 3] x5w; +} +transformed data { + real transformed_data_real; + matrix[d_int, d_int] transformed_data_matrix; + vector[d_int] transformed_data_vector; + row_vector[d_int] transformed_data_row_vector; + + array[3] vector[2] trans_x3y; + array[3] row_vector[2] trans_x4y; + array[3] matrix[2, 3] trans_x5y; + + array[3, 4] real trans_x2z; + array[3, 4] vector[2] trans_x3z; + array[3, 4] row_vector[2] trans_x4z; + array[3, 4] matrix[2, 3] trans_x5z; + + array[3, 4, 5] real trans_x2w; + array[3, 4, 5] vector[2] trans_x3w; + array[3, 4, 5] row_vector[2] trans_x4w; + array[3, 4, 5] matrix[2, 3] trans_x5w; + + transformed_data_real = std_normal_log_qf(d_int); + transformed_data_real = std_normal_log_qf(d_real); + transformed_data_matrix = std_normal_log_qf(d_matrix); + transformed_data_vector = std_normal_log_qf(d_vector); + transformed_data_row_vector = std_normal_log_qf(d_row_vector); + trans_x3y = std_normal_log_qf(x3y); + trans_x4y = std_normal_log_qf(x4y); + trans_x5y = std_normal_log_qf(x5y); + + trans_x2z = std_normal_log_qf(x1z); + trans_x2z = std_normal_log_qf(x2z); + trans_x3z = std_normal_log_qf(x3z); + trans_x4z = std_normal_log_qf(x4z); + trans_x5z = std_normal_log_qf(x5z); + + trans_x2w = std_normal_log_qf(x1w); + trans_x2w = std_normal_log_qf(x2w); + trans_x3w = std_normal_log_qf(x3w); + trans_x4w = std_normal_log_qf(x4w); + trans_x5w = std_normal_log_qf(x5w); +} +parameters { + real p_real; + real y_p; + array[d_int] real p_real_array; + matrix[d_int, d_int] p_matrix; + vector[d_int] p_vector; + row_vector[d_int] p_row_vector; + + array[3] vector[2] p_x3y; + array[3] row_vector[2] p_x4y; + array[3] matrix[2, 3] p_x5y; + + array[3, 4] real p_x2z; + array[3, 4] vector[2] p_x3z; + array[3, 4] row_vector[2] p_x4z; + array[3, 4] matrix[2, 3] p_x5z; + + array[3, 4, 5] real p_x2w; + array[3, 4, 5] vector[2] p_x3w; + array[3, 4, 5] row_vector[2] p_x4w; + array[3, 4, 5] matrix[2, 3] p_x5w; +} +transformed parameters { + real transformed_param_real; + + matrix[d_int, d_int] transformed_param_matrix; + vector[d_int] transformed_param_vector; + row_vector[d_int] transformed_param_row_vector; + array[3] vector[2] trans_p_x3y; + array[3] row_vector[2] trans_p_x4y; + array[3] matrix[2, 3] trans_p_x5y; + + array[3, 4] real trans_p_x2z; + array[3, 4] vector[2] trans_p_x3z; + array[3, 4] row_vector[2] trans_p_x4z; + array[3, 4] matrix[2, 3] trans_p_x5z; + + array[3, 4, 5] real trans_p_x2w; + array[3, 4, 5] vector[2] trans_p_x3w; + array[3, 4, 5] row_vector[2] trans_p_x4w; + array[3, 4, 5] matrix[2, 3] trans_p_x5w; + + transformed_param_real = std_normal_log_qf(d_int); + transformed_param_real = std_normal_log_qf(d_real); + transformed_param_real = std_normal_log_qf(p_real); + + transformed_param_matrix = std_normal_log_qf(d_matrix); + transformed_param_vector = std_normal_log_qf(d_vector); + transformed_param_row_vector = std_normal_log_qf(d_row_vector); + transformed_param_matrix = std_normal_log_qf(p_matrix); + transformed_param_vector = std_normal_log_qf(p_vector); + transformed_param_row_vector = std_normal_log_qf(p_row_vector); + + trans_p_x3y = std_normal_log_qf(p_x3y); + trans_p_x4y = std_normal_log_qf(p_x4y); + trans_p_x5y = std_normal_log_qf(p_x5y); + + trans_p_x2z = std_normal_log_qf(p_x2z); + trans_p_x3z = std_normal_log_qf(p_x3z); + trans_p_x4z = std_normal_log_qf(p_x4z); + trans_p_x5z = std_normal_log_qf(p_x5z); + + trans_p_x2w = std_normal_log_qf(p_x2w); + trans_p_x3w = std_normal_log_qf(p_x3w); + trans_p_x4w = std_normal_log_qf(p_x4w); + trans_p_x5w = std_normal_log_qf(p_x5w); +} +model { + y_p ~ normal(0, 1); +} diff --git a/test/integration/good/function-signatures/math/matrix/std_normal_qf.stan b/test/integration/good/function-signatures/math/matrix/std_normal_qf.stan new file mode 100644 index 0000000000..b2c345c4ab --- /dev/null +++ b/test/integration/good/function-signatures/math/matrix/std_normal_qf.stan @@ -0,0 +1,136 @@ +data { + int d_int; + real d_real; + array[d_int] int d_int_array; + array[d_int] real d_real_array; + matrix[d_int, d_int] d_matrix; + vector[d_int] d_vector; + row_vector[d_int] d_row_vector; + + array[3] vector[2] x3y; + array[3] row_vector[2] x4y; + array[3] matrix[2, 3] x5y; + + array[3, 4] int x1z; + array[3, 4] real x2z; + array[3, 4] vector[2] x3z; + array[3, 4] row_vector[2] x4z; + array[3, 4] matrix[2, 3] x5z; + + array[3, 4, 5] int x1w; + array[3, 4, 5] real x2w; + array[3, 4, 5] vector[2] x3w; + array[3, 4, 5] row_vector[2] x4w; + array[3, 4, 5] matrix[2, 3] x5w; +} +transformed data { + real transformed_data_real; + matrix[d_int, d_int] transformed_data_matrix; + vector[d_int] transformed_data_vector; + row_vector[d_int] transformed_data_row_vector; + + array[3] vector[2] trans_x3y; + array[3] row_vector[2] trans_x4y; + array[3] matrix[2, 3] trans_x5y; + + array[3, 4] real trans_x2z; + array[3, 4] vector[2] trans_x3z; + array[3, 4] row_vector[2] trans_x4z; + array[3, 4] matrix[2, 3] trans_x5z; + + array[3, 4, 5] real trans_x2w; + array[3, 4, 5] vector[2] trans_x3w; + array[3, 4, 5] row_vector[2] trans_x4w; + array[3, 4, 5] matrix[2, 3] trans_x5w; + + transformed_data_real = std_normal_qf(d_int); + transformed_data_real = std_normal_qf(d_real); + transformed_data_matrix = std_normal_qf(d_matrix); + transformed_data_vector = std_normal_qf(d_vector); + transformed_data_row_vector = std_normal_qf(d_row_vector); + trans_x3y = std_normal_qf(x3y); + trans_x4y = std_normal_qf(x4y); + trans_x5y = std_normal_qf(x5y); + + trans_x2z = std_normal_qf(x1z); + trans_x2z = std_normal_qf(x2z); + trans_x3z = std_normal_qf(x3z); + trans_x4z = std_normal_qf(x4z); + trans_x5z = std_normal_qf(x5z); + + trans_x2w = std_normal_qf(x1w); + trans_x2w = std_normal_qf(x2w); + trans_x3w = std_normal_qf(x3w); + trans_x4w = std_normal_qf(x4w); + trans_x5w = std_normal_qf(x5w); +} +parameters { + real p_real; + real y_p; + array[d_int] real p_real_array; + matrix[d_int, d_int] p_matrix; + vector[d_int] p_vector; + row_vector[d_int] p_row_vector; + + array[3] vector[2] p_x3y; + array[3] row_vector[2] p_x4y; + array[3] matrix[2, 3] p_x5y; + + array[3, 4] real p_x2z; + array[3, 4] vector[2] p_x3z; + array[3, 4] row_vector[2] p_x4z; + array[3, 4] matrix[2, 3] p_x5z; + + array[3, 4, 5] real p_x2w; + array[3, 4, 5] vector[2] p_x3w; + array[3, 4, 5] row_vector[2] p_x4w; + array[3, 4, 5] matrix[2, 3] p_x5w; +} +transformed parameters { + real transformed_param_real; + + matrix[d_int, d_int] transformed_param_matrix; + vector[d_int] transformed_param_vector; + row_vector[d_int] transformed_param_row_vector; + array[3] vector[2] trans_p_x3y; + array[3] row_vector[2] trans_p_x4y; + array[3] matrix[2, 3] trans_p_x5y; + + array[3, 4] real trans_p_x2z; + array[3, 4] vector[2] trans_p_x3z; + array[3, 4] row_vector[2] trans_p_x4z; + array[3, 4] matrix[2, 3] trans_p_x5z; + + array[3, 4, 5] real trans_p_x2w; + array[3, 4, 5] vector[2] trans_p_x3w; + array[3, 4, 5] row_vector[2] trans_p_x4w; + array[3, 4, 5] matrix[2, 3] trans_p_x5w; + + transformed_param_real = std_normal_qf(d_int); + transformed_param_real = std_normal_qf(d_real); + transformed_param_real = std_normal_qf(p_real); + + transformed_param_matrix = std_normal_qf(d_matrix); + transformed_param_vector = std_normal_qf(d_vector); + transformed_param_row_vector = std_normal_qf(d_row_vector); + transformed_param_matrix = std_normal_qf(p_matrix); + transformed_param_vector = std_normal_qf(p_vector); + transformed_param_row_vector = std_normal_qf(p_row_vector); + + trans_p_x3y = std_normal_qf(p_x3y); + trans_p_x4y = std_normal_qf(p_x4y); + trans_p_x5y = std_normal_qf(p_x5y); + + trans_p_x2z = std_normal_qf(p_x2z); + trans_p_x3z = std_normal_qf(p_x3z); + trans_p_x4z = std_normal_qf(p_x4z); + trans_p_x5z = std_normal_qf(p_x5z); + + trans_p_x2w = std_normal_qf(p_x2w); + trans_p_x3w = std_normal_qf(p_x3w); + trans_p_x4w = std_normal_qf(p_x4w); + trans_p_x5w = std_normal_qf(p_x5w); +} +model { + y_p ~ normal(0, 1); +} From c82b3ce51a4c2d41c390b4be6e25adb2ba6608e8 Mon Sep 17 00:00:00 2001 From: Brian Ward Date: Thu, 13 Oct 2022 12:49:44 -0400 Subject: [PATCH 2/2] Dune promote --- .../signatures/stan_math_signatures.t | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/test/integration/signatures/stan_math_signatures.t b/test/integration/signatures/stan_math_signatures.t index b220bfdf16..760a4a127a 100644 --- a/test/integration/signatures/stan_math_signatures.t +++ b/test/integration/signatures/stan_math_signatures.t @@ -24578,10 +24578,90 @@ Display all Stan math signatures exposed in the language std_normal_log(vector) => real std_normal_log(row_vector) => real std_normal_log(array[] real) => real + std_normal_log_qf(int) => real + std_normal_log_qf(real) => real + std_normal_log_qf(vector) => vector + std_normal_log_qf(row_vector) => row_vector + std_normal_log_qf(matrix) => matrix + std_normal_log_qf(array[] int) => array[] real + std_normal_log_qf(array[] real) => array[] real + std_normal_log_qf(array[] vector) => array[] vector + std_normal_log_qf(array[] row_vector) => array[] row_vector + std_normal_log_qf(array[] matrix) => array[] matrix + std_normal_log_qf(array[,] int) => array[,] real + std_normal_log_qf(array[,] real) => array[,] real + std_normal_log_qf(array[,] vector) => array[,] vector + std_normal_log_qf(array[,] row_vector) => array[,] row_vector + std_normal_log_qf(array[,] matrix) => array[,] matrix + std_normal_log_qf(array[,,] int) => array[,,] real + std_normal_log_qf(array[,,] real) => array[,,] real + std_normal_log_qf(array[,,] vector) => array[,,] vector + std_normal_log_qf(array[,,] row_vector) => array[,,] row_vector + std_normal_log_qf(array[,,] matrix) => array[,,] matrix + std_normal_log_qf(array[,,,] int) => array[,,,] real + std_normal_log_qf(array[,,,] real) => array[,,,] real + std_normal_log_qf(array[,,,] vector) => array[,,,] vector + std_normal_log_qf(array[,,,] row_vector) => array[,,,] row_vector + std_normal_log_qf(array[,,,] matrix) => array[,,,] matrix + std_normal_log_qf(array[,,,,] int) => array[,,,,] real + std_normal_log_qf(array[,,,,] real) => array[,,,,] real + std_normal_log_qf(array[,,,,] vector) => array[,,,,] vector + std_normal_log_qf(array[,,,,] row_vector) => array[,,,,] row_vector + std_normal_log_qf(array[,,,,] matrix) => array[,,,,] matrix + std_normal_log_qf(array[,,,,,] int) => array[,,,,,] real + std_normal_log_qf(array[,,,,,] real) => array[,,,,,] real + std_normal_log_qf(array[,,,,,] vector) => array[,,,,,] vector + std_normal_log_qf(array[,,,,,] row_vector) => array[,,,,,] row_vector + std_normal_log_qf(array[,,,,,] matrix) => array[,,,,,] matrix + std_normal_log_qf(array[,,,,,,] int) => array[,,,,,,] real + std_normal_log_qf(array[,,,,,,] real) => array[,,,,,,] real + std_normal_log_qf(array[,,,,,,] vector) => array[,,,,,,] vector + std_normal_log_qf(array[,,,,,,] row_vector) => array[,,,,,,] row_vector + std_normal_log_qf(array[,,,,,,] matrix) => array[,,,,,,] matrix std_normal_lpdf(real) => real std_normal_lpdf(vector) => real std_normal_lpdf(row_vector) => real std_normal_lpdf(array[] real) => real + std_normal_qf(int) => real + std_normal_qf(real) => real + std_normal_qf(vector) => vector + std_normal_qf(row_vector) => row_vector + std_normal_qf(matrix) => matrix + std_normal_qf(array[] int) => array[] real + std_normal_qf(array[] real) => array[] real + std_normal_qf(array[] vector) => array[] vector + std_normal_qf(array[] row_vector) => array[] row_vector + std_normal_qf(array[] matrix) => array[] matrix + std_normal_qf(array[,] int) => array[,] real + std_normal_qf(array[,] real) => array[,] real + std_normal_qf(array[,] vector) => array[,] vector + std_normal_qf(array[,] row_vector) => array[,] row_vector + std_normal_qf(array[,] matrix) => array[,] matrix + std_normal_qf(array[,,] int) => array[,,] real + std_normal_qf(array[,,] real) => array[,,] real + std_normal_qf(array[,,] vector) => array[,,] vector + std_normal_qf(array[,,] row_vector) => array[,,] row_vector + std_normal_qf(array[,,] matrix) => array[,,] matrix + std_normal_qf(array[,,,] int) => array[,,,] real + std_normal_qf(array[,,,] real) => array[,,,] real + std_normal_qf(array[,,,] vector) => array[,,,] vector + std_normal_qf(array[,,,] row_vector) => array[,,,] row_vector + std_normal_qf(array[,,,] matrix) => array[,,,] matrix + std_normal_qf(array[,,,,] int) => array[,,,,] real + std_normal_qf(array[,,,,] real) => array[,,,,] real + std_normal_qf(array[,,,,] vector) => array[,,,,] vector + std_normal_qf(array[,,,,] row_vector) => array[,,,,] row_vector + std_normal_qf(array[,,,,] matrix) => array[,,,,] matrix + std_normal_qf(array[,,,,,] int) => array[,,,,,] real + std_normal_qf(array[,,,,,] real) => array[,,,,,] real + std_normal_qf(array[,,,,,] vector) => array[,,,,,] vector + std_normal_qf(array[,,,,,] row_vector) => array[,,,,,] row_vector + std_normal_qf(array[,,,,,] matrix) => array[,,,,,] matrix + std_normal_qf(array[,,,,,,] int) => array[,,,,,,] real + std_normal_qf(array[,,,,,,] real) => array[,,,,,,] real + std_normal_qf(array[,,,,,,] vector) => array[,,,,,,] vector + std_normal_qf(array[,,,,,,] row_vector) => array[,,,,,,] row_vector + std_normal_qf(array[,,,,,,] matrix) => array[,,,,,,] matrix std_normal_rng() => real step(real) => real student_t_ccdf_log(real, real, real, real) => real