GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — For Eigen 5.0 add a missing element-wise pow() by eddelbuettel · Pull Request #9 · tsmodels/tsgarch

Conversation

@eddelbuettel

@eddelbuettel eddelbuettel commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Hi Alexios,

Eigen 5.0.0, which we are trying to bring to CRAN in an updated RcppEigen, apparently did away with a (scalar) pow() needed for your package to compile. (Also note that they changed the versioning scheme so Eigen 5.0.0 corresponds to 3.5.0 under the old scheme.) See RcppEigen issue 151 for all the changes related to this upgrade.

With assistance from Deepseek v4 flash-0731, a simple workaround was found. I have tested the workaround with both the CRAN version of RcppEigen (0.3.4.0.2, containing Eigen 3.4.0.2) and the 'release candidate' from our repo / from our r-universe (0.4.9.9.2, containing Eigen 5.0.1). I also ran a full R CMD check with all suggested packages against both RcppEigen versions. As the initial failure was plain installation / compilation, this should be sufficient.

Feel free to alter / adjust the PR as you see fit. I am not familiar with TMB and INLA and others using it may have found similar workaround. For your perusal I also include the summary from the large language model below.

So if you could apply this PR and get the update to CRAN before we update, a new RcppEigen would not break your package. If you don't update it we would get breakage 😞 but this PR overcomes this. We have been at this update for a long time as there were other issues in affected packages so the upload is not really imminent -- but getting closer. If you can get this to CRAN over the next few weeks we would appreciate it. 'Some time' in the near future will work, you can see at RcppEigen issue 151 how the other changes come in.

Thanks!


Summary for tsgarch changes

Porting tsgarch (R package for GARCH-family volatility models, built on TMB)
to Eigen 5.0.1 via the in-development RcppEigen 0.4.9.9.x (installed here;
baseline was RcppEigen 0.3.4.0.2 / Eigen 3.4.0.2).

Project summary

  • Imports: TMB (>= 1.7.20), Rcpp, nloptr, Rdpack, numDeriv, xts, zoo, plus
    tsmethods/tsdistributions/flextable/future/etc. LinkingTo: Rcpp, RcppEigen,
    TMB.
  • C++ is TMB model code under src/TMB/ (per-model *fun.hpp + shared
    garchextra.h, distfun.h, *kappa.h). Models are compiled by TMB
    (src/TMB/compile.R -> tsgarch_TMBExports.cpp ->
    tsgarch_TMBExports.so) via the package-specific src/Makevars.
  • tsgarch_TMBExports.cpp includes TMB.hpp, distfun.h, garchextra.h,
    then all model headers.
  • Model/helper Type is CppAD::AD<double> (TMB). TMB vector .pow() member
    is separate from the Eigen free pow().

The Eigen 5.0 API break (same as SpatialGEV)

Symptom

TMB compilation of tsgarch_TMBExports.cpp failed at src/TMB/garchextra.h
with:

no matching function for call to 'pow(const Eigen::CwiseBinaryOp<...>, CppAD::AD<double>)'
no type named 'type' in 'struct std::enable_if<false, ...>'

affecting the array-base pow(<array expr>, delta) calls in init_aparch /
init_fgarch:

  • garchextra.h:32,34,36 (lines in init_aparch) and
  • garchextra.h:55,57,59 (init_fgarch variant with eta).

Cause

Eigen 5.0 added a hard enable_if to the free pow(ArrayBase, ScalarExponent)
(in Eigen/src/Core/GlobalFunctions.h):

GlobalUnaryPowReturnType = std::enable_if_t<
    !is_arithmetic<NumTraits<Derived>::Real> &&
    is_arithmetic<NumTraits<ScalarExponent>::Real>,   // CppAD::AD<double> is NOT
    CwiseUnaryOp<scalar_unary_pow_op<...>>>;

For a TMB Type = CppAD::AD<double> exponent, NumTraits<AD<double>>::Real is
the non-arithmetic AD type, so the overload is SFINAE-removed. Eigen 3.x had no
such restriction. All OTHER pow() uses in the package are scalar-scalar
(pow(lambda, i), pow(fabs(u)-..., delta), pow(Type(2.0), ...), etc.) and
are NOT affected. Note x.pow(2.0) (member on tmbutils::vector) is a
different mechanism and also unaffected.

Fix

