1 # include "sandia_rules.hpp"
2 # include "sandia_sgmgg.hpp"
3
4 # include <cstdlib>
5 # include <iostream>
6 # include <iomanip>
7 # include <cstring>
8 # include <ctime>
9
10 namespace webbur
11 {
12 //****************************************************************************80
13
sandia_sgmgg_coef_inc2(int m,int n1,int s1[],int c1[],int s2[],int c3[])14 void sandia_sgmgg_coef_inc2 ( int m, int n1, int s1[], int c1[],
15 int s2[], int c3[] )
16
17 //****************************************************************************80
18 //
19 // Purpose:
20 //
21 // SANDIA_SGMGG_COEF_INC2 computes tentative coefficient changes.
22 //
23 // Discussion:
24 //
25 // An active set S1 of N1 sparse grid indices is given, each of
26 // size M.
27 //
28 // The coefficient C1 of each sparse grid index is also given.
29 //
30 // A candidate sparse grid index S2 is provided.
31 //
32 // This function determines the N+1 coefficients that would be
33 // appropriate if the candidate S2 was added to the active set
34 // as the (N+1)-st item.
35 //
36 // During the calculation, we may try to update coefficients of inactive
37 // index sets. By the end of the calculation, all these inactive index
38 // sets should have accumulated total coefficients of 0 again. As a check,
39 // we temporarily set aside space for these objects, and check, at the end,
40 // that the coefficients are zero.
41 //
42 // Example:
43 //
44 // Input:
45 //
46 // +1 * {0,2}
47 // -1 * {0,1} +1 * {1,1}
48 // -1 * {1,0} +1 * {2,0}
49 //
50 // Add {3,0}
51 //
52 // Output:
53 //
54 // +1 * {0,2}
55 // -1 * {0,1} +1 * {1,1}
56 // -1 * {1,0} 0 * {2,0} +1 * {3,0}
57 //
58 // Licensing:
59 //
60 // This code is distributed under the GNU LGPL license.
61 //
62 // Modified:
63 //
64 // 05 September 2011
65 //
66 // Author:
67 //
68 // John Burkardt
69 //
70 // Parameters:
71 //
72 // Input, int M, the dimension of the vector.
73 //
74 // Input, int N1, the number of points in the active set.
75 //
76 // Input, int S1[M*N1], the indices for the active set.
77 //
78 // Input, int C1[N1], the coefficients for the active set.
79 //
80 // Input, int S2[M], the indices for the candidate.
81 //
82 // Output, int C3[N1+1], the coefficients for the active set
83 // plus the candidate.
84 //
85 {
86 int *c4;
87 int i;
88 int i2;
89 int j;
90 int j2;
91 int k;
92 int n4;
93 int *s;
94 int *s4;
95 //
96 // Initialize the inactive data.
97 //
98 n4 = 0;
99
100 c4 = new int[n1];
101 for ( i = 0; i < n1; i++ )
102 {
103 c4[i] = 0;
104 }
105
106 s4 = new int[m*n1];
107 for ( j = 0; j < n1; j++ )
108 {
109 for ( i = 0; i < m; i++ )
110 {
111 s4[i+j*m] = 0;
112 }
113 }
114 //
115 // Copy C1.
116 //
117 for ( j = 0; j < n1; j++ )
118 {
119 c3[j] = c1[j];
120 }
121 c3[n1] = 1;
122 //
123 // Consider the effect of the new item S2 on each of the current
124 // items in the active set S1.
125 //
126 s = new int[m];
127
128 for ( j = 0; j < n1; j++ )
129 {
130 //
131 // Determine S, the element-wise minimum of the J-th item in S1 versus S2.
132 //
133 k = j;
134
135 for ( i = 0; i < m; i++ )
136 {
137 if ( s2[i] < s1[i+j*m] )
138 {
139 s[i] = s2[i];
140 k = -1;
141 }
142 else
143 {
144 s[i] = s1[i+j*m];
145 }
146 }
147 //
148 // If S = S1[*,J], then K is J.
149 //
150 if ( k != -1 )
151 {
152 c3[k] = c3[k] - c1[j];
153 }
154 //
155 // If S is equal to an element of the active set, we set K to that index.
156 //
157 else
158 {
159 for ( j2 = 0; j2 < n1; j2++ )
160 {
161 k = j2;
162 for ( i2 = 0; i2 < m; i2++ )
163 {
164 if ( s1[i2+j2*m] != s[i2] )
165 {
166 k = -1;
167 break;
168 }
169 }
170 if ( k != -1 )
171 {
172 c3[k] = c3[k] - c1[j];
173 break;
174 }
175 }
176 }
177 //
178 // If S is equal to an element of the inactive set, set K to that index.
179 //
180 if ( k == -1 )
181 {
182 for ( j2 = 0; j2 < n4; j2++ )
183 {
184 k = j2;
185
186 for ( i2 = 0; i2 < m; i2++ )
187 {
188 if ( s4[i2+j2*m] != s[i2] )
189 {
190 k = - 1;
191 break;
192 }
193 }
194
195 if ( k != - 1 )
196 {
197 c4[k] = c4[k] - c1[j];
198 break;
199 }
200 }
201 }
202 //
203 // S is not equal to S1(*,J), or any element of S1, or any element of S4.
204 // Add S to the set of elements S4.
205 //
206 if ( k == -1 )
207 {
208 k = n4;
209 c4[k] = 0;
210 for ( i = 0; i < m; i++ )
211 {
212 s4[i+k*m] = s[i];
213 }
214 c4[k] = c4[k] - c1[j];
215 n4 = n4 + 1;
216 }
217 }
218 //
219 // At the end, the C4(1:N4) should all be zero.
220 //
221 for ( i = 0; i < n4; i++ )
222 {
223 if ( c4[k] != 0 )
224 {
225 std::cerr << "\n";
226 std::cerr << "SANDIA_SGMGG_COEF_INC2 - Fatal error!\n";
227 std::cerr << " Some inactive indices were assigned a nonzero coefficient.\n";
228 webbur::i4mat_transpose_print ( m, n4, s4, " S4:" );
229 webbur::i4vec_print ( n4, c4, " C4:" );
230 std::exit ( 1 );
231 }
232 }
233
234 delete [] c4;
235 delete [] s;
236 delete [] s4;
237
238 return;
239 }
240 //****************************************************************************80
241
sandia_sgmgg_coef_naive(int dim_num,int point_num,int sparse_index[],int coef[])242 void sandia_sgmgg_coef_naive ( int dim_num, int point_num, int sparse_index[],
243 int coef[] )
244
245 //****************************************************************************80
246 //
247 // Purpose:
248 //
249 // SANDIA_SGMGG_COEF_NAIVE returns the combinatorial coefficients.
250 //
251 // Discussion:
252 //
253 // The coefficient of point I is calculated as follows:
254 //
255 // *) point J is a "neighbor" of point I if every entry of the sparse
256 // index for point J is either equal to, or 1 greater than, the
257 // corresponding entry of the sparse index of point I.
258 //
259 // *) If point J is a neighbor of point I, then it contributes
260 // (-1)^D to the coefficient, where D is the sum of the differences
261 // between the sparse indices of point I and point J.
262 //
263 // This is a completely naive implementation of the calculation,
264 // intended simply as a demonstration for small examples.
265 //
266 // Licensing:
267 //
268 // This code is distributed under the GNU LGPL license.
269 //
270 // Modified:
271 //
272 // 05 August 2010
273 //
274 // Author:
275 //
276 // John Burkardt
277 //
278 // Reference:
279 //
280 // Fabio Nobile, Raul Tempone, Clayton Webster,
281 // A Sparse Grid Stochastic Collocation Method for Partial Differential
282 // Equations with Random Input Data,
283 // SIAM Journal on Numerical Analysis,
284 // Volume 46, Number 5, 2008, pages 2309-2345.
285 //
286 // Fabio Nobile, Raul Tempone, Clayton Webster,
287 // An Anisotropic Sparse Grid Stochastic Collocation Method for Partial
288 // Differential Equations with Random Input Data,
289 // SIAM Journal on Numerical Analysis,
290 // Volume 46, Number 5, 2008, pages 2411-2442.
291 //
292 // Parameters:
293 //
294 // Input, int DIM_NUM, the dimension of the vector.
295 //
296 // Input, int POINT_NUM, the number of points.
297 //
298 // Input, int SPARSE_INDEX[DIM_NUM*POINT_NUM],
299 // the indices that define the points.
300 //
301 // Output, int COEF[POINT_NUM], the coefficients.
302 //
303 {
304 int dif;
305 int i;
306 int j;
307 int j1;
308 int j2;
309 bool neighbor;
310 int term;
311
312 for ( j = 0; j < point_num; j++ )
313 {
314 coef[j] = 0;
315 }
316 for ( j1 = 0; j1 < point_num; j1++ )
317 {
318 for ( j2 = 0; j2 < point_num; j2++ )
319 {
320 neighbor = true;
321 term = + 1;
322 for ( i = 0; i < dim_num; i++ )
323 {
324 dif = sparse_index[i+j2*dim_num] - sparse_index[i+j1*dim_num];
325
326 if ( dif == 0 )
327 {
328 }
329 else if ( dif == 1 )
330 {
331 term = - term;
332 }
333 else
334 {
335 neighbor = false;
336 break;
337 }
338 }
339 if ( neighbor )
340 {
341 coef[j1] = coef[j1] + term;
342 }
343 }
344 }
345 return;
346 }
347 //****************************************************************************80
348
sandia_sgmgg_neighbor_naive(int dim_num,int point_num,int sparse_index[],int neighbor[])349 void sandia_sgmgg_neighbor_naive ( int dim_num, int point_num, int sparse_index[],
350 int neighbor[] )
351
352 //****************************************************************************80
353 //
354 // Purpose:
355 //
356 // SANDIA_SGMGG_NEIGHBOR_NAIVE returns the immediate forward neighbor array.
357 //
358 // Discussion:
359 //
360 // A sparse grid index vector is a list of DIM_NUM nonnegative indices.
361 //
362 // An immediate forward L-neighbor of a sparse grid index vector I is a
363 // sparse grid index vector J with the property that all entries of J
364 // are equal to those of I except for the L-the entry, which is greater by 1.
365 //
366 // A forward neighbor of a sparse grid index vector I is a sparse
367 // grid index vector K with the property that every entry of K is
368 // equal to or greater by 1 than the corresponding entry of I.
369 //
370 // This function is given a collection of sparse grid index vectors,
371 // and returns information defining, for every such vector, the entire
372 // set of its immediate forward neighbors. This is done with a
373 // "NEIGHBOR" array of dimension DIM_NUM. For sparse grid vector I,
374 // entry L of NEIGHBOR is 1 if I has an immediate forward L-neighbor,
375 // and 0 otherwise.
376 //
377 // This implementation of the procedure is inefficient, and is provided
378 // solely for demonstration on small problems.
379 //
380 // Licensing:
381 //
382 // This code is distributed under the GNU LGPL license.
383 //
384 // Modified:
385 //
386 // 06 August 2010
387 //
388 // Author:
389 //
390 // John Burkardt
391 //
392 // Reference:
393 //
394 // Fabio Nobile, Raul Tempone, Clayton Webster,
395 // A Sparse Grid Stochastic Collocation Method for Partial Differential
396 // Equations with Random Input Data,
397 // SIAM Journal on Numerical Analysis,
398 // Volume 46, Number 5, 2008, pages 2309-2345.
399 //
400 // Fabio Nobile, Raul Tempone, Clayton Webster,
401 // An Anisotropic Sparse Grid Stochastic Collocation Method for Partial
402 // Differential Equations with Random Input Data,
403 // SIAM Journal on Numerical Analysis,
404 // Volume 46, Number 5, 2008, pages 2411-2442.
405 //
406 // Parameters:
407 //
408 // Input, int DIM_NUM, the dimension of the vector.
409 //
410 // Input, int POINT_NUM, the number of points.
411 //
412 // Input, int SPARSE_INDEX[DIM_NUM*POINT_NUM],
413 // the indices that define the points.
414 //
415 // Output, int NEIGHBOR[DIM_NUM*POINT_NUM], the immediate forward
416 // neighbor array.
417 //
418 {
419 int i;
420 int j;
421 int j1;
422 int j2;
423 int l;
424
425 for ( j = 0; j < point_num; j++ )
426 {
427 for ( i = 0; i < dim_num; i++ )
428 {
429 neighbor[i+j*dim_num] = 0;
430 }
431 }
432 for ( j1 = 0; j1 < point_num; j1++ )
433 {
434 for ( j2 = 0; j2 < point_num; j2++ )
435 {
436 l = -1;
437 for ( i = 0; i < dim_num; i++ )
438 {
439 //
440 // If the entries are not equal...
441 //
442 if ( sparse_index[i+j2*dim_num] != sparse_index[i+j1*dim_num] )
443 {
444 //
445 // ...and we haven't already found a difference...
446 //
447 if ( l != -1 )
448 {
449 l = -1;
450 break;
451 }
452 //
453 // ...and this difference is +1...
454 //
455 if ( sparse_index[i+j2*dim_num] != sparse_index[i+j1*dim_num] + 1 )
456 {
457 break;
458 }
459 //
460 // ...then remember this index.
461 //
462 l = i;
463 }
464 }
465 //
466 // If a single unit difference was found, record the direction.
467 //
468 if ( l != - 1 )
469 {
470 neighbor[l+j1*dim_num] = 1;
471 }
472 }
473 }
474 return;
475 }
476
477 }
478