1
/*****************************************************************************
2
* erf.cpp Blitz++ Vector<T> example
3
*****************************************************************************/
5
#include <blitz/blitz.h>
7
#ifdef BZ_HAVE_IEEE_MATH
9
#include <blitz/vector-et.h>
11
// This program uses erf(), which is not part of ANSI C/C++. In order
12
// to compile this example, you must have a Posix or X/Open-compliant
13
// compiler, and #define an appropriate source level (-D_XOPEN_SOURCE or
14
// -D_POSIX_SOURCE). You will need to run compiler/bzconfig with
15
// this flag defined as well, so that the Blitz++ flag BZ_HAVE_IEEE_MATH
16
// will be set properly in <blitz/config.h>.
18
BZ_USING_NAMESPACE(blitz)
22
// Integrate the expression
25
// ------- | exp(-t^2) dt
28
// to estimate the error function erf(x) on the interval [0,1].
30
// Three methods are compared:
32
// 2. Two-point trapezoid
33
// 3. Three-point Simpson's
35
const double m_2_sqrtpi = 1.12837916709551257389615890312154517;
36
const int numSamples = 1024; // Number of samples
37
double dt = 1.0 / numSamples; // Distance between samples
38
Range R(0, numSamples - 1); // Index set for sample vectors
39
Range displayRange(0, 900, 100); // Indices to output to screen
41
// For comparison purposes, use the built-in erf(x) function.
42
Vector<double> z = erf(R * dt);
43
cout << " Built-in: " << z(displayRange+1) << endl;
47
Vector<double> z1 = accumulate(m_2_sqrtpi * exp(-sqr(R * dt)) * dt);
48
cout << " Naive: " << z1(displayRange+1) << endl;
50
// Calculate the rms error
51
double error1 = sqrt(mean(sqr(z1 - z)));
52
cout << "RMS Error: " << error1 << endl;
55
// For the following rules, it's easier to work with a
57
Vector<double> a = m_2_sqrtpi * exp(-sqr(R * dt));
60
// Two-point trapezoid
61
Range J(1, numSamples-1);
62
Vector<double> z2 = accumulate(dt / 2.0 * (a(J) + a(J-1)));
64
cout << " Trapezoid: " << z2(displayRange) << endl;
65
cout << "RMS Error: " << sqrt(mean(sqr(z2-z(J)))) << endl;
68
// Three-point Simpson's (parabolic)
69
Range I(1, numSamples-2);
70
Vector<double> z3 = accumulate(dt / 6.0 * (a(I-1) + 4 * a(I) + a(I+1)));
72
cout << " Parabolic: " << z3(displayRange) << endl;
73
cout << "RMS Error: " << sqrt(mean(sqr(z3 - z(I)))) << endl;
85
cout << "This example requires IEEE math functions." << endl;
89
#endif // BZ_HAVE_IEEE_MATH