R/RcppExports.R

Defines functions zpm_cart gradzpm_cart norm_zpm zpmCP zpmC zapm_iso_128 zapm_128 zapm_iso zapm rzernike_ann gol_welsch tiltpsiC pwrap jac_frame res_frame rzernike readraw q_uw gpcapsiC aiapsiC lspsiC id_uw id_dxy_uw

Documented in aiapsiC gol_welsch gpcapsiC gradzpm_cart id_dxy_uw id_uw lspsiC norm_zpm q_uw rzernike rzernike_ann tiltpsiC zapm zapm_128 zapm_iso zapm_iso_128 zpmC zpm_cart

# Generated by using Rcpp::compileAttributes() -> do not edit by hand
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393

#' Compiled code via Rcpp for Itoh's method of phase unwrapping
#' 
#' Called by [brcutpuw()] for fast phase unwrapping
#' 
#' @param nr number of rows in phase matrix
#' @param nc number of columns in phase matrix
#' @param phase phase matrix converted to vector
#' @param mask matrix of mask values converted to vector
#' @param dx wrapped phase differences in x direction
#' @param dy wrapped phase differences in y direction
#' @return a vector with the unwrapped phase
#' @details
#'   This is called by [brcutpuw()] through [idiffpuw()] 
#'   but is also user callable.
#'   Wrapped phase values and differences are divided by \code{2*pi} before input
#'   making the input values in the range [-1/2, 1/2).
#'   In [brcutpuw()] the mask indicates areas outside the interferogram area
#'   and lines of branch cuts
#' @seealso [brcutpuw()], [idiffpuw()]
#' @author M.L. Peck (mlpeck54 -at- gmail.com)  
id_dxy_uw <- function(nr, nc, phase, mask, dx, dy, uw) {
    .Call(`_zernike_id_dxy_uw`, nr, nc, phase, mask, dx, dy, uw)
}

#' Compiled code via Rcpp for Itoh's method of phase unwrapping
#' 
#' Called by [idiffpuw()] for fast phase unwrapping
#' 
#' @param nr number of rows in phase matrix
#' @param nc number of columns in phase matrix
#' @param phase phase matrix converted to vector
#' @return a vector with the unwrapped phase
#' @details
#'   This is called by [idiffpuw()] 
#'   but is also user callable.
#'   Wrapped phase values are divided by \code{2*pi} before input
#'   making the input values in the range [-1/2, 1/2).
#'   In [brcutpuw()] the mask indicates areas outside the interferogram area
#'   and lines of branch cuts
#' @seealso [brcutpuw()], [idiffpuw()]
#' @author M.L. Peck (mlpeck54 -at- gmail.com)  
id_uw <- function(nr, nc, phase) {
    .Call(`_zernike_id_uw`, nr, nc, phase)
}

lspsiC <- function(images, phases, wt) {
    .Call(`_zernike_lspsiC`, images, phases, wt)
}

aiapsiC <- function(images, phases_init, ptol, maxiter, trace) {
    .Call(`_zernike_aiapsiC`, images, phases_init, ptol, maxiter, trace)
}

gpcapsiC <- function(images, ptol, maxiter, trace) {
    .Call(`_zernike_gpcapsiC`, images, ptol, maxiter, trace)
}

#' Compiled code via Rcpp for quality guided phase unwrapping
#' 
#' Called by [qpuw()] for fast quality guided phase unwrapping
#' 
#' @param nr number of rows in phase matrix
#' @param nc number of columns in phase matrix
#' @param phase phase matrix converted to vector
#' @param qual quality matrix converted to vector
#' @return a vector with the unwrapped phase
#' @details
#'   This is called by [qpuw()] but is also user callable.
#'   Wrapped phase values are divided by \code{2*pi} before input
#'   making the input values in the range [-1/2, 1/2).
#' @seealso [qpuw()], [idiffpuw()]
#' @author M.L. Peck (mlpeck54 -at- gmail.com)  
#'   with valuable programming advice from Steve Koehler
q_uw <- function(nr, nc, phase, qual) {
    .Call(`_zernike_q_uw`, nr, nc, phase, qual)
}

