#!/usr/bin/env ruby require("gsl") require("../gsl_test2.rb") include GSL::Test include Math module GSL module Test module Sf TEST_TOL0 = 2.0*GSL::DBL_EPSILON TEST_TOL1 = 16.0*GSL::DBL_EPSILON TEST_TOL2 = 256.0*GSL::DBL_EPSILON TEST_TOL3 = 2048.0*GSL::DBL_EPSILON TEST_TOL4 = 16384.0*GSL::DBL_EPSILON TEST_TOL5 = 131072.0*GSL::DBL_EPSILON TEST_TOL6 = 1048576.0*GSL::DBL_EPSILON TEST_SQRT_TOL0 = 2.0*GSL::SQRT_DBL_EPSILON TEST_SNGL = 1.0e-06 TEST_SF_INCONS = 1 TEST_SF_ERRNEG = 2 TEST_SF_TOLBAD = 4 TEST_SF_RETBAD = 8 TEST_FACTOR = 100.0 TEST_SIGMA = 1.5 def test_sf_frac_diff(x1, x2) if x1.zero? and x2.zero? return 0.0 elsif x1 <= DBL_MAX and x2 < DBL_MAX and (x1 + x1 != 0.0) return ((x1 - x2)/(x1 + x2)).abs else return 1.0 end end def test_sf_check_result(mbuf, r, val, tol) s = 0 f = 0.0 if isnan?(r.val) or isnan?(val) s = isnan(r.val) != isnan(val) ? TEST_SF_INCONS : s elsif isinf?(r.val) or isinf?(val) s = isinf(r.val) != isinf(val) ? TEST_SF_INCONS : s else f = test_sf_frac_diff(val, r.val) if (val - r.val).abs > 2.0*TEST_SIGMA*r.err s |= TEST_SF_INCONS end if r.err < 0.0 s |= TEST_SF_ERRNEG end if f > TEST_FACTOR * tol s |= TEST_SF_TOLBAD end end if s != 0 message = sprintf(" expected: %20.16g\n", val) mbuf += message message = sprintf(" obtained: %20.16g %20.16g %g\n", r.val, r.err, r.err/(r.val.abs + r.err)) mbuf += message message = sprintf(" fracdiff: %20.16g\n", f) mbuf += message end if s & TEST_SF_INCONS mbuf += " value/expected not consistent within reported error\n" end if s & TEST_SF_ERRNEG mbuf += " reported error negative\n" end if s & TEST_SF_TOLBAD mbuf += " value not within tolerance of expected value\n" end return s, mbuf end def test_sf_check_val(mbuf, rval, val, tol) s = 0; f = test_sf_frac_diff(val, rval) if f > TEST_FACTOR * tol s |= TEST_SF_TOLBAD end if s != 0 buf = sprintf(" expected: %20.16g\n", val) mbuf += buf buf = sprintf(" obtained: %20.16g\n", rval) mbuf += buf buf = sprintf(" fracdiff: %20.16g\n", f) mbuf += buf end if s & TEST_SF_TOLBAD mbuf += " value not within tolerance of expected value\n" end return s, mbuf end def test_sf_check_result_relax(mbuf, r, val, tol) s = 0; f = test_sf_frac_diff(val, r.val) if f > GSL_MAX_DBL(TEST_SNGL, TEST_FACTOR * tol) s |= TEST_SF_INCONS end if r.err < 0.0 s |= TEST_SF_ERRNEG end if f > TEST_FACTOR * tol s |= TEST_SF_TOLBAD end if s != 0 buf = sprintf(" expected: %20.16g\n", val) mbuf += buf buf = sprintf(" obtained: %20.16g %20.16g %g\n", r.val, r.err, r.err/(r.val.abs + r.err)) mbuf += buf buf = sprintf(" fracdiff: %20.16g\n", f) mbuf += buf end if s & TEST_SF_INCONS mbuf += " value/expected not consistent MAX(tol,SINGLE_PREC)\n" end if s & TEST_SF_ERRNEG mbuf += " reported error negative\n" end if s & TEST_SF_TOLBAD mbuf += " value not within tolerance of expected value\n" end return s, mbuf end def test_sf_check_return(mbuf, val, expected) if val != expected buf = sprintf(" unexpected return code: %d\n", val) mbuf += buf return TEST_SF_RETBAD, mbuf else return 0, mbuf end end def test_sf(r, val, tol, status, expect, desc) local_s = 0 mbuf = "" s, mbuf = test_sf_check_result(mbuf, r, val, tol) local_s |= s s, mbuf = test_sf_check_return(mbuf, status, expect) local_s |= s GSL::Test::test(local_s, desc) if local_s != 0 print(mbuf) printf(" %22.18g %22.18g\n", r.val, r.err) end return local_s end def test_sf_val(val, val_in, tol, desc) local_s = 0 mbuf = "" s, mbuf = test_sf_check_val(mbuf, val, val_in, tol) local_s |= s GSL::Test::test(local_s, desc) if local_s != 0 printf("%s", mbuf) printf(" %22.18g\n", val) end return local_s end def test_sf_rlx(r, val_in, tol, status, expect_return, desc) local_s = 0 message_buff = "" s, message_buff = test_sf_check_result_relax(message_buff, r, val_in, tol) local_s |= s s, message_buff = test_sf_check_return(message_buff, status, expect_return) local_s |= s GSL::Test::test(local_s, desc) if local_s != 0 printf("%s", message_buff) printf(" %22.18g %22.18g\n", r.val, r.err) end return local_s end def test_sf_2(r1, val1, tol1, r2, val2, tol2, status, expect_return, desc) int local_s = 0 message_buff = "" s, message_buff = test_sf_check_result(message_buff, r1, val1, tol1) local_s |= s s, message_buff = test_sf_check_result(message_buff, r2, val2, tol2) local_s |= s s, message_buff = test_sf_check_return(message_buff, status, expect_return) local_s |= s GSL::Test::test(local_s, desc) if local_s != 0 printf("%s", message_buff) printf(" %22.18g %22.18g\n", r1.val, r1.err) printf(" %22.18g %22.18g\n", r2.val, r2.err) end return local_s end def test_sf_sgn(r, sgn, val_in, tol, expect_sgn, status, expect_return, desc) local_r local_s = 0 message_buff = "" local_r.val = sgn local_r.err = 0.0 s, message_buff = test_sf_check_result(message_buff, r, val_in, tol) local_s |= s s, message_buff = test_sf_check_result(message_buff, local_r, expect_sgn, 0.0) local_s |= s s, message_buff = test_sf_check_return(message_buff, status, expect_return) local_s |= s GSL::Test::test(local_s, desc) if local_s != 0 printf("%s", message_buff) printf(" %22.18g %22.18g\n", r.val, r.err) end return local_s end def TEST_SF(stat, func, args, val_in, tol, expect_return) r, = eval("#{func}#{args}") # p r # p val_in status = 0 stat += test_sf(r, val_in, tol, status, expect_return, "#{func}#{args}") return stat end def TEST_SF_2(stat, func, args, val1, tol1, val2, tol2, expect_return) r, = eval("#{func}#{args}") status = 0 stat += test_sf_2(r1, val1, tol1, r2, val2, tol2, status, expect_return, "#{func}#{args}") return stat end def TEST_SF_SGN(stat, func, args, val_in, tol, expect_sgn, expect_return) r, = eval("#{func}#{args}") status = 0 stat += test_sf_sgn(r, sgn, val_in, tol, expect_sgn, status, expect_return, "#{func}#{args}") return stat end end end end