Blob Blame History Raw
From 5d37981978494681a6e55224ac6e6f765eb59edb Mon Sep 17 00:00:00 2001
From: Roberto Di Remigio <roberto.diremigio@gmail.com>
Date: Mon, 23 Aug 2021 08:23:23 +0200
Subject: [PATCH] Always use a temporary of large enough size

Should fix #151
---
 src/functionals/brx.cpp | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/functionals/brx.cpp b/src/functionals/brx.cpp
index 260a0ed..acaaafc 100644
--- a/src/functionals/brx.cpp
+++ b/src/functionals/brx.cpp
@@ -50,11 +50,15 @@ static double BR(double z) {
 // Obtain the Taylor expansion of x(y), which is the
 // inverse of BR_y. Use linear method for simplicity.
 template <typename T, int Ndeg>
-void BR_taylor(const T & z0, taylor<T, 1, Ndeg> & t) {
-  taylor<T, 1, Ndeg> f, d;
+taylor <T, 1, Ndeg> BR_taylor(const T & z0) {
+  static_assert(Ndeg >= 3);
+
+  taylor<T, 1, Ndeg> t;
   t = 0;
   t[0] = BR(z0);
   t[1] = 1;
+
+  taylor<T, 1, Ndeg> f;
   f = BR_z(t);
   t[1] = 1 / f[1];
   // Linear method, for quadratic see i.e. Brent & Kung ~197x
@@ -62,6 +66,8 @@ void BR_taylor(const T & z0, taylor<T, 1, Ndeg> & t) {
     f = BR_z(t);
     t[i] = -f[i] * t[1];
   }
+
+  return t;
 }
 
 /* This is a fully differentiable solver for Eq.(21) in
@@ -70,8 +76,9 @@ void BR_taylor(const T & z0, taylor<T, 1, Ndeg> & t) {
  */
 template <typename T, int Nvar>
 static ctaylor<T, Nvar> BR(const ctaylor<T, Nvar> & t) {
-  taylor<T, 1, Nvar> tmp;
-  BR_taylor(t.c[0], tmp);
+  // temporary has dimension 3 at least. See: https://github.com/dftlibs/xcfun/issues/151
+  // in C++14 and later can use std::max(Nvar, 3) for the second template argument
+  auto tmp = BR_taylor<T, (Nvar >= 3) ? Nvar : 3>(t.c[0]);
 
   ctaylor<T, Nvar> res = tmp[0];
   for (int i = 1; i <= Nvar; i++)