readraw <- function(fname, channels) {
    .Call(`_zernike_readraw`, fname, channels)
}

rzernike <- function(rho, n, m) {
    .Call(`_zernike_rzernike`, rho, n, m)
}

res_frame <- function(pars, adata) {
    .Call(`_zernike_res_frame`, pars, adata)
}

jac_frame <- function(pars, adata) {
    .Call(`_zernike_jac_frame`, pars, adata)
}

pwrap <- function(phase) {
    .Call(`_zernike_pwrap`, phase)
}

tiltpsiC <- function(images, phases_init, coords, ptol, maxiter, trace) {
    .Call(`_zernike_tiltpsiC`, images, phases_init, coords, ptol, maxiter, trace)
}

#' Golub-Welsch method to find quadrature points and weights for Gauss-Legendre quadrature
#'
#' Calculates the nodes and weights for Legendre polynomials shifted
#'   to the interval (eps^2, 1).
#'
#' @param eps obstruction fraction 0 <= eps < 1
#' @param qwts an input R vector with length equal to the number of quatrature points.
#'
#' @return a vector of quadrature nodes the same length as `qwts` in the open interval 
#'   (eps^2, 1). `qwts` will be overwritten with the quadrature weights.
#'
#' @details If N is the maximum polynomial order to be evaluated qwts should be at least
#'   of length N/2 + 1. Quadratures will then be nominally exact.
#'
#' @seealso Called by [zapm()] and [zapm_iso()].
gol_welsch <- function(eps, qwts) {
    .Call(`_zernike_gol_welsch`, eps, qwts)
}

#' Radial Zernike Annular polynomials
#'
#' Create a matrix of Zernike Annular polynomial values in
#' extended Fringe sequence for a set of polar coordinates.
#'
#' @param rho a vector of radial coordinates.
#' @param eps the obstruction fraction 0 <= eps < 1.
#' @param n the maximum radial order required
#' @param m azimuthal order
#' @param xq nodes for Gauss-Legendre quadrature
#' @param qwts weights for Gauss-Legendre quadrature
#'
#' @return A length(rho) x (n-m)/2+1 column matrix of radial Zernike Annular polynomial values evaluated at the input
#'  radial coordinates. The radial indexes are in increasing order from m, m+2, ..., n.
#'
#' @details To the author's knowledge no recurrence relations for radial Zernike annular polynomials
#'  have been published, even though several are well known for the closely related Zernike circle polynomials.
#'  However the m=0 polynomials representing axially symmetric aberrations are just shifted Legendre polynomials
#'  with an easily derived recurrence relation. This routine makes use of that fact to generate
#'  recurrence relations for arbitrary polynomial indexes using chebyshev's algorithm with modified moments.
#'  The modified moments are calculated using Gauss-Legendre quadrature. If enough quadrature nodes
#'  were chosen the quadrature is nominally exact, as are the resulting annular Zernike values.
#'
#' @seealso This function is called by [zapm()] and [zapm_iso()].
#'
#' @md
rzernike_ann <- function(rho, eps, n, m, xq, qwts) {
    .Call(`_zernike_rzernike_ann`, rho, eps, n, m, xq, qwts)
}

