ProteoWizard
erfTest.cpp
Go to the documentation of this file.
1//
2// $Id$
3//
4//
5// Original author: Darren Kessner <darren@proteowizard.org>
6//
7// Copyright 2006 Louis Warschaw Prostate Cancer Center
8// Cedars Sinai Medical Center, Los Angeles, California 90048
9//
10// Licensed under the Apache License, Version 2.0 (the "License");
11// you may not use this file except in compliance with the License.
12// You may obtain a copy of the License at
13//
14// http://www.apache.org/licenses/LICENSE-2.0
15//
16// Unless required by applicable law or agreed to in writing, software
17// distributed under the License is distributed on an "AS IS" BASIS,
18// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19// See the License for the specific language governing permissions and
20// limitations under the License.
21//
22
23
24#include "erf.hpp"
27#include <limits>
28#include <cstring>
29#include <cmath>
30
31
32using namespace pwiz::util;
33using namespace pwiz::math;
34using std::numeric_limits;
35using std::complex;
36
37
38ostream* os_ = 0;
39const double epsilon_ = numeric_limits<double>::epsilon();
40
41
42/*
43void test_series()
44{
45 cout << "test_series()\n";
46
47 // we match real-valued erf within epsilon_*10 in range [-2,2],
48 // using 29 terms at +/-2
49
50 for (double x=-2; x<2; x+=.2)
51 {
52 complex<double> resultComplex = erf_series(complex<double>(x));
53 double resultReal = ((double(*)(double))erf)(x);
54 //cout << resultComplex << " " << resultReal << endl;
55 unit_assert_equal(resultComplex.real(), resultReal, epsilon_*10);
56 }
57}
58
59
60void test_series2()
61{
62 cout << "test_series2()\n";
63
64 // 1e-12 precision in range [-20,20] using < 1200 terms
65 for (double x=-20; x<20; x+=2)
66 {
67 complex<double> resultComplex = erf_series2(complex<double>(x));
68 double resultReal = ((double(*)(double))erf)(x);
69 //cout << resultComplex << " " << resultReal << endl;
70 unit_assert_equal(resultComplex.real(), resultReal, 1e-12);
71 }
72}
73
74
75void test_1vs2()
76{
77 cout << "test_1vs2()\n";
78
79 // erf_series matches erf_series2 in region [-2,2]x[-2,2] within 1e-10
80 double a = 2;
81 for (double x=-a; x<=a; x+=a/5.)
82 for (double y=-a; y<=a; y+=a/5.)
83 {
84 complex<double> z(x,y);
85 complex<double> result1 = erf_series(z);
86 complex<double> result2 = erf_series2(z);
87 //cout << z << ": " << abs(result1-result2) << endl;
88 unit_assert_equal(result1, result2, 1e-10);
89 }
90}
91
92
93void test_convergence2()
94{
95 complex<double> z(100,1);
96 cout << erf_series2(z) << endl;
97}
98*/
99
100
101#if defined(_MSC_VER)
102void test_real()
103{
104 cerr << "[erfTest] Warning: test_real() not implemented for MSVC.\n";
105}
106#else
108{
109 // tests our complex erf against the not-so-standard gcc-provided double erf(double)
110
111 if (os_) *os_ << "test_real()\n";
112
113 double a = 10;
114 for (double x=-a; x<=a; x+=a/100)
115 {
116 complex<double> resultComplex = erf(complex<double>(x));
117 double resultReal = ((double(*)(double))::erf)(x);
118 if (os_) *os_ << x << " -> " << resultComplex << " " << resultReal << endl;
119 unit_assert_equal(resultComplex.real(), resultReal, 1e-12);
120 }
121
122 if (os_) *os_ << endl;
123}
124#endif // defined(_MSC_VER)
125
126
128{
129 if (os_) *os_ << "test_series()\n";
130
131 // erf_series2 matches erf in region [-2,2]x[-2,2] within 1e-10
132 double a = 2;
133 for (double x=-a; x<=a; x+=a/5.)
134 for (double y=-a; y<=a; y+=a/5.)
135 {
136 complex<double> z(x,y);
137 complex<double> result1 = erf(z);
138 complex<double> result2 = erf_series2(z);
139 if (os_) *os_ << z << ": " << abs(result1-result2) << endl;
140 unit_assert_equal(abs(result1-result2), 0, 1e-10);
141 }
142
143 if (os_) *os_ << endl;
144}
145
146
148{
149 if (os_) *os_ << "test_real_wrapper()\n";
150
151 double a = 10;
152 for (double x=-a; x<=a; x+=a/100)
153 {
154 double result_pwiz = pwiz::math::erf(x);
155 double result_std = ::erf(x);
156 if (os_) *os_ << x << " -> " << result_pwiz << " " << result_std << endl;
157 unit_assert_equal(result_pwiz, result_std, 1e-12);
158 }
159
160 if (os_) *os_ << endl;
161}
162
163
164int main(int argc, char* argv[])
165{
166 TEST_PROLOG(argc, argv)
167
168 try
169 {
170 if (argc>1 && !strcmp(argv[1],"-v")) os_ = &cout;
171 if (os_) *os_ << "erfTest\n" << setprecision(20);
172 test_real();
173 test_series();
175 }
176 catch (exception& e)
177 {
178 TEST_FAILED(e.what())
179 }
180 catch (...)
181 {
182 TEST_FAILED("Caught unknown exception.")
183 }
184
186}
187
KernelTraitsBase< Kernel >::space_type::abscissa_type x
KernelTraitsBase< Kernel >::space_type::ordinate_type y
int main(int argc, char *argv[])
Definition erfTest.cpp:164
void test_real_wrapper()
Definition erfTest.cpp:147
const double epsilon_
Definition erfTest.cpp:39
void test_real()
Definition erfTest.cpp:107
ostream * os_
Definition erfTest.cpp:38
void test_series()
Definition erfTest.cpp:127
PWIZ_API_DECL std::complex< double > erf_series2(const std::complex< double > &z)
series implementation for testing
PWIZ_API_DECL double erf(double x)
real error function; calls gcc-provided erf, complex version (below) on msvc
#define TEST_EPILOG
Definition unit.hpp:183
#define TEST_FAILED(x)
Definition unit.hpp:177
#define unit_assert_equal(x, y, epsilon)
Definition unit.hpp:99
#define TEST_PROLOG(argc, argv)
Definition unit.hpp:175