1 /** 2 Internal test utilities. 3 Use flags -unittest -debug=libcerf to receive debug info. 4 5 Copyright: 6 © 2012 Massachusetts Institute of Technology, 7 © 2013 Forschungszentrum Jülich GmbH, 8 © 2014 Ilya Yaroshenko 9 10 Authors: 11 Steven G. Johnson, core author; 12 Joachim Wuttke, C package maintainer; 13 $(LINK2 http://plus.google.com/+IlyaYaroshenko, Ilya Yaroshenko), D package maintainer 14 15 License: 16 Subject to the terms of the MIT license, as written in the included LICENSE.txt file. 17 */ 18 module libcerf.testutils; 19 20 import std.complex; 21 import std.math : isNaN, isInfinity, isFinite; 22 import core.stdc.math : fabs; 23 24 debug(libcerf) 25 { 26 import std.traits : fullyQualifiedName; 27 import std.stdio : writefln; 28 } 29 30 import core.stdc.math : pow, erfc; 31 32 package: 33 34 /// 35 bool relativeErrorCheck(double a, double b) 36 @safe nothrow @nogc 37 { 38 if(a.isNaN) 39 { 40 return b.isNaN; 41 } 42 if(a.isInfinity) 43 { 44 return b == a; 45 } 46 if(a == 0) 47 { 48 return fabs(b) < 1e-13; 49 } 50 return fabs((b-a) / a) < 1e-13; 51 } 52 53 /// 54 bool relativeErrorCheck(Complex!double a, Complex!double b) 55 @safe nothrow @nogc 56 { 57 return relativeErrorCheck(a.re, b.re) && relativeErrorCheck(a.im, b.im); 58 } 59 60 /// 61 void commonTest(alias cfun)(in Complex!double[] Z, in Complex!double[] W) 62 { 63 debug(libcerf){ 64 enum name = fullyQualifiedName!cfun; 65 writefln("%s common tests...", name); 66 scope (success) 67 writefln("%s common tests success", name); 68 } 69 assert(W.length == Z.length); 70 foreach(i; 0..Z.length) { 71 immutable z = Z[i]; 72 immutable w = W[i]; 73 immutable f = cfun(z); 74 auto e = f-w; 75 e.re /= w.re; 76 e.im /= w.im; 77 debug(libcerf) 78 writefln("%s(%s) = %s, vs. %s, rel. err. = %s)", name, z, f, w, e); 79 assert(relativeErrorCheck(w, f)); 80 } 81 } 82 83 /// 84 void specialTest(alias cfun, alias fun, double C)() 85 { 86 debug(libcerf){ 87 enum name = fullyQualifiedName!cfun; 88 writefln("%s special tests...", name); 89 scope (success) 90 writefln("%s special tests success", name); 91 } 92 foreach (i; 0..10000) 93 { 94 immutable x = pow(10., -300. + i * 600. / (10000 - 1)); 95 assert(relativeErrorCheck(fun(+x), cfun(Complex!double(+x,x*C)).re)); 96 assert(relativeErrorCheck(fun(-x), cfun(Complex!double(-x,x*C)).re)); 97 } 98 assert(relativeErrorCheck(fun(double.infinity), cfun(Complex!double(double.infinity,0.)).re)); 99 assert(relativeErrorCheck(fun(-double.infinity), cfun(Complex!double(-double.infinity,0.)).re)); 100 assert(relativeErrorCheck(fun(double.nan), cfun(Complex!double(double.nan,0.)).re)); 101 }