#' Zernike Annular polynomials
#'
#' Create a matrix of Zernike Annular polynomial values in
#' extended Fringe sequence for a set of polar coordinates.
#'
#' @param rho a vector of radial coordinates with eps <= rho <= 1.
#' @param theta a vector of angular coordinates, in radians.
#' @param eps the obstruction fraction 0 <= eps < 1.
#' @param maxorder the maximum radial polynomial order (defaults to 12).
#' @param nq the number of quadrature points for numerical integration
#'
#' @return a matrix of Zernike Annular polynomial values evaluated at the input
#'  polar coordinates and all radial orders from
#'  0 through `maxorder` in Fringe sequence, with orthonormal scaling.
#'
#' @details The *radial* polynomials are calculated using recurrence relations
#'  generated numerically using chebyshev's algorithm with modified moments.
#'  See the documentation for [rzernike_ann()]. A formal presentation is
#'  included in the package documentation.
#' @examples
#'   sample_az <- function(maxorder=12, eps=0.33, col=rev(zernike::rygcb(400)), addContours=TRUE, cscale=TRUE) {
#'   
#'     ## get coordinates for unobstructed and obstructed apertures
#'     cpa <- cp.default
#'     cpa$obstruct <- eps
#'     prt <- pupil.rhotheta(nrow.default,ncol.default,cp.default)
#'     prta <- pupil.rhotheta(nrow.default,ncol.default,cp=cpa)
#'     rho0 <- prt$rho[!is.na(prt$rho)]
#'     theta0 <- prt$theta[!is.na(prt$theta)]
#'     rhoa <- prta$rho[!is.na(prta$rho)]
#'     thetaa <- prta$theta[!is.na(prta$theta)]
#'     
#'     ## fill up matrixes of Zernikes and Annular Zernikes
#'     
#'     zm <- zpmC(rho0, theta0, maxorder=maxorder)
#'     zam <- zapm(rhoa, thetaa, eps=eps, maxorder=maxorder, nq=maxorder/2+5)
#'     
#'     ## pick a column at random and look up its index pair
#'     
#'     zlist <- makezlist(0, maxorder)
#'     i <- sample(2:ncol(zm), 1)
#'     n <- zlist$n[i]
#'     m <- zlist$m[i]
#'     
#'     ## fill up the wavefront representations and plot them
#'     
#'     wf0 <- prt$rho
#'     wf0[!is.na(wf0)] <- zm[,i]
#'     class(wf0) <- "pupil"
#'     
#'     wfa <- prta$rho
#'     wfa[!is.na(wfa)] <- zam[,i]
#'     class(wfa) <- "pupil"
#'     
#'     plot(wf0, cp=cp.default, col=col, addContours=addContours, cscale=cscale)
#'     mtext(paste("Zernike, n =", n, " m =", m))
#'     
#'     x11()
#'     plot(wfa, cp=cpa, col=col, addContours=addContours, cscale=cscale)
#'     mtext(paste("Annular Zernike, n =", n, " m =", m))
#'     
#'     ## return Zernike matrices and wavefronts invisibly
#'     ## just in case user wants to do something with them
#'     
#'     invisible(list(zm=zm, wf0=wf0, zam=zam, wfa=wfa))
#'   }
#'
#'   sample_az()
#'
#' @md
zapm <- function(rho, theta, eps, maxorder = 12L, nq = maxorder/2L + 5L) {
    .Call(`_zernike_zapm`, rho, theta, eps, maxorder, nq)
}

