Doxygen 1.15.0
Toolkit for Adaptive Stochastic Modeling and Non-Intrusive ApproximatioN: Tasmanian v8.2
Loading...
Searching...
No Matches
tsgCacheLagrange.hpp
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
43
44#include "tsgGridCore.hpp"
45
46namespace TasGrid{
47
60template <typename T>
61class CacheLagrange{
62public:
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
111protected:
120 std::vector<std::vector<T>> cache;
122 std::vector<int> offsets;
123};
124
125
132
133template <typename T>
134class CacheLagrangeDerivative {
135public:
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 }
157 ~CacheLagrangeDerivative() = default;
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
196protected:
198 std::vector<std::vector<T>> cache;
200 std::vector<int> offsets;
201};
202
203}
204
205#endif
@ 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