Simpatico  v1.10
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 
11 namespace 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 }
~CardinalBSpline()
Destructor.
File containing preprocessor macros for error handling.
CardinalBSpline(int degree, bool verbose=false)
Construct a spline basis of specified degree.
Utility classes for scientific computation.
Definition: accumulators.mod:1
Dynamically allocatable contiguous array template.
Definition: DArray.h:31
#define UTIL_CHECK(condition)
Assertion macro suitable for serial or parallel production code.
Definition: global.h:68
void allocate(int capacity)
Allocate the underlying C array.
Definition: DArray.h:191
A Polynomial (i.e,.
Definition: Polynomial.h:30
A Rational number (a ratio of integers).
Definition: Rational.h:33