R/075_atoms_elementwise_log_normcdf.R

Defines functions log_normcdf

Documented in log_normcdf

#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/atoms/elementwise/log_normcdf.R
#####

## CVXPY SOURCE: atoms/elementwise/log_normcdf.py
## LogNormcdf -- quadratic approximation of log(Phi(x))

#' Elementwise log of the standard normal CDF
#'
#' @description
#' Quadratic approximation of `log(pnorm(x))` with modest accuracy over the range -4 to 4.
#'
#' @param x An Expression or numeric value.
#' @returns A concave Expression representing log(Phi(x)).
#' @export
log_normcdf <- function(x) {
  x <- as_expr(x)
  diag_vals <- sqrt(c(0.02301291, 0.08070214, 0.16411522,
                       0.09003495, 0.08200854, 0.01371543, 0.04641081))
  b <- matrix(c(3.0, 2.0, 1.0, 0.0, -1.0, -2.5, -3.5), ncol = 1L)
  nb <- length(diag_vals)

  flat_x <- reshape_expr(x, c(1L, expr_size(x)))

  ## A @ (b %*% ones(1, size) - ones(nb, 1) %*% flat_x)
  ## A is diagonal, so element-wise multiply by diag_vals
  ones_x <- Constant(matrix(1, 1L, expr_size(x)))
  ones_b <- Constant(matrix(1, nb, 1L))
  inner <- Constant(b) %*% ones_x - ones_b %*% flat_x
  A <- Constant(as(Matrix::Diagonal(x = diag_vals), "generalMatrix"))
  y <- A %*% inner

  out <- -sum_entries(Maximum(y, 0)^2, axis = 2L)
  reshape_expr(out, x@shape)
}

Try the CVXR package in your browser

Any scripts or data that you put into this service are public.

CVXR documentation built on March 6, 2026, 9:10 a.m.