WaveBlocksND
genz_keister_qr.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <cmath>
4 #include <iostream>
5 #include <tuple>
6 #include <vector>
7 
8 #include <Eigen/Core>
9 #include <Eigen/Dense>
10 
11 #include "../types.hpp"
12 #include "../math/combinatorics.hpp"
13 
14 #include "tables_genzkeister.hpp"
15 
16 
17 namespace waveblocks {
18  namespace innerproducts {
25  template <dim_t DIM, dim_t LEVEL>
27  {
28  static const dim_t D = DIM;
29  static const dim_t level = LEVEL;
30 
31  using NodeMatrix = Eigen::Matrix<real_t,DIM,Eigen::Dynamic>;
32  using WeightVector = Eigen::Matrix<real_t,1,Eigen::Dynamic>;
33 
34 
39  {
41  return cached_nodes.cols();
42  }
43 
47  static NodeMatrix nodes()
48  {
50  return cached_nodes;
51  }
52 
53 
58  {
60  return cached_weights;
61  }
62 
66  static std::tuple<NodeMatrix,WeightVector>
68  {
70  return std::make_tuple(cached_nodes, cached_weights);
71  }
72 
73 
77  static void clear_cache()
78  {
79  cached = false;
80  cached_nodes.resize(DIM, 0);
81  cached_weights.resize(1, 0);
82  }
83 
84  private:
85  static bool cached;
88 
93  {
94  clear_cache();
95 
96  // Check LEVEL validity.
97  if (LEVEL < 1 || LEVEL > 30)
98  {
99  std::cerr << "GenzKeisterQR: LEVEL must be between 1 and 30!\n";
100  }
101 
102  const dim_t K = LEVEL - 1;
103  const math::partitions_t<DIM> parts = math::partitions<DIM>(K);
104  dim_t node_offset = 0;
105  for (const auto& part : parts)
106  {
107  int sum = 0;
108  for (int p : part) sum += p + genz_keister_zs(p);
109  if (sum <= K)
110  {
111  // Calculate nodes and weights for this partition.
112  const NodeMatrix part_nodes = nodes_for_partition(part);
113  const dim_t n_nodes = part_nodes.cols();
114  const real_t part_weight = weight_for_partition(part);
115 
116  // Append them to the result.
117  cached_nodes.conservativeResize(Eigen::NoChange, node_offset + n_nodes);
118  cached_weights.conservativeResize(Eigen::NoChange, node_offset + n_nodes);
119 
120  cached_nodes.rightCols(n_nodes) = part_nodes;
121  cached_weights.tail(n_nodes).fill(part_weight);
122 
123  node_offset += n_nodes;
124  }
125  }
126 
127  // Transform weights.
128  for (dim_t i = 0; i < cached_nodes.cols(); ++i)
129  {
130  cached_weights(i) /= exp(-cached_nodes.col(i).squaredNorm());
131  }
132 
133  cached = true;
134  }
135 
142  {
143  const dim_t xi = math::nz<DIM>(part);
144  const math::permutations_t<DIM> perms = math::permutations<DIM>(part);
145  NodeMatrix nodes = NodeMatrix::Zero(DIM, perms.size() * (1 << (DIM-xi)));
146 
147  dim_t node_offset = 0;
148  for (const auto& perm : perms)
149  {
150  // Copy nodes with flipped signs from non-zero generators.
151  int nnz_row = 0;
152  for (int row = 0; row < DIM; ++row)
153  {
154  if (perm[row] == 0) continue;
155 
156  for (int col = 0; col < (1 << (DIM-xi)); ++col)
157  {
158  // Generators corresponding to current permutation.
159  const int sign = -2 * ((col >> nnz_row) & 1) + 1;
160  nodes(row, node_offset + col) = sign *
161  genz_keister_generators(perm[row]);
162  }
163 
164  // Count non-zero rows.
165  ++ nnz_row;
166  }
167 
168  node_offset += (1 << (DIM-xi));
169  }
170 
171  return nodes;
172  }
173 
180  {
181  const dim_t K = LEVEL - 1;
182 
183  real_t weight = 0;
184  for (const auto& q : math::lattice_points<DIM>(K - math::sum<DIM>(part)))
185  {
186  real_t w = 1;
187  for (dim_t i = 0; i < DIM; ++i)
188  {
189  w *= genz_keister_weight_factors(part[i], q[i] + part[i]);
190  }
191  weight += w;
192  }
193 
194  return weight / (1 << math::nnz<DIM>(part));
195  }
196  };
197 
198  // Initialize static members.
199  template <dim_t DIM, dim_t LEVEL>
201 
202  template <dim_t DIM, dim_t LEVEL>
205 
206  template <dim_t DIM, dim_t LEVEL>
209  }
210 }
Eigen::Matrix< real_t, DIM, Eigen::Dynamic > NodeMatrix
Definition: genz_keister_qr.hpp:31
Definition: coefficients_file_parser.cpp:10
static WeightVector cached_weights
Definition: genz_keister_qr.hpp:87
function p(by, bw, bv)
Definition: jquery.js:23
static std::tuple< NodeMatrix, WeightVector > nodes_and_weights()
Return the quadrature nodes and weights.
Definition: genz_keister_qr.hpp:67
double real_t
Definition: types.hpp:14
Eigen::Matrix< real_t, 1, Eigen::Dynamic > WeightVector
Definition: genz_keister_qr.hpp:32
const RMatrix< genz_keister_tablesize, genz_keister_tablesize > genz_keister_weight_factors((RMatrix< genz_keister_tablesize, genz_keister_tablesize >()<< 1.7724538509055160273,-0.59081795030183867577, 0,-0.36853179227754229196,-0.36295709857235321137, 0, 0, 0, 0.022960325295871627477, 0.064774271955447564196, 0, 0, 0, 0, 0,-0.078993210637533977466,-0.21232194703927159819,-0.2456538225746588462, 0, 0, 0, 0, 0, 0, 0, 0, 0.0069854780851807704795, 0.93317381243987030624, 1.4408446595539685687, 32.462751316915930367, 0, 0.59081795030183867577, 0,-0.099659379601210619666,-0.15492071280527271217, 0, 0, 0,-0.021871890362310419772,-0.087151369618079604908, 0, 0, 0, 0, 0,-0.0084280964777479900247,-0.024959611548050215265,-0.033335853594384873008, 0, 0, 0, 0, 0, 0, 0, 0,-0.00083442479578140975084,-0.19359613215029009931,-0.30341863259901277748,-9.0190236387036132044, 0, 0, 0, 0.0024661361310306921164,-0.0021319596048930450734, 0, 0, 0, 4.0299852847920501352e-05,-0.00016134458352852282233, 0, 0, 0, 0, 0,-2.2985475621124760988e-06,-1.3413229500114444752e-05,-7.0762776783582841311e-05, 0, 0, 0, 0, 0, 0, 0, 0, 9.9226143816067400596e-11,-8.9771296128557796343e-09,-1.5175167948853198633e-08, 8.2790782248066394335e-07, 0, 0, 0, 0.46572503574772221951, 0.49166353523456075667, 0, 0, 0,-0.054992498935111849795,-0.1639032046687536758, 0, 0, 0, 0, 0,-0.030615086786806054104,-0.083704656697661577387,-0.099275694118263682144, 0, 0, 0, 0, 0, 0, 0, 0,-0.010933454407877926348,-1.583559780719271216,-2.4517160773325681828,-57.79911654719117283, 0, 0, 0, 0, 0.028346235747958211943, 0, 0, 0,-0.0034131974823463628108,-0.047397915243750231577, 0, 0, 0, 0, 0, 0.0027516228912164496213, 0.0098895388621464664082, 0.018017220768844287104, 0, 0, 0, 0, 0, 0, 0, 0,-8.2396289613717090217e-07, 0.00069805033976115270287, 0.0011232827256560501634, 0.074544571196262348206, 0, 0, 0, 0, 0, 0, 0, 0, 7.4926939886103445085e-08,-7.1867796345038965618e-08, 0, 0, 0, 0, 0,-2.4809313611998399183e-10, 2.6985146228426857407e-09,-3.8784905914488334667e-09, 0, 0, 0, 0, 0, 0, 0, 0, 2.4377187921244046447e-16,-6.8906698719329670782e-15,-1.3303118025999139614e-14, 1.3222051263169226208e-13, 0, 0, 0, 0, 0, 0, 0, 0, 0.050311651403425852408, 0.16646558769663434605, 0, 0, 0, 0, 0, 0.015121380597001994656, 0.042631804134288498327, 0.052894007283365266033, 0, 0, 0, 0, 0, 0, 0, 0,-0.00228042374526934975,-0.38761835932549071167,-0.60300716658807476412,-15.476251566409639582, 0, 0, 0, 0, 0, 0, 0, 0,-2.908568677413876793e-06, 5.0691221187388293689e-06, 0, 0, 0, 0, 0, 1.7290497100670668627e-08, 2.7120025500606351173e-07,-1.5742878326131491385e-06, 0, 0, 0, 0, 0, 0, 0, 0, 4.1133482077574836997e-13,-1.9592820190556365775e-11,-3.4894317864083047118e-11, 6.7158596618593598195e-10, 0, 0, 0, 0, 0, 0, 0, 0, 0.0069681438693607597638, 0.057142342329530976368, 0, 0, 0, 0, 0,-0.0052916310381902192374,-0.017948738442487162366,-0.029684350935920472511, 0, 0, 0, 0, 0, 0, 0, 0, 3.9407676130575873034e-06, 0.01120796927808146534, 0.017902020219827321149, 0.88400496224987437599, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.010226634878176754698, 0, 0, 0, 0, 0,-0.00054959323707625352453,-0.0021610363202395604912,-0.0046128892358297682251, 0, 0, 0, 0, 0, 0, 0, 0, 6.8201331441269281092e-08,-2.0119651796767681865e-05,-3.272801877689525844e-05,-0.0043094107121951234471, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4.4731291214089043723e-15,-7.9937156824834138633e-15, 3.5243233640534113735e-15, 0, 0, 0, 0, 0, 0, 0, 0,-3.5979073644975835664e-23, 4.5787578394467178907e-22, 1.1823259066197271028e-21,-4.7914913139336527046e-21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.099711523786586315879, 0.26852239716792939686, 0.31153799075718904033, 0, 0, 0, 0, 0, 0, 0, 0,-0.012942205205303980778,-1.7442103174041754507,-2.6939320223251190934,-61.000372377628353199, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-5.2609392917097827721e-13, 1.4704795024993304091e-12,-9.2506568007263991711e-13, 0, 0, 0, 0, 0, 0, 0, 0, 1.5785932351677890194e-20,-2.6338462204337911645e-19,-5.9364547960338525453e-19, 3.2318133244861044316e-18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0062420420705365663879, 0.019823703327519339518, 0.029495272419014293819, 0, 0, 0, 0, 0, 0, 0, 0,-2.8712227378685372603e-05,-0.013023628116982740502,-0.020617469269662274043,-0.77744561213595182479, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.813505764633597492e-11,-8.6698198707035091664e-11, 7.9542508450399069479e-11, 0, 0, 0, 0, 0, 0, 0, 0,-2.4991256866116674136e-18, 5.4084778438692794698e-17, 1.1146766899167308562e-16,-8.1214610992049753868e-16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.333031955787889199e-05, 0.00024173377847937665464, 0.00068064388805162083445, 0, 0, 0, 0, 0, 0, 0, 0,-3.1728953354017843925e-09, 4.8788852162859657901e-07, 8.0598370444025131215e-07,-0.00027432960967869342032, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4.7806686765607031912e-08, 1.2364713155024626226e-07, 0, 0, 0, 0, 0, 0, 0, 0,-1.6391871509412773069e-14, 6.0972774207556211602e-13, 1.1215022650753154351e-12,-1.5601959912306827249e-11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9.6925599474040720024e-06, 0, 0, 0, 0, 0, 0, 0, 0,-5.0478028338888555907e-12, 3.1042162446656135191e-10, 5.3910396570270701411e-10,-1.4997190640433153694e-08, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.966610468031952332e-35,-9.3725229288180246934e-35, 2.8175911769125794736e-34,-2.6791356729768828299e-34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.012234307825621222445, 1.6989572266556452903, 2.6267270916601100203, 60.493525291298403679, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1.7462006007817010057e-33, 6.1064103564975326083e-33,-2.5424116143210707669e-32, 2.6810227097986687364e-32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0062338782069609262528, 0.95288239924914269787, 1.4777893468529787418, 35.875172109135358315, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.6404631535319264035e-32,-1.0083297438305276761e-31, 6.0279502653589950369e-31,-6.9543885865056008569e-31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.0012910899749692758878, 0.25864570545974318927, 0.40406333226476557602, 11.240276946785162355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-1.4853386161233029025e-31, 6.1561988785958881913e-31,-5.8641391245757267453e-30, 7.35654767983557935e-30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00027128436115260543027, 0.075441650507782930325, 0.11863969202649792811, 3.7993742821956509655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2.8439821915492598744e-31,-1.2750675795119443774e-30, 2.5590556531634099977e-29,-3.4795116876601401699e-29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-0.0089789557648437572205,-0.014366120484444668385,-0.75366721653557697842, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4.2040208044811380297e-29, 6.18461706215374787e-29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.00081040558279177164563 ).finished())
const GVector< int, genz_keister_tablesize > genz_keister_zs((GVector< int, genz_keister_tablesize >()<< 0, 0, 1, 0, 0, 3, 2, 1, 0, 0, 5, 4, 3, 2, 1, 0, 0, 0, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0, 0, 0 ).finished())
static NodeMatrix cached_nodes
Definition: genz_keister_qr.hpp:86
std::list< partition_t< D >> partitions_t
Definition: combinatorics.hpp:10
static void calculate_nodes_and_weights()
Precalculate nodes and weights.
Definition: genz_keister_qr.hpp:92
static NodeMatrix nodes()
Return the quadrature nodes.
Definition: genz_keister_qr.hpp:47
static bool cached
Definition: genz_keister_qr.hpp:85
static WeightVector weights()
Return the quadrature weights.
Definition: genz_keister_qr.hpp:57
static dim_t number_nodes()
Return the number of nodes for the given order.
Definition: genz_keister_qr.hpp:38
static real_t weight_for_partition(const math::partition_t< DIM > &part)
Return quadrature weight for given partition.
Definition: genz_keister_qr.hpp:179
std::list< permutation_t< D >> permutations_t
Definition: combinatorics.hpp:14
static const dim_t level
Definition: genz_keister_qr.hpp:29
std::array< int, D > partition_t
Definition: combinatorics.hpp:9
int sum(const point_t< D > Z)
Sum of the components of the point Z.
Definition: combinatorics.hpp:20
int dim_t
Definition: types.hpp:16
Structure providing weighted nodes for Genz-Keister quadrature.
Definition: genz_keister_qr.hpp:26
static NodeMatrix nodes_for_partition(const math::partition_t< DIM > &part)
Return fully symmetric quadrature nodes for given partition.
Definition: genz_keister_qr.hpp:141
static const dim_t D
Definition: genz_keister_qr.hpp:28
const RVector< genz_keister_tablesize > genz_keister_generators((RVector< genz_keister_tablesize >()<< 0.0, 1.2247448713915890491, 2.9592107790638377223, 0.52403354748695764515, 2.0232301911005156592, 4.4995993983103888029, 0.87004089535290290013, 3.66777421594633786, 1.8357079751751868738, 2.2665132620567880275, 6.3759392709822359517, 0.17606414208200893503, 5.6432578578857450628, 1.5794121348467670857, 5.0360899444730939687, 2.5705583765842967091, 4.0292201405043713648, 3.3491639537131949774, 12.371183263294440156, 0.36668252574926773363, 11.773315693849850411, 0.66761453794663251987, 11.279571841264790728, 1.0853772883690724485, 10.839884501585234819, 1.3554874833640409297, 10.435144794449726187, 1.8804002593778771426, 10.055514590896118546, 2.4894835291142853745 ).finished())
static void clear_cache()
Free the precalculated nodes and weights.
Definition: genz_keister_qr.hpp:77