Doxygen 1.9.1
Toolkit for Adaptive Stochastic Modeling and Non-Intrusive ApproximatioN: Tasmanian v8.2 (development)
tsgCacheLagrange.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017, Miroslav Stoyanov
3  *
4  * This file is part of
5  * Toolkit for Adaptive Stochastic Modeling And Non-Intrusive ApproximatioN: TASMANIAN
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
12  * and the following disclaimer in the documentation and/or other materials provided with the distribution.
13  *
14  * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
15  * or promote products derived from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
20  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
21  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  * UT-BATTELLE, LLC AND THE UNITED STATES GOVERNMENT MAKE NO REPRESENTATIONS AND DISCLAIM ALL WARRANTIES, BOTH EXPRESSED AND IMPLIED.
25  * THERE ARE NO EXPRESS OR IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY PATENT,
26  * COPYRIGHT, TRADEMARK, OR OTHER PROPRIETARY RIGHTS, OR THAT THE SOFTWARE WILL ACCOMPLISH THE INTENDED RESULTS OR THAT THE SOFTWARE OR ITS USE WILL NOT RESULT IN INJURY OR DAMAGE.
27  * THE USER ASSUMES RESPONSIBILITY FOR ALL LIABILITIES, PENALTIES, FINES, CLAIMS, CAUSES OF ACTION, AND COSTS AND EXPENSES, CAUSED BY, RESULTING FROM OR ARISING OUT OF,
28  * IN WHOLE OR IN PART THE USE, STORAGE OR DISPOSAL OF THE SOFTWARE.
29  */
30 
31 #ifndef __TSG_CACHE_LAGRANGE_HPP
32 #define __TSG_CACHE_LAGRANGE_HPP
33 
44 #include "tsgGridCore.hpp"
45 
46 namespace TasGrid{
47 
60 template <typename T>
62 public:
75  CacheLagrange(int num_dimensions, const std::vector<int> &max_levels, const OneDimensionalWrapper &rule, const double x[]) :
76  cache(std::vector<std::vector<T>>(num_dimensions, std::vector<T>())), offsets(rule.getPointsCount()){
77  for(int dim=0; dim<num_dimensions; dim++){
78  cache[dim].resize(offsets[max_levels[dim] + 1]);
79  for(int level=0; level <= max_levels[dim]; level++)
80  cacheLevel(level, x[dim], rule, &(cache[dim][offsets[level]]));
81  }
82  }
84  ~CacheLagrange() = default;
85 
87  static void cacheLevel(int level, double x, const OneDimensionalWrapper &rule, T *cc){
88  const double *nodes = rule.getNodes(level);
89  const double *coeff = rule.getCoefficients(level);
90  int num_points = rule.getNumPoints(level);
91 
92  cc[0] = 1.0;
93  T c = 1.0;
94  for(int j=0; j<num_points-1; j++){
95  c *= (x - nodes[j]);
96  cc[j+1] = c;
97  }
98  c = (rule.getRule() == rule_clenshawcurtis0) ? (x * x - 1.0) : 1.0;
99  cc[num_points-1] *= c * coeff[num_points-1];
100  for(int j=num_points-2; j>=0; j--){
101  c *= (x - nodes[j+1]);
102  cc[j] *= c * coeff[j];
103  }
104  }
105 
107  T getLagrange(int dimension, int level, int local) const{
108  return cache[dimension][offsets[level] + local];
109  }
110 
111 protected:
120  std::vector<std::vector<T>> cache;
122  std::vector<int> offsets;
123 };
124 
125 
133 template <typename T>
135 public:
148  CacheLagrangeDerivative(int num_dimensions, const std::vector<int> &max_levels, const OneDimensionalWrapper &rule, const double x[]) :
149  cache(std::vector<std::vector<T>>(num_dimensions, std::vector<T>())), offsets(rule.getPointsCount()) {
150  for(int dim=0; dim<num_dimensions; dim++){
151  cache[dim].resize(offsets[max_levels[dim] + 1]);
152  for(int level=0; level <= max_levels[dim]; level++)
153  cacheDerivativeLevel(level, x[dim], rule, &(cache[dim][offsets[level]]));
154  }
155  }
158 
160  static void cacheDerivativeLevel(int level, double x, const OneDimensionalWrapper &rule, T *cc){
161  /*
162  * The usual j-th Lagrange derivative is of the form Lj(x) = cj * fj(x) * gj(x) where
163  *
164  * fj(x) = (x - nodes[0])...(x - nodes[j-1]),
165  * gj(x) = (x - nodes[j+1])...(x - nodes[num_points-1]),
166  *
167  * and cj is the j-th Lagrange coefficient. The product rule gives Lj'(x) = cj * [fj'(x) * gj(x) + fj(x) * gj'(x)].
168  * Hence, we do a forward pass for [fj(x), fj'(x)] and a backward pass for [gj(x), gj'(x)].
169  */
170  const double *nodes = rule.getNodes(level);
171  const double *coeff = rule.getCoefficients(level);
172  int num_points = rule.getNumPoints(level);
173  // cc first stores fj'(x), aux_f stores fj(x), and aux_g stores gj(x).
174  std::vector<T> aux_f(num_points), aux_g(num_points);
175  cc[0] = (rule.getRule() == rule_clenshawcurtis0) ? 2.0 * x : 0.0;
176  aux_f[0] = (rule.getRule() == rule_clenshawcurtis0) ? x * x - 1.0 : 1.0;
177  aux_g[num_points-1] = 1.0;
178  for(int i=1; i<num_points; i++) {
179  aux_f[i] = aux_f[i-1] * (x - nodes[i-1]);
180  aux_g[num_points-1-i] = aux_g[num_points-i] * (x - nodes[num_points-i]);
181  cc[i] = aux_f[i-1] + (x - nodes[i-1]) * cc[i-1];
182  }
183  cc[num_points-1] *= coeff[num_points-1];
184  T diff_gj = 0.0;
185  for(int i=num_points-2; i>=0; i--) {
186  diff_gj = aux_g[i+1] + diff_gj * (x - nodes[i+1]);
187  cc[i] = coeff[i] * (cc[i] * aux_g[i] + aux_f[i] * diff_gj);
188  }
189  }
190 
192  T getLagrangeDerivative(int dimension, int level, int local) const {
193  return cache[dimension][offsets[level] + local];
194  }
195 
196 protected:
198  std::vector<std::vector<T>> cache;
200  std::vector<int> offsets;
201 };
202 
203 }
204 
205 #endif
Cache that holds the derivatives of 1D Lagrange polynomials. Uses the same interface as CacheLagrange...
Definition: tsgCacheLagrange.hpp:134
std::vector< int > offsets
See CacheLagrange::offsets.
Definition: tsgCacheLagrange.hpp:200
static void cacheDerivativeLevel(int level, double x, const OneDimensionalWrapper &rule, T *cc)
Computes the derivatives of all Lagrange polynomials for the given level at the given x.
Definition: tsgCacheLagrange.hpp:160
~CacheLagrangeDerivative()=default
Destructor, clear all used data.
T getLagrangeDerivative(int dimension, int level, int local) const
Return the Lagrange derivative cache for given dimension, level and offset local to the level.
Definition: tsgCacheLagrange.hpp:192
CacheLagrangeDerivative(int num_dimensions, const std::vector< int > &max_levels, const OneDimensionalWrapper &rule, const double x[])
Constructor that takes into account a single canonical point x.
Definition: tsgCacheLagrange.hpp:148
std::vector< std::vector< T > > cache
See CacheLagrange::cache.
Definition: tsgCacheLagrange.hpp:198
Cache that holds the values of 1D Lagrange polynomials.
Definition: tsgCacheLagrange.hpp:61
std::vector< std::vector< T > > cache
Stores the values of the Lagrange polynomias for each dimension and each level.
Definition: tsgCacheLagrange.hpp:120
std::vector< int > offsets
Stores the offsets for each level within each dimension.
Definition: tsgCacheLagrange.hpp:122
static void cacheLevel(int level, double x, const OneDimensionalWrapper &rule, T *cc)
Computes the values of all Lagrange polynomials for the given level at the given x.
Definition: tsgCacheLagrange.hpp:87
T getLagrange(int dimension, int level, int local) const
Return the Lagrange cache for given dimension, level and offset local to the level.
Definition: tsgCacheLagrange.hpp:107
~CacheLagrange()=default
Destructor, clear all used data.
CacheLagrange(int num_dimensions, const std::vector< int > &max_levels, const OneDimensionalWrapper &rule, const double x[])
Constructor that takes into account a single canonical point x.
Definition: tsgCacheLagrange.hpp:75
A class to cache one dimensional rules, nodes, weight, meta-data, etc.
Definition: tsgOneDimensionalWrapper.hpp:53
const double * getCoefficients(int level) const
Get an array of the Lagrange coefficients associated with the level, the order matches getNodes().
Definition: tsgOneDimensionalWrapper.hpp:305
const double * getNodes(int level) const
Get an array of all nodes associated with the level (the array is ordered by local index).
Definition: tsgOneDimensionalWrapper.hpp:303
TypeOneDRule getRule() const
Get the loaded rule.
Definition: tsgOneDimensionalWrapper.hpp:311
int getNumPoints(int level) const
Get the number of points for the level, can only query loaded levels.
Definition: tsgOneDimensionalWrapper.hpp:279
@ rule_clenshawcurtis0
Same as rule_clenshawcurtis but with modified basis that assumes the model is zero at the boundary.
Definition: tsgEnumerates.hpp:291
Encapsulates the Tasmanian Sparse Grid module.
Definition: TasmanianSparseGrid.hpp:68
Definition for the base grid class.