From 5e682edfdf180ce5ba0d2f682474a075d85a175e Mon Sep 17 00:00:00 2001
From: "Joachim Wuttke (o)" <j.wuttke@fz-juelich.de>
Date: Thu, 5 Nov 2015 13:53:55 +0100
Subject: [PATCH] Corr error propagation in 'pow'. New perf test oyd1a

---
 pub/lib/fbase.cpp   | 20 ++++++++++++++------
 pub/ptest/oyd1a.f2t | 17 +++++++++++++++++
 2 files changed, 31 insertions(+), 6 deletions(-)
 create mode 100755 pub/ptest/oyd1a.f2t

diff --git a/pub/lib/fbase.cpp b/pub/lib/fbase.cpp
index 62c518fb..f85f9fcc 100644
--- a/pub/lib/fbase.cpp
+++ b/pub/lib/fbase.cpp
@@ -204,14 +204,22 @@ int func_idiv(double v, int a) { return a!=0 ? (int)(ceil(v)+0.5)/a : 0; }
 int func_mod(int v, int a) { return v%a; }
 double func_mod(double v, double a) { return fmod(v,a); }
 
-double func_pow(double v, double a)
-{ return ( v>0 || (v==0&&a>0) || a==(int)a ) ? pow(v,a) : 0; }
-void func_pow(double& r, double& dr, double v, double dv, double a, double da)
+double func_pow(double a, double b)
+{ return ( a>0 || (a==0&&b>0) || b==(int)b ) ? pow(a,b) : 0; }
+void func_pow(double& r, double& dr, double a, double da, double b, double db)
 {
-    if ( v>0 || (v==0&&a>0) || a==(int)a ) {
-        r = pow(v,a); dr = sqrt( SQR(a*r/v) + SQR(log(v)*a) );
+    if ( a>0 ) {
+        r = pow(a,b);
+        dr = r*b/a*sqrt(SQR(da)+SQR(db));
+    } else if ( a==0 && b>0 ) {
+        r = pow(a,b);
+        dr = b*pow(a,b-1)*db;
+    } else if ( b==(int)b ) {
+        r = pow(a,b);
+        dr = r*b/a*da;
     } else {
-        r = 0; dr = 0;
+        r = 0;
+        dr = 0;
     }
 }
 
diff --git a/pub/ptest/oyd1a.f2t b/pub/ptest/oyd1a.f2t
new file mode 100755
index 00000000..8b50b130
--- /dev/null
+++ b/pub/ptest/oyd1a.f2t
@@ -0,0 +1,17 @@
+#!/usr/bin/env frida
+fm 34000 100 h
+oy! sqrt(1+j+i)
+oy! y+-sqrt(y)
+oy y^2
+oy! sqrt(y)
+oy ln(y)
+oy! exp(y)
+oy y*7+42
+oy! (y-42)/7
+exit_unless(abs(y[0,7,77]-y[1,7,77])<1e-12,"y_changed_1")
+exit_unless(abs(y[0,7,77]-y[2,7,77])<1e-12,"y_changed_2")
+exit_unless(abs(y[0,7,77]-y[3,7,77])<1e-12,"y_changed_3")
+exit_unless(abs(dy[0,7,77]-dy[1,7,77])<1e-10,"dy_changed_1")
+exit_unless(abs(dy[0,7,77]-dy[2,7,77])<1e-10,"dy_changed_2")
+exit_unless(abs(dy[0,7,77]-dy[3,7,77])<1e-10,"dy_changed_3")
+exit(0)
\ No newline at end of file
-- 
GitLab