#' Zernike Annular polynomials, ISO ordering
#'
#' Create a matrix of Zernike Annular polynomial values in
#' ISO/ANSI sequence for a set of polar coordinates.
#'
#' @param rho a vector of radial coordinates with eps <= rho <= 1.
#' @param theta a vector of angular coordinates, in radians.
#' @param eps the obstruction fraction 0 <= eps < 1.
#' @param maxorder the maximum radial and azimuthal polynomial order (defaults to 12).
#' @param nq the number of quadrature points for numerical integration
#'
#' @return a matrix of Zernike Annular polynomial values evaluated at the input
#'  polar coordinates and all radial orders from
#'  0 through `maxorder` in ISO/ANSI sequence, with orthonormal scaling.
#'
#' @details The *radial* polynomials are calculated using recurrence relations
#'  generated numerically using chebyshev's algorithm with modified moments.
#'  See the documentation for [rzernike_ann()]. A formal presentation is
#'  included in the package documentation.
#'
#' @examples
#'   sample_az_iso <- function(maxorder=12, eps=0.33, col=rev(zernike::rygcb(400)), addContours=TRUE, cscale=TRUE) {
#'   
#'     ## get coordinates for unobstructed and obstructed apertures
#'     cpa <- cp.default
#'     cpa$obstruct <- eps
#'     prt <- pupil.rhotheta(nrow.default,ncol.default,cp.default)
#'     prta <- pupil.rhotheta(nrow.default,ncol.default,cp=cpa)
#'     rho0 <- prt$rho[!is.na(prt$rho)]
#'     theta0 <- prt$theta[!is.na(prt$theta)]
#'     rhoa <- prta$rho[!is.na(prta$rho)]
#'     thetaa <- prta$theta[!is.na(prta$theta)]
#'     
#'     ## fill up matrixes of Zernikes and Annular Zernikes
#'     
#'     zm <- zpm_cart(x=rho0*cos(theta0), y=rho0*sin(theta0), maxorder=maxorder)
#'     zam <- zapm_iso(rhoa, thetaa, eps=eps, maxorder=maxorder, nq=maxorder/2+5)
#'     
#'     ## pick a column at random and look up its index pair
#'     
#'     zlist <- makezlist.iso(maxorder)
#'     i <- sample(2:ncol(zm), 1)
#'     n <- zlist$n[i]
#'     m <- zlist$m[i]
#'     
#'     ## fill up the wavefront representations and plot them
#'     
#'     wf0 <- prt$rho
#'     wf0[!is.na(wf0)] <- zm[,i]
#'     class(wf0) <- "pupil"
#'     
#'     wfa <- prta$rho
#'     wfa[!is.na(wfa)] <- zam[,i]
#'     class(wfa) <- "pupil"
#'     
#'     plot(wf0, cp=cp.default, col=col, addContours=addContours, cscale=cscale)
#'     mtext(paste("Zernike, n =", n, " m =", m))
#'     
#'     x11()
#'     plot(wfa, cp=cpa, col=col, addContours=addContours, cscale=cscale)
#'     mtext(paste("Annular Zernike, n =", n, " m =", m))
#'     
#'     ## return Zernike matrices and wavefronts invisibly
#'     ## just in case user wants to do something with them
#'     
#'     invisible(list(zm=zm, wf0=wf0, zam=zam, wfa=wfa))
#'   }
#'
#'   sample_az_iso()
#'
#' @md
zapm_iso <- function(rho, theta, eps, maxorder = 12L, nq = maxorder/2L + 5L) {
    .Call(`_zernike_zapm_iso`, rho, theta, eps, maxorder, nq)
}

#' Zernike Annular polynomials, extended precision version
#'
#' Create a matrix of Zernike Annular polynomial values in
#' extended Fringe sequence for a set of polar coordinates.
#'
#' @param rho a vector of radial coordinates with eps <= rho <= 1.
#' @param theta a vector of angular coordinates, in radians.
#' @param eps the obstruction fraction 0 <= eps < 1.
#' @param maxorder the maximum radial polynomial order (defaults to 12).
#' @param nq the number of quadrature points for numerical integration
#'
#' @return a matrix of Zernike Annular polynomial values evaluated at the input
#'  polar coordinates and all radial orders from
#'  0 through `maxorder` in Fringe sequence, with orthonormal scaling.
#'
#' @details The *radial* polynomials are calculated using recurrence relations
#'  generated numerically using chebyshev's algorithm with modified moments.
#'  See the documentation for [rzernike_ann()]. A formal presentation is
#'  included in the package documentation.
#' @examples
#'   sample_az_128 <- function(maxorder=12, eps=0.33, col=rev(zernike::rygcb(400)), addContours=TRUE, cscale=TRUE) {
#'   
#'     ## get coordinates for unobstructed and obstructed apertures
#'     cpa <- cp.default
#'     cpa$obstruct <- eps
#'     prt <- pupil.rhotheta(nrow.default,ncol.default,cp.default)
#'     prta <- pupil.rhotheta(nrow.default,ncol.default,cp=cpa)
#'     rho0 <- prt$rho[!is.na(prt$rho)]
#'     theta0 <- prt$theta[!is.na(prt$theta)]
#'     rhoa <- prta$rho[!is.na(prta$rho)]
#'     thetaa <- prta$theta[!is.na(prta$theta)]
#'     
#'     ## fill up matrixes of Zernikes and Annular Zernikes
#'     
#'     zm <- zpmC(rho0, theta0, maxorder=maxorder)
#'     zam <- zapm_128(rhoa, thetaa, eps=eps, maxorder=maxorder, nq=maxorder/2+5)
#'     
#'     ## pick a column at random and look up its index pair
#'     
#'     zlist <- makezlist(0, maxorder)
#'     i <- sample(2:ncol(zm), 1)
#'     n <- zlist$n[i]
#'     m <- zlist$m[i]
#'     
#'     ## fill up the wavefront representations and plot them
#'     
#'     wf0 <- prt$rho
#'     wf0[!is.na(wf0)] <- zm[,i]
#'     class(wf0) <- "pupil"
#'     
#'     wfa <- prta$rho
#'     wfa[!is.na(wfa)] <- zam[,i]
#'     class(wfa) <- "pupil"
#'     
#'     plot(wf0, cp=cp.default, col=col, addContours=addContours, cscale=cscale)
#'     mtext(paste("Zernike, n =", n, " m =", m))
#'     
#'     x11()
#'     plot(wfa, cp=cpa, col=col, addContours=addContours, cscale=cscale)
#'     mtext(paste("Annular Zernike, n =", n, " m =", m))
#'     
#'     ## return Zernike matrices and wavefronts invisibly
#'     ## just in case user wants to do something with them
#'     
#'     invisible(list(zm=zm, wf0=wf0, zam=zam, wfa=wfa))
#'   }
#'
#'   sample_az_128()
#'
#' @md
zapm_128 <- function(rho, theta, eps, maxorder = 12L, nq = maxorder/2L + 5L) {
    .Call(`_zernike_zapm_128`, rho, theta, eps, maxorder, nq)
}

#' Zernike Annular polynomials, ISO ordering - extended precision version
#'
#' Create a matrix of Zernike Annular polynomial values in
#' ISO/ANSI sequence for a set of polar coordinates.
#'
#' @param rho a vector of radial coordinates with eps <= rho <= 1.
#' @param theta a vector of angular coordinates, in radians.
#' @param eps the obstruction fraction 0 <= eps < 1.
#' @param maxorder the maximum radial and azimuthal polynomial order (defaults to 12).
#' @param nq the number of quadrature points for numerical integration
#'
#' @return a matrix of Zernike Annular polynomial values evaluated at the input
#'  polar coordinates and all radial orders from
#'  0 through `maxorder` in ISO/ANSI sequence, with orthonormal scaling.
#'
#' @details The *radial* polynomials are calculated using recurrence relations
#'  generated numerically using chebyshev's algorithm with modified moments.
#'  See the documentation for [rzernike_ann()]. A formal presentation is
#'  included in the package documentation.
#'
#' @examples
#'   sample_az_iso_128 <- function(maxorder=12, eps=0.33, col=rev(zernike::rygcb(400)), addContours=TRUE, cscale=TRUE) {
#'   
#'     ## get coordinates for unobstructed and obstructed apertures
#'     cpa <- cp.default
#'     cpa$obstruct <- eps
#'     prt <- pupil.rhotheta(nrow.default,ncol.default,cp.default)
#'     prta <- pupil.rhotheta(nrow.default,ncol.default,cp=cpa)
#'     rho0 <- prt$rho[!is.na(prt$rho)]
#'     theta0 <- prt$theta[!is.na(prt$theta)]
#'     rhoa <- prta$rho[!is.na(prta$rho)]
#'     thetaa <- prta$theta[!is.na(prta$theta)]
#'     
#'     ## fill up matrixes of Zernikes and Annular Zernikes
#'     
#'     zm <- zpm_cart(x=rho0*cos(theta0), y=rho0*sin(theta0), maxorder=maxorder)
#'     zam <- zapm_iso_128(rhoa, thetaa, eps=eps, maxorder=maxorder, nq=maxorder/2+5)
#'     
#'     ## pick a column at random and look up its index pair
#'     
#'     zlist <- makezlist.iso(maxorder)
#'     i <- sample(2:ncol(zm), 1)
#'     n <- zlist$n[i]
#'     m <- zlist$m[i]
#'     
#'     ## fill up the wavefront representations and plot them
#'     
#'     wf0 <- prt$rho
#'     wf0[!is.na(wf0)] <- zm[,i]
#'     class(wf0) <- "pupil"
#'     
#'     wfa <- prta$rho
#'     wfa[!is.na(wfa)] <- zam[,i]
#'     class(wfa) <- "pupil"
#'     
#'     plot(wf0, cp=cp.default, col=col, addContours=addContours, cscale=cscale)
#'     mtext(paste("Zernike, n =", n, " m =", m))
#'     
#'     x11()
#'     plot(wfa, cp=cpa, col=col, addContours=addContours, cscale=cscale)
#'     mtext(paste("Annular Zernike, n =", n, " m =", m))
#'     
#'     ## return Zernike matrices and wavefronts invisibly
#'     ## just in case user wants to do something with them
#'     
#'     invisible(list(zm=zm, wf0=wf0, zam=zam, wfa=wfa))
#'   }
#'
#'   sample_az_iso_128()
#'
#' @md
zapm_iso_128 <- function(rho, theta, eps, maxorder = 12L, nq = maxorder/2L + 5L) {
    .Call(`_zernike_zapm_iso_128`, rho, theta, eps, maxorder, nq)
}

zpmC <- function(rho, theta, maxorder = 12L) {
    .Call(`_zernike_zpmC`, rho, theta, maxorder)
}

zpmCP <- function(rho, theta, maxorder) {
    .Call(`_zernike_zpmCP`, rho, theta, maxorder)
}

#' Normalize matrix of Zernike polynomial values.
#'
#' Convert a matrix of Zernike polynomial values from
#' unit scaled to unit variance aka orthonormal form.
#'
#' @param uzpm matrix of Zernike polynomial values
#' @param maxorder the maximum radial order.
#'
#' @return matrix in orthonormal form.
#'
#' @details
#'  This is intended only for ISO/ANSI ordered matrices. The
#'  only check performed is that the number of columns in the
#'  matrix matches the expected number given by the argument
#'  `maxorder`.
#'  This is called by [gradzpm_cart()] and [zpm_cart()]
#'  if `unit_variance` is set to `true` in the respective
#'  function calls.
#' @md
norm_zpm <- function(uzpm, maxorder = 12L) {
    .Call(`_zernike_norm_zpm`, uzpm, maxorder)
}

#' Zernike polynomials and cartesian gradients
#'
#' Calculate Zernike polynomial values and Cartesian gradients in
#' ISO/ANSI sequence for a set of Cartesian coordinates.
#'
#' @param x a vector of x coordinates for points on a unit disk.
#' @param y a vector of y coordinates.
#' @param maxorder the maximum radial polynomial order (defaults to 12).
#' @param unit_variance logical: return with orthonormal scaling? (default `false`)
#' @param return_zpm logical: return Zernike polynomial matrix? (default `true`)
#'
#' @return a named list with the matrices `zm` (optional but returned by default), `dzdx`, `dzdy`.
#'
#' @references
#'   Anderson, T.B. (2018) Optics Express 26, #5, 18878
#'   <https://doi.org/10.1364/OE.26.018878> (open access)
#'
#' @details
#'  Uses the recurrence relations in the above publication to calculate Zernike
#'  polynomial values and their directional derivatives in Cartesian coordinates. These are
#'  known to be both efficient and numerically stable.
#'
#'  Columns are in ISO/ANSI sequence: for each radial order n >= 0 the azimuthal orders m are sequenced
#'  m = {-n, -(n-2), ..., (n-2), n}, with sine components for negative m and cosine for positive m. Note this
#'  is the opposite ordering from the extended Fringe set and the ordering of aberrations is quite different. 
#'  For example the two components of trefoil are in the 7th and 10th column while coma is in
#'  columns 8 and 9 (or 7 and 8 with 0-indexing). Note also that except for tilt and coma-like aberrations
#'  (m=1) non-axisymmetric aberrations will be separated.
#'
#'  All three matrices will have the same dimensions on return. Columns 0 and 1 of `dzdx` will be all 0,
#'  while columns 0 and 2 of `dzdy` are 0.
#'
#' @seealso [zpm()] uses the same recurrence relations for polar coordinates and extended
#'  Fringe set ordering, which is the more common indexing scheme for optical design/testing
#'  software.
#' @seealso [zpm_cart()] calculates and returns the Zernike polynomial values only.
#'
#' @examples
#'  rho <- seq(0.2, 1., length=5)
#'  theta <- seq(0, 1.6*pi, length=5)
#'  rt <- expand.grid(theta, rho)
#'  x <- c(0, rt[,2]*cos(rt[,1]))
#'  y <- c(0, rt[,2]*sin(rt[,1]))
#'  gzpm <- gradzpm_cart(x, y)
#'
#' @md
gradzpm_cart <- function(x, y, maxorder = 12L, unit_variance = FALSE, return_zpm = TRUE) {
    .Call(`_zernike_gradzpm_cart`, x, y, maxorder, unit_variance, return_zpm)
}

#' Zernike polynomials
#'
#' Calculate Zernike polynomial values in
#' ISO/ANSI sequence for a set of Cartesian coordinates.
#'
#' @param x a vector of x coordinates for points on a unit disk.
#' @param y a vector of y coordinates.
#' @param maxorder the maximum radial polynomial order (defaults to 12).
#' @param unit_variance logical: return with orthonormal scaling? (default `true`)
#'
#' @return a matrix of Zernike polynomial values evaluated at the input
#'  Cartesian coordinates and all radial and azimuthal orders from
#'  0 through `maxorder`.
#'
#' @details This is the same algorithm and essentially the same code as [gradzpm_cart()]
#'  except directional derivatives aren't calculated.
#'
#' @examples
#'   ##illustrates difference in smoothed wavefront from using zpm_cart with ISO sequence of same order
#'
#'   require(zernike)
#'   fpath <- file.path(find.package(package="zernike"), "psidata")
#'   files <- scan(file.path(fpath, "files.txt"), what="character")
#'   for (i in 1:length(files)) files[i] <- file.path(fpath, files[i])
#'   
#'   ## load the images into an array
#'   
#'   images <- load.images(files)
#'   
#'   ## parameters for this run
#'   
#'   source(file.path(fpath, "parameters.txt"))
#'   
#'   ## phase shifts
#'   
#'   phases <- wrap((0:(dim(images)[3]-1))/frames.per.cycle*2*pi)
#'   phases <- switch(ps.dir, ccw = -phases, cw = phases, phases)
#'   
#'   ## target SA coefficients for numerical null.
#'   
#'   sa.t <- sconic(diam,roc,lambda=wavelength)
#'   zopt <- psfit_options()
#'   zopt$satarget <- sa.t
#'   psfit <- psifit(images, phases, psialg="ls", options=zopt)
#'   
#'   ## get back the raw wavefront
#'   
#'   wf.raw <- qpuw(psfit$phi, psfit$mod)
#'   
#'   ## This will tell wf_net to use zpm_cart instead
#'   
#'   zopt$isoseq <- TRUE
#'   ifit <- wf_net(wf.raw, cp = psfit$cp, options=zopt)
#'   
#'   ## plotn does a direct comparison
#'   
#'   plotn(psfit, ifit, wftype="smooth", qt=c(0,1))
#'
#' @md
zpm_cart <- function(x, y, maxorder = 12L, unit_variance = TRUE) {
    .Call(`_zernike_zpm_cart`, x, y, maxorder, unit_variance)
}
mlpeck/zernike documentation built on April 19, 2024, 3:16 p.m.