PSCF v1.1
CardinalBSpline.cpp
1/*
2* Util Package - C++ Utilities for Scientific Computation
3*
4* Copyright 2010 - 2017, The Regents of the University of Minnesota
5* Distributed under the terms of the GNU General Public License.
6*/
7
8#include "CardinalBSpline.h"
9#include <util/global.h>
10
11namespace Util
12{
13
14 /*
15 * Construct a cardinal spline basis function of specified degree.
16 */
17 CardinalBSpline::CardinalBSpline(int degree, bool verbose)
18 : floatPolynomials_(),
19 degree_(degree)
20 {
21 UTIL_CHECK(degree >= 0);
22
23 // Polynomials with Rational coefficients for use in constructor.
24 DArray< Polynomial<Rational> > exactPolynomials;
25
26 // Allocate both polynomial arrays
27 int size = degree_ + 1;
28 exactPolynomials.allocate(size);
29 floatPolynomials_.allocate(size);
30
31 // Set B_{0,0} = 1
33 exactPolynomials[0] = unity;
34
35 if (verbose) {
36 int n = 0;
37 std::cout << std::endl;
38 std::cout << "Degree = 0 ";
39 std::cout << " [" << n
40 << " , " << n + 1 << "] : ";
41 std::cout << exactPolynomials[n];
42 }
43
44 if (degree_ > 0) {
45
46 // Allocate and initialize work array
48 work.allocate(size);
49 int n;
50 for (n = 0; n < size; ++n) {
51 work[n].setToZero();
52 }
53
54 // Recursive construction of spline bases
55 int m; // Degree of previously calculated spline polynomials
56 for (m = 0; m < degree_; ++m) {
57
58 // Evaluate and store integrals of degree m polynomials
59 for (n = 0; n <= m; ++n) {
60 work[n] = exactPolynomials[n].integrate();
61 }
62
63 // Clear exactPolynomials array
64 for (n = 0; n < size; ++n) {
65 exactPolynomials[n].setToZero();
66 }
67
68 // Applying recursion relation to obtain degree m+1 polynomials
69 for (n = 0; n <= m + 1; ++n) {
70 if (n < m + 1) {
71 exactPolynomials[n] += work[n];
72 exactPolynomials[n] -= work[n](Rational(n));
73 }
74 if (n > 0) {
75 exactPolynomials[n] += work[n-1](Rational(n));
76 exactPolynomials[n] -= work[n-1].shift(Rational(-1));
77 }
78 }
79
80 // Optionally output intermediate results
81 if (verbose) {
82 std::cout << std::endl;
83 for (n = 0; n <= m + 1; ++n) {
84 std::cout << std::endl;
85 std::cout << "Degree = " << m + 1;
86 std::cout << " [" << n
87 << " , " << n + 1 << "] : ";
88 std::cout << exactPolynomials[n] << " ";
89 std::cout << exactPolynomials[n](Rational(n)) << " ";
90 std::cout << exactPolynomials[n](Rational(n+1)) << " ";
91 }
92 }
93
94 }
95
96 // Check continuity of function and m-1 derivatives
97 for (n = 0; n <= degree_; ++n) {
98 work[n] = exactPolynomials[n];
99 }
100 Rational lower;
101 Rational upper;
102 for (m = 0; m < degree_; ++m) {
103 for (n = 1; n <= degree_; ++n) {
104 lower = work[n-1](Rational(n));
105 upper = work[n](Rational(n));
106 UTIL_CHECK(lower == upper);
107 }
108 for (n = 0; n <= degree_; ++n) {
109 work[n] = work[n].differentiate();
110 }
111 }
112
113 // Convert polynomials coefficients from Rational to double.
114 for (n = 0; n <= degree_; ++n) {
115 floatPolynomials_[n] = exactPolynomials[n];
116 }
117
118 }
119
120 }
121
122 /*
123 * Destructor.
124 */
126 {}
127
128}
int degree() const
Return degree of basis function (i.e., degree of polynomials).
CardinalBSpline(int degree, bool verbose=false)
Construct a spline basis of specified degree.
Dynamically allocatable contiguous array template.
Definition: DArray.h:32
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:199
A Polynomial (i.e,.
Definition: Polynomial.h:30
A Rational number (a ratio of integers).
Definition: Rational.h:34
File containing preprocessor macros for error handling.
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition: global.h:68
Utility classes for scientific computation.
Definition: accumulators.mod:1