From c4bc4dcc98c44ef9eec6d0c97994bbaefde71057 Mon Sep 17 00:00:00 2001 From: saruman Date: Sat, 16 Nov 2019 21:05:32 +0100 Subject: [PATCH] added abs() function --- source/dualnumbers.d | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/source/dualnumbers.d b/source/dualnumbers.d index 38bc926..6a579b6 100644 --- a/source/dualnumbers.d +++ b/source/dualnumbers.d @@ -449,6 +449,43 @@ unittest assert(res.du.approxEqual(3 * res.re)); } +/** Abs function on dual numbers. + + Params: x = A dual number. + Returns: |x| +*/ +Dual!T abs(T)(Dual!T x) @safe pure nothrow @nogc +{ + import std.math: signbit; + if (signbit(x.re)) + return -x; + else + return x; +} + +/// +unittest +{ + import std.math: approxEqual; + // f(x) = |x|, f'(x) = 1 when x positive + auto x = dual(2.0, 1.0); + auto result = abs(x); + assert(approxEqual(result.re, 2.0) && approxEqual(result.du, 1.0)); + + // f'(x) = -1 when x negative + x = dual(-2.0, 1.0); + result = abs(x); + assert(approxEqual(result.re, 2.0) && approxEqual(result.du, -1.0)); + + // because floating point numbers have -0 and +0 f'(x) is defined for x = 0 + x = dual(0.0, 1.0); + result = abs(x); + assert(approxEqual(result.du, 1.0)); + x = dual(-0.0, 1.0); + result = abs(x); + assert(approxEqual(result.du, -1.0)); +} + /* Test constructors */ // Works with floating point types