Added an elementwise pow_cwise(base, exponent) helper at the top of
src/TMB/garchextra.h (namespace garchextra) that builds the same
CwiseUnaryOp<scalar_unary_pow_op<...>> lazy expression the old free pow
produced, bypassing the new enable_if:

template <class Derived, class ExponentScalar>
inline Eigen::CwiseUnaryOp<Eigen::internal::scalar_unary_pow_op<typename Derived::Scalar, ExponentScalar>,
                           const Derived>
pow_cwise(const Eigen::ArrayBase<Derived>& x, const ExponentScalar& e) {
    typedef typename Derived::Scalar Scalar;
    return Eigen::CwiseUnaryOp<Eigen::internal::scalar_unary_pow_op<Scalar, ExponentScalar>, const Derived>(
        x.derived(), Eigen::internal::scalar_unary_pow_op<Scalar, ExponentScalar>(e));
}

Then replaced the 6 affected call sites in garchextra.h with pow_cwise(...).

Portability fix (IMPORTANT, do not regress)

The FIRST version of pow_cwise used Eigen::internal::scalar_unary_pow_op,
which is NEW in Eigen 5.0 and does NOT exist in the released RcppEigen
(Eigen 3.4). R CMD check/installDeps.r compile against the RELEASED
RcppEigen (Eigen 3.4), so the package failed again with:

garchextra.h:6:49: error: 'scalar_unary_pow_op' is not a member of 'Eigen::internal'; did you mean 'scalar_pow_op'?

There are TWO RcppEigen installs on this machine and the choice depends on the
tool:

  • /usr/lib/R/site-library/RcppEigen = RELEASED 0.3.4.0.2 / Eigen 3.4
    (used by R CMD check, installDeps.r/TMB tooling).
  • /usr/local/lib/R/site-library/RcppEigen = DEV 0.4.9.9-3 / Eigen 5.0.1
    (resolve via find.package("RcppEigen") in plain R).

So pow_cwise must compile under BOTH 3.4 and 5.0. Rewrote it portability using
unaryExpr + a lambda (auto return, C++14+; TMB compiles as gnu++17/20), which
is present in both versions:

template <class Derived, class ExponentScalar>
inline auto pow_cwise(const Eigen::ArrayBase<Derived>& x, const ExponentScalar& e) {
    typedef typename Derived::Scalar Scalar;
    return x.derived().unaryExpr([e](const Scalar& v) { return Eigen::numext::pow(v, e); });
}

unaryExpr lives in CommonCwiseUnaryOps.inc (common plugin) so it is available
on all dense expressions (arrays and matrices) in both Eigen versions.
Eigen::numext::pow(AD, AD) resolves via ADL to CppAD::pow.

Verification

  • Syntax-checked tsgarch_TMBExports.cpp (fsyntax-only) against BOTH:
    • released RcppEigen /usr/lib/... (Eigen 3.4): NO errors
    • dev RcppEigen /usr/local/... (Eigen 5.0.1): NO errors
  • Full TMB::compile (dev, Default) -> tsgarch_TMBExports.so (~20 MB), all
    models at AD/AD/AD<AD> tape depths.
  • R CMD INSTALL tsgarch (dev) -> * DONE (tsgarch); library(tsgarch) loads
    (v1.0.4).

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@eddelbuettel
For Eigen 5.0 add a missing element-wise pow()
4036176
@eddelbuettel eddelbuettel mentioned this pull request Oct 1, 2026
Transition to Eigen 5.0.* RcppCore/RcppEigen#151
Open
44 of 50 tasks
@eddelbuettel

eddelbuettel commented Oct 8, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor Author

I just learned in the other PR also suffering from the pow() change that this needs to be protect with a check for Eigen 5.0.0 or later -- which I will add shortly.

PS "Lucky us" -- it doesn't affect is here so there may have been an additional issue with the other package only.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@alexiosg
alexiosg merged commit 66e031d into tsmodels:main Oct 9, 2026
3 of 4 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@alexiosg

alexiosg commented Oct 9, 2026

Copy link
Copy Markdown
Member

Thanks Dirk! Much appreciated. This should also save me time on a new package I am writing which also uses RcppEigen.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@eddelbuettel

eddelbuettel commented Oct 9, 2026

Copy link
Copy Markdown
Contributor Author

Awesome, thanks for the two merged. I hope to get to CRAN "soon" but I may well be November given that a few other maintainers need to be nudged. But should hopefully be before the end of the year.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@eddelbuettel @alexiosg
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.