The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

libimath

R-CMD-check

Static build of Academy Software Foundation’s Imath C++ library for R. Imath is a basic, light-weight, and efficient C++ representation of 2D and 3D vectors, matrices, and other mathematical objects, functions, and data types common in computer graphics applications, including the half 16-bit floating-point type. It is not a generic linear algebra library (such as Eigen), but rather one specialized for 2D and 3D transformations common in computer graphics.

The installed package includes a static copy of the C++ library (along with CMake config files) so you can use Imath functionality in your package without requiring the user to separately install Imath as a system dependency. This package does not provide an R API–rather, it simply makes the Imath C++ library available to other R packages.

Imath is maintained by the OpenEXR project, a part of the Academy Software Foundation (ASWF).

Features

The Imath library provides:

For detailed information on the Imath API, please refer to the Imath documentation.


Installation

# once released on CRAN
install.packages("tylermorganwall/libimath")

# development version
remotes::install_github("tylermorganwall/libimath")

No external libraries are required—the Imath static library is built and installed during the R package install.


Using the bundled static library in your own packages

The package installs:

lib/<R_ARCH>/libImath-3_2.a        # static archive (version 3.2)
lib/<R_ARCH>/cmake/Imath/*         # CMake config files
include/Imath/*                    # public headers

R_ARCH can be obtained in R via Sys.info()[["machine"]].

Makevars-style linkage

The version (3_2) is appended after the library name: add this to link the static library.

## configure
IMATH_DIR=$(Rscript -e 'cat(system.file("lib", Sys.info()[["machine"]], package = "libimath"))')
CPPFLAGS += -I$(IMATH_DIR)/../include
PKG_LIBS += -L$(IMATH_DIR) -lImath-3_2

CMake consumers

Call this R code in your configure step to determine the location of the CMake config files:

IMATH_LIB_ARCH = normalizePath(sprintf(
  "%s/%s",
  system.file(
    "lib",
    package = "libimath",
    mustWork = TRUE
  ),
  Sys.info()[["machine"]]
))

IMATH_CMAKE_CONFIG = file.path(IMATH_LIB_ARCH, "cmake", "Imath")

Minimal example

Below is a minimal example showing how to use this library with R.

#define R_NO_REMAP

#include <R.h>
#include <Rinternals.h>
#include <R_ext/Rdynload.h>
#include <R_ext/Print.h> 

#include <Imath/ImathMatrix.h>
#include <Imath/ImathVec.h>

/**
 * Rotates a 3D point using Imath's matrix operations
 * 
 * @param point An R numeric vector with 3 elements (x, y, z)
 * @param angles An R numeric vector with 3 elements (rotation angles in radians)
 * @return The rotated point as an R numeric vector
 */
extern "C" SEXP imath_rotate_point(SEXP point, SEXP angles) {
    // Validate inputs
    if (TYPEOF(point) != REALSXP || LENGTH(point) != 3) {
        Rf_error("'point' must be a numeric vector of length 3");
    }
    if (TYPEOF(angles) != REALSXP || LENGTH(angles) != 3) {
        Rf_error("'angles' must be a numeric vector of length 3");
    }
    
    // Extract point coordinates
    double *point_ptr = REAL(point);
    Imath::V3f p((float)point_ptr[0], (float)point_ptr[1], (float)point_ptr[2]);
    
    // Extract rotation angles
    double *angles_ptr = REAL(angles);
    Imath::V3f rot((float)angles_ptr[0], (float)angles_ptr[1], (float)angles_ptr[2]);
    
    // Create identity matrix
    Imath::M44f M;
    M.makeIdentity();
    
    // Create rotation matrix
    Imath::M44f R;
    R.makeIdentity();
    R.rotate(rot);
    
    // Apply rotation
    M = R * M;
    
    // Transform the point
    Imath::V3f result;
    M.multVecMatrix(p, result);
    
    // Create and populate result vector
    SEXP r_result = PROTECT(Rf_allocVector(REALSXP, 3));
    REAL(r_result)[0] = (double)result.x;
    REAL(r_result)[1] = (double)result.y;
    REAL(r_result)[2] = (double)result.z;
    
    // Add names to result vector for R
    SEXP names = PROTECT(Rf_allocVector(STRSXP, 3));
    SET_STRING_ELT(names, 0, Rf_mkChar("x"));
    SET_STRING_ELT(names, 1, Rf_mkChar("y"));
    SET_STRING_ELT(names, 2, Rf_mkChar("z"));
    Rf_setAttrib(r_result, R_NamesSymbol, names);
    
    UNPROTECT(2);
    return r_result;
}

//=== registration ===========================================================

static const R_CallMethodDef CallEntries[] = {
    {"imath_rotate_point", (DL_FUNC) &imath_rotate_point, 2},
    {NULL, NULL, 0}
};

void R_init_libimathwrapper(DllInfo *dll) {
    R_registerRoutines(dll, NULL, CallEntries, NULL, NULL);
    R_useDynamicSymbols(dll, FALSE);
}

And the R code calling this function:

#' Rotate Point
#'
#' @param point A length-3 numeric vector (x, y, z)
#' @param angles A length-3 numeric vector (rotation angles in radians)
#' @return The rotated point as an R numeric vector
#' @export
#' @examples
#' # This rotates a point around an angle.
#' point = c(1.0, 0.0, 0.0)
#' angles = c(0.0, pi/4, 0.0)
#' imath_rotate_point(point, angles)
imath_rotate_point = function(point, angles) {
  rotated = .Call(
    "imath_rotate_point",
    point,
    angles,
    PACKAGE = "libimath"
  )
  return(rotated)
}

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.