R/185_reductions_complex2real_canonicalizers_aff_canon.R

Defines functions c2r_binary_canon .c2r_add .c2r_join c2r_hermitian_wrap_canon c2r_conj_canon c2r_imag_canon c2r_real_canon c2r_separable_canon

#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/reductions/complex2real/canonicalizers/aff_canon.R
#####

## CVXPY SOURCE: reductions/complex2real/canonicalizers/aff_canon.py
## Affine canonicalizers: separable, binary, conj, real, imag, hermitian_wrap

## -- separable_canon -----------------------------------------------
## For linear functions that are separable in real/imaginary parts:
## f(a + bi) = f(a) + f(b)i
c2r_separable_canon <- function(expr, real_args, imag_args, real2imag) {
  if (all(vapply(imag_args, is.null, logical(1L)))) {
    return(list(expr_copy(expr, real_args), NULL))
  } else if (all(vapply(real_args, is.null, logical(1L)))) {
    return(list(NULL, expr_copy(expr, imag_args)))
  } else {
    ## Mixed: fill in NULLs with zero constants
    for (idx in seq_along(real_args)) {
      if (is.null(real_args[[idx]])) {
        real_args[[idx]] <- Constant(matrix(0, imag_args[[idx]]@shape[1L],
                                            imag_args[[idx]]@shape[2L]))
      } else if (is.null(imag_args[[idx]])) {
        imag_args[[idx]] <- Constant(matrix(0, real_args[[idx]]@shape[1L],
                                            real_args[[idx]]@shape[2L]))
      }
    }
    return(list(expr_copy(expr, real_args), expr_copy(expr, imag_args)))
  }
}

## -- real_canon ----------------------------------------------------
c2r_real_canon <- function(expr, real_args, imag_args, real2imag) {
  if (is.null(real_args[[1L]])) {
    return(list(0L * imag_args[[1L]], NULL))
  } else {
    return(list(real_args[[1L]], NULL))
  }
}

## -- imag_canon ----------------------------------------------------
c2r_imag_canon <- function(expr, real_args, imag_args, real2imag) {
  if (is.null(imag_args[[1L]])) {
    return(list(0L * real_args[[1L]], NULL))
  } else {
    return(list(imag_args[[1L]], NULL))
  }
}

## -- conj_canon ----------------------------------------------------
c2r_conj_canon <- function(expr, real_args, imag_args, real2imag) {
  if (is.null(imag_args[[1L]])) {
    imag_arg <- NULL
  } else {
    imag_arg <- -imag_args[[1L]]
  }
  list(real_args[[1L]], imag_arg)
}

## -- hermitian_wrap_canon ------------------------------------------
c2r_hermitian_wrap_canon <- function(expr, real_args, imag_args, real2imag) {
  if (!is.null(imag_args[[1L]])) {
    imag_arg <- skew_symmetric_wrap(imag_args[[1L]])
  } else {
    imag_arg <- NULL
  }
  real_arg <- symmetric_wrap(real_args[[1L]])
  list(real_arg, imag_arg)
}

## -- join ----------------------------------------------------------
## Helper: combine two arguments via expr.copy([lh, rh])
.c2r_join <- function(expr, lh_arg, rh_arg) {
  if (is.null(lh_arg) || is.null(rh_arg)) {
    return(NULL)
  } else {
    return(expr_copy(expr, list(lh_arg, rh_arg)))
  }
}

## -- add -----------------------------------------------------------
## Helper: sum two arguments, negating rh if neg=TRUE
.c2r_add <- function(lh_arg, rh_arg, neg = FALSE) {
  if (!is.null(rh_arg) && neg) {
    rh_arg <- -rh_arg
  }
  if (is.null(lh_arg) && is.null(rh_arg)) {
    return(NULL)
  } else if (is.null(lh_arg)) {
    return(rh_arg)
  } else if (is.null(rh_arg)) {
    return(lh_arg)
  } else {
    return(lh_arg + rh_arg)
  }
}

## -- binary_canon --------------------------------------------------
## For multiplication-like operations:
## (a + bi)(c + di) = (ac - bd) + (ad + bc)i
c2r_binary_canon <- function(expr, real_args, imag_args, real2imag) {
  real_by_real <- .c2r_join(expr, real_args[[1L]], real_args[[2L]])
  imag_by_imag <- .c2r_join(expr, imag_args[[1L]], imag_args[[2L]])
  real_by_imag <- .c2r_join(expr, real_args[[1L]], imag_args[[2L]])
  imag_by_real <- .c2r_join(expr, imag_args[[1L]], real_args[[2L]])
  real_output <- .c2r_add(real_by_real, imag_by_imag, neg = TRUE)
  imag_output <- .c2r_add(real_by_imag, imag_by_real, neg = FALSE)
  list(real_output, imag_output)
}

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.