LSST Applications g0265f82a02+0e5473021a,g02d81e74bb+f5613e8b4f,g1470d8bcf6+190ad2ba91,g14a832a312+311607e4ab,g2079a07aa2+86d27d4dc4,g2305ad1205+a8e3196225,g295015adf3+b67ee847e5,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g3ddfee87b4+a761f810f3,g487adcacf7+17c8fdbcbd,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+65b5bd823e,g5a732f18d5+53520f316c,g64a986408d+f5613e8b4f,g6c1bc301e9+51106c2951,g858d7b2824+f5613e8b4f,g8a8a8dda67+585e252eca,g99cad8db69+6729933424,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,ga8c6da7877+ef4e3a5875,gb0e22166c9+60f28cb32d,gb6a65358fc+0e5473021a,gba4ed39666+c2a2e4ac27,gbb8dafda3b+e9bba80f27,gc120e1dc64+eee469a5e5,gc28159a63d+0e5473021a,gcf0d15dbbd+a761f810f3,gdaeeff99f8+f9a426f77a,ge6526c86ff+d4c1d4bfef,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gf1cff7945b+f5613e8b4f,w.2024.16
LSST Data Management Base Package
Loading...
Searching...
No Matches
Classes | Functions
lsst::afw::math::details Namespace Reference

Classes

struct  AuxFunc1
 Auxiliary struct 1. More...
 
struct  AuxFunc2
 
class  binder2_1
 
class  binder3_1
 
class  Int2DAuxType
 
class  Int3DAuxType
 

Functions

template<class T >
norm (const T &x)
 
template<class T >
real (const T &x)
 
template<class T >
Epsilon ()
 
template<class T >
MinRep ()
 
template<class T >
rescale_error (T err, T const &resabs, T const &resasc)
 
template<typename UnaryFunctionT , typename Arg >
bool intGKPNA (UnaryFunctionT func, IntRegion< Arg > &reg, Arg const epsabs, Arg const epsrel, std::map< Arg, Arg > *fxmap=nullptr)
 Non-adaptive integration of the function f over the region 'reg'.
 
template<typename UnaryFunctionT , typename Arg >
void intGKP (UnaryFunctionT func, IntRegion< Arg > &reg, Arg const epsabs, Arg const epsrel, std::map< Arg, Arg > *fxmap=nullptr)
 An adaptive integration algorithm which computes the integral of f over the region reg.
 
template<class UF >
AuxFunc1< UF > Aux1 (UF uf)
 Auxiliary function 1.
 
template<class UF >
AuxFunc2< UF > Aux2 (UF uf)
 Auxiliary function 2.
 
template<class BF , class Tp >
binder2_1< BF > bind21 (const BF &oper, const Tp &x)
 
template<class TF , class Tp >
binder3_1< TF > bind31 (const TF &oper, const Tp &x)
 
int gkp_n (int level)
 
template<class T >
const std::vector< T > & gkp_x (int level)
 
template<class T >
const std::vector< T > & gkp_wa (int level)
 
template<class T >
const std::vector< T > & gkp_wb (int level)
 

Function Documentation

◆ Aux1()

template<class UF >
AuxFunc1< UF > lsst::afw::math::details::Aux1 ( UF uf)
inline

Auxiliary function 1.

Definition at line 587 of file Integrate.h.

587 {
588 return AuxFunc1<UF>(uf);
589}

◆ Aux2()

template<class UF >
AuxFunc2< UF > lsst::afw::math::details::Aux2 ( UF uf)
inline

Auxiliary function 2.

Definition at line 608 of file Integrate.h.

608 {
609 return AuxFunc2<UF>(uf);
610}

◆ bind21()

template<class BF , class Tp >
binder2_1< BF > lsst::afw::math::details::bind21 ( const BF & oper,
const Tp & x )
inline

Definition at line 628 of file Integrate.h.

628 {
629 using Arg = typename BF::first_argument_type;
630 return binder2_1<BF>(oper, static_cast<Arg>(x));
631}

◆ bind31()

template<class TF , class Tp >
binder3_1< TF > lsst::afw::math::details::bind31 ( const TF & oper,
const Tp & x )
inline

Definition at line 670 of file Integrate.h.

670 {
671 using Arg = typename TF::firstof3_argument_type;
672 return binder3_1<TF>(oper, static_cast<Arg>(x));
673}

◆ Epsilon()

template<class T >
T lsst::afw::math::details::Epsilon ( )
inline

Definition at line 244 of file Integrate.h.

244 {
246}
T epsilon(T... args)

◆ gkp_n()

int lsst::afw::math::details::gkp_n ( int level)
inline

Definition at line 47 of file IntGKPData10.h.

47 {
48 assert(level >= 0 && level < NGKPLEVELS);
49 static const int ngkp[NGKPLEVELS] = {5, 5, 11, 22, 44};
50 return ngkp[level];
51}

◆ gkp_wa()

template<class T >
const std::vector< T > & lsst::afw::math::details::gkp_wa ( int level)
inline

Definition at line 116 of file IntGKPData10.h.

116 {
117 // w21a, weights of the 21-point formula for abscissae x10
118 static const T aw21a[5] = {0.032558162307964727478818972459390, 0.075039674810919952767043140916190,
119 0.109387158802297641899210590325805, 0.134709217311473325928054001771707,
120 0.147739104901338491374841515972068};
121 static const std::vector<T> vw21a(aw21a, aw21a + 5);
122
123 // w43a, weights of the 43-point formula for abscissae x10,x21
124 static const T aw43a[10] = {0.016296734289666564924281974617663, 0.037522876120869501461613795898115,
125 0.054694902058255442147212685465005, 0.067355414609478086075553166302174,
126 0.073870199632393953432140695251367, 0.005768556059769796184184327908655,
127 0.027371890593248842081276069289151, 0.046560826910428830743339154433824,
128 0.061744995201442564496240336030883, 0.071387267268693397768559114425516};
129 static const std::vector<T> vw43a(aw43a, aw43a + 10);
130
131 // w87a, weights of the 87-point formula for abscissae x10..x43
132 static const T aw87a[21] = {0.008148377384149172900002878448190, 0.018761438201562822243935059003794,
133 0.027347451050052286161582829741283, 0.033677707311637930046581056957588,
134 0.036935099820427907614589586742499, 0.002884872430211530501334156248695,
135 0.013685946022712701888950035273128, 0.023280413502888311123409291030404,
136 0.030872497611713358675466394126442, 0.035693633639418770719351355457044,
137 0.000915283345202241360843392549948, 0.005399280219300471367738743391053,
138 0.010947679601118931134327826856808, 0.016298731696787335262665703223280,
139 0.021081568889203835112433060188190, 0.025370969769253827243467999831710,
140 0.029189697756475752501446154084920, 0.032373202467202789685788194889595,
141 0.034783098950365142750781997949596, 0.036412220731351787562801163687577,
142 0.037253875503047708539592001191226};
143 static const std::vector<T> vw87a(aw87a, aw87a + 21);
144
145 // w175a, weights of the 175-point formula for abscissae x10..x87
146 static const T aw175a[43] = {
147 0.004074188692082600103872341, 0.009380719100781411819741177, 0.01367372552502614309257226,
148 0.01683885365581896502443513, 0.01846754991021395380770806, 0.001442436294030254510518689,
149 0.006842973011356375224430623, 0.01164020675144415562952859, 0.01543624880585667934076834,
150 0.01784681681970938536027839, 0.0004576754584154192941064591, 0.002699640110136963534043642,
151 0.005473839800559775445647306, 0.008149365848393670964180954, 0.01054078444460191775302900,
152 0.01268548488462691364854167, 0.01459484887823787625642303, 0.01618660123360139484467359,
153 0.01739154947518257137619173, 0.01820611036567589378188459, 0.01862693775152385427017140,
154 0.0001363171844264931156688042, 0.0009035606060432074452289352, 0.002048434635928091782250346,
155 0.003379145025868061092978424, 0.004774978836099393880602724, 0.006164723826122346701274159,
156 0.007505223673194467726814647, 0.008774483993121594091281642, 0.009969018893220443741650500,
157 0.01109746798050614328494604, 0.01216957356300040269315573, 0.01318725270741960360319771,
158 0.01414345539438560032188640, 0.01502629056404634765715107, 0.01582337568571996469999659,
159 0.01652520670998925164398162, 0.01712754985211303089259342, 0.01763120633007834051620255,
160 0.01803849481144435059221422, 0.01834930224922804724856518, 0.01856027463491628805666919,
161 0.01866711437596752016025132};
162 static const std::vector<T> vw175a(aw175a, aw175a + 43);
163
164 static const std::vector<T>* wa[NGKPLEVELS] = {nullptr, &vw21a, &vw43a, &vw87a, &vw175a};
165
166 assert(level >= 1 && level < NGKPLEVELS);
167 return *wa[level];
168}

◆ gkp_wb()

template<class T >
const std::vector< T > & lsst::afw::math::details::gkp_wb ( int level)
inline

Definition at line 171 of file IntGKPData10.h.

171 {
172 // w10, weights of the 10-point formula
173 static const T aw10b[6] = {0.066671344308688137593568809893332, 0.149451349150580593145776339657697,
174 0.219086362515982043995534934228163, 0.269266719309996355091226921569469,
175 0.295524224714752870173892994651338, 0.0};
176 static const std::vector<T> vw10b(aw10b, aw10b + 6);
177
178 // w21b, weights of the 21-point formula for abscissae x21
179 static const T aw21b[6] = {0.011694638867371874278064396062192, 0.054755896574351996031381300244580,
180 0.093125454583697605535065465083366, 0.123491976262065851077958109831074,
181 0.142775938577060080797094273138717, 0.149445554002916905664936468389821};
182 static const std::vector<T> vw21b(aw21b, aw21b + 6);
183
184 // w43b, weights of the 43-point formula for abscissae x43
185 static const T aw43b[12] = {0.001844477640212414100389106552965, 0.010798689585891651740465406741293,
186 0.021895363867795428102523123075149, 0.032597463975345689443882222526137,
187 0.042163137935191811847627924327955, 0.050741939600184577780189020092084,
188 0.058379395542619248375475369330206, 0.064746404951445885544689259517511,
189 0.069566197912356484528633315038405, 0.072824441471833208150939535192842,
190 0.074507751014175118273571813842889, 0.074722147517403005594425168280423};
191 static const std::vector<T> vw43b(aw43b, aw43b + 12);
192
193 // w87b, weights of the 87-point formula for abscissae x87
194 static const T aw87b[23] = {0.000274145563762072350016527092881, 0.001807124155057942948341311753254,
195 0.004096869282759164864458070683480, 0.006758290051847378699816577897424,
196 0.009549957672201646536053581325377, 0.012329447652244853694626639963780,
197 0.015010447346388952376697286041943, 0.017548967986243191099665352925900,
198 0.019938037786440888202278192730714, 0.022194935961012286796332102959499,
199 0.024339147126000805470360647041454, 0.026374505414839207241503786552615,
200 0.028286910788771200659968002987960, 0.030052581128092695322521110347341,
201 0.031646751371439929404586051078883, 0.033050413419978503290785944862689,
202 0.034255099704226061787082821046821, 0.035262412660156681033782717998428,
203 0.036076989622888701185500318003895, 0.036698604498456094498018047441094,
204 0.037120549269832576114119958413599, 0.037334228751935040321235449094698,
205 0.037361073762679023410321241766599};
206 static const std::vector<T> vw87b(aw87b, aw87b + 23);
207
208 // w175b, weights of the 175-point formula for abscissae x175
209 static const T aw175b[45] = {
210 0.00003901440664395060055484226, 0.0002787312407993348139961464, 0.0006672934146291138823512275,
211 0.001163051749910003055308177, 0.001738533916888715565420637, 0.002369555040550195269486165,
212 0.003036735036032612976379865, 0.003725394125884235586678819, 0.004424387541776355951933433,
213 0.005125062882078508655875582, 0.005820601038952832388647054, 0.006505667785357412495794539,
214 0.007176258976795165213169074, 0.007829642423806550517967042, 0.008464316525043036555640657,
215 0.009079917879101951192512711, 0.009677029304308397008134699, 0.01025687419430508685393322,
216 0.01082092935368957685380896, 0.01137052956179654620079332, 0.01190655150082017425918844,
217 0.01242924137407215963971061, 0.01293819980598456566872951, 0.01343248644726851711632966,
218 0.01391078107864287587682982, 0.01437154592198526807352501, 0.01481316256915705351874381,
219 0.01523404482122031244940129, 0.01563274056894636856297717, 0.01600802989372176552081826,
220 0.01635901148521841710605397, 0.01668515675646806540972517, 0.01698630892029276765404134,
221 0.01726261506199017604299177, 0.01751439915887340284018269, 0.01774200489411242260549908,
222 0.01794564958245060930824294, 0.01812532816637054898168673, 0.01828078919412312732671357,
223 0.01841158014800801587767163, 0.01851713825962505903167768, 0.01859689376712028821908313,
224 0.01865035760791320287947920, 0.01867717982648033250824110, 0.01868053688133951170552407};
225 static const std::vector<T> vw175b(aw175b, aw175b + 45);
226
227 static const std::vector<T>* wb[NGKPLEVELS] = {&vw10b, &vw21b, &vw43b, &vw87b, &vw175b};
228
229 assert(level >= 0 && level < NGKPLEVELS);
230 return *wb[level];
231}

◆ gkp_x()

template<class T >
const std::vector< T > & lsst::afw::math::details::gkp_x ( int level)
inline

Definition at line 54 of file IntGKPData10.h.

54 {
55 // x10, abscissae common to the 10-, 21-, 43- and 87-point rule
56 static const T ax10[5] = {0.973906528517171720077964012084452, 0.865063366688984510732096688423493,
57 0.679409568299024406234327365114874, 0.433395394129247190799265943165784,
58 0.148874338981631210884826001129720};
59 static const std::vector<T> vx10(ax10, ax10 + 5);
60
61 // x21, abscissae common to the 21-, 43- and 87-point rule
62 static const T ax21[5] = {0.995657163025808080735527280689003, 0.930157491355708226001207180059508,
63 0.780817726586416897063717578345042, 0.562757134668604683339000099272694,
64 0.294392862701460198131126603103866};
65 static const std::vector<T> vx21(ax21, ax21 + 5);
66
67 // x43, abscissae common to the 43- and 87-point rule
68 static const T ax43[11] = {0.999333360901932081394099323919911, 0.987433402908088869795961478381209,
69 0.954807934814266299257919200290473, 0.900148695748328293625099494069092,
70 0.825198314983114150847066732588520, 0.732148388989304982612354848755461,
71 0.622847970537725238641159120344323, 0.499479574071056499952214885499755,
72 0.364901661346580768043989548502644, 0.222254919776601296498260928066212,
73 0.074650617461383322043914435796506};
74 static const std::vector<T> vx43(ax43, ax43 + 11);
75
76 // x87, abscissae of the 87-point rule
77 static const T ax87[22] = {0.999902977262729234490529830591582, 0.997989895986678745427496322365960,
78 0.992175497860687222808523352251425, 0.981358163572712773571916941623894,
79 0.965057623858384619128284110607926, 0.943167613133670596816416634507426,
80 0.915806414685507209591826430720050, 0.883221657771316501372117548744163,
81 0.845710748462415666605902011504855, 0.803557658035230982788739474980964,
82 0.757005730685495558328942793432020, 0.706273209787321819824094274740840,
83 0.651589466501177922534422205016736, 0.593223374057961088875273770349144,
84 0.531493605970831932285268948562671, 0.466763623042022844871966781659270,
85 0.399424847859218804732101665817923, 0.329874877106188288265053371824597,
86 0.258503559202161551802280975429025, 0.185695396568346652015917141167606,
87 0.111842213179907468172398359241362, 0.037352123394619870814998165437704};
88 static const std::vector<T> vx87(ax87, ax87 + 22);
89
90 // x175, new abscissae of the 175-point rule
91 static const T ax175[44] = {
92 0.9999863601049729677997719, 0.9996988005421428623760900, 0.9987732473138838303043008,
93 0.9969583851613681945576954, 0.9940679446543307664316419, 0.9899673391741082769960501,
94 0.9845657252243253759726856, 0.9778061574856414566055911, 0.9696573134362640567828241,
95 0.9601075259508299668299148, 0.9491605191933640559839528, 0.9368321320434676982049391,
96 0.9231475266471484946315312, 0.9081385954543932335481458, 0.8918414554201179766275301,
97 0.8742940658668577971868106, 0.8555341249920432726468181, 0.8355974653331171075829366,
98 0.8145171513255796294567278, 0.7923233739697216224661771, 0.7690440708082055924983192,
99 0.7447060413364141221086362, 0.7193362474393392286563226, 0.6929630148748741413274435,
100 0.6656169582351898081906710, 0.6373315753624730450361940, 0.6081435407529742253347887,
101 0.5780927509986774074337714, 0.5472221576559162873479056, 0.5155774001694817879753989,
102 0.4832062516695473663839323, 0.4501579202236101928554315, 0.4164822936334372150371142,
103 0.3822292525735955063074986, 0.3474481818229070516859048, 0.3121877718977455143765043,
104 0.2764961311348905899785770, 0.2404211453027010909070665, 0.2040109589145005126324680,
105 0.1673144327616352753945014, 0.1303814601095591675431696, 0.09326308333660176874846400,
106 0.05601141598806823374241435, 0.01867941779948308845140053};
107 static const std::vector<T> vx175(ax175, ax175 + 44);
108
109 static const std::vector<T>* x[NGKPLEVELS] = {&vx10, &vx21, &vx43, &vx87, &vx175};
110
111 assert(level >= 0 && level < NGKPLEVELS);
112 return *x[level];
113}

◆ intGKP()

template<typename UnaryFunctionT , typename Arg >
void lsst::afw::math::details::intGKP ( UnaryFunctionT func,
IntRegion< Arg > & reg,
Arg const epsabs,
Arg const epsrel,
std::map< Arg, Arg > * fxmap = nullptr )
inline

An adaptive integration algorithm which computes the integral of f over the region reg.

Note
First the non-adaptive GKP algorithm is tried. If that is not accurate enough (according to the absolute and relative accuracies, epsabs and epsrel), the region is split in half, and each new region is integrated. The routine continues by successively splitting the subregion which gave the largest absolute error until the integral converges.

The area and estimated error are returned as reg.Area() and reg.Err() If desired, *retx and *retf return std::vectors of x,f(x) respectively They only include the evaluations in the non-adaptive pass, so they do not give an accurate estimate of the number of function evaluations.

Definition at line 426 of file Integrate.h.

428 {
429 integ_dbg2 << "Start intGKP\n";
430
431 assert(epsabs >= 0.0);
432 assert(epsrel > 0.0);
433
434 // perform the first integration
435 bool done = intGKPNA(func, reg, epsabs, epsrel, fxmap);
436 if (done) return;
437
438 integ_dbg2 << "In adaptive GKP, failed first pass... subdividing\n";
439 integ_dbg2 << "Intial range = " << reg.Left() << ".." << reg.Right() << std::endl;
440
441 int roundoffType1 = 0, errorType = 0;
442 Arg roundoffType2 = 0;
443 size_t iteration = 1;
444
446 allregions.push(reg);
447 Arg finalarea = reg.Area();
448 Arg finalerr = reg.Err();
449 Arg tolerance = std::max(epsabs, epsrel * fabs(finalarea));
450 assert(finalerr > tolerance);
451
452 while (!errorType && finalerr > tolerance) {
453 // Bisect the subinterval with the largest error estimate
454 integ_dbg2 << "Current answer = " << finalarea << " +- " << finalerr;
455 integ_dbg2 << " (tol = " << tolerance << ")\n";
456 IntRegion<Arg> parent = allregions.top();
457 allregions.pop();
458 integ_dbg2 << "Subdividing largest error region ";
459 integ_dbg2 << parent.Left() << ".." << parent.Right() << std::endl;
460 integ_dbg2 << "parent area = " << parent.Area();
461 integ_dbg2 << " +- " << parent.Err() << std::endl;
463 parent.SubDivide(&children);
464 // For "GKP", there are only two, but for GKPOSC, there is one
465 // for each oscillation in region
466
467 // Try to do at least 3x better with the children
468 Arg factor = 3 * children.size() * finalerr / tolerance;
469 Arg newepsabs = fabs(parent.Err() / factor);
470 Arg newepsrel = newepsabs / fabs(parent.Area());
471 integ_dbg2 << "New epsabs, rel = " << newepsabs << ", " << newepsrel;
472 integ_dbg2 << " (" << children.size() << " children)\n";
473
474 Arg newarea = Arg(0.0);
475 Arg newerror = 0.0;
476 for (size_t i = 0; i < children.size(); i++) {
477 IntRegion<Arg> &child = children[i];
478 integ_dbg2 << "Integrating child " << child.Left();
479 integ_dbg2 << ".." << child.Right() << std::endl;
480 bool hasConverged;
481 hasConverged = intGKPNA(func, child, newepsabs, newepsrel);
482 integ_dbg2 << "child (" << i + 1 << '/' << children.size() << ") ";
483 if (hasConverged) {
484 integ_dbg2 << " converged.";
485 } else {
486 integ_dbg2 << " failed.";
487 }
488 integ_dbg2 << " Area = " << child.Area() << " +- " << child.Err() << std::endl;
489
490 newarea += child.Area();
491 newerror += child.Err();
492 }
493 integ_dbg2 << "Compare: newerr = " << newerror;
494 integ_dbg2 << " to parent err = " << parent.Err() << std::endl;
495
496 finalerr += (newerror - parent.Err());
497 finalarea += newarea - parent.Area();
498
499 Arg delta = parent.Area() - newarea;
500 if (newerror <= parent.Err() && fabs(delta) <= parent.Err() && newerror >= 0.99 * parent.Err()) {
501 integ_dbg2 << "roundoff type 1: delta/newarea = ";
502 integ_dbg2 << fabs(delta) / fabs(newarea);
503 integ_dbg2 << ", newerror/error = " << newerror / parent.Err() << std::endl;
504 roundoffType1++;
505 }
506 if (iteration >= 10 && newerror > parent.Err() && fabs(delta) <= newerror - parent.Err()) {
507 integ_dbg2 << "roundoff type 2: newerror/error = ";
508 integ_dbg2 << newerror / parent.Err() << std::endl;
509 roundoffType2 += std::min(newerror / parent.Err() - 1.0, Arg(1.0));
510 }
511
512 tolerance = std::max(epsabs, epsrel * fabs(finalarea));
513 if (finalerr > tolerance) {
514 if (roundoffType1 >= 200) {
515 errorType = 1; // round off error
516 integ_dbg2 << "GKP: Round off error 1\n";
517 }
518 if (roundoffType2 >= 200.0) {
519 errorType = 2; // round off error
520 integ_dbg2 << "GKP: Round off error 2\n";
521 }
522 if (fabs((parent.Right() - parent.Left()) / (reg.Right() - reg.Left())) < Epsilon<double>()) {
523 errorType = 3; // found singularity
524 integ_dbg2 << "GKP: Probable singularity\n";
525 }
526 }
527 for (size_t i = 0; i < children.size(); i++) {
528 allregions.push(children[i]);
529 }
530 iteration++;
531 }
532
533 // Recalculate finalarea in case there are any slight rounding errors
534 finalarea = 0.0;
535 finalerr = 0.0;
536 while (!allregions.empty()) {
537 IntRegion<Arg> const &r = allregions.top();
538 finalarea += r.Area();
539 finalerr += r.Err();
540 allregions.pop();
541 }
542 reg.SetArea(finalarea, finalerr);
543
544 if (errorType == 1) {
546 s << "Type 1 roundoff's = " << roundoffType1;
547 s << ", Type 2 = " << roundoffType2 << std::endl;
548 s << "Roundoff error 1 prevents tolerance from being achieved ";
549 s << "in intGKP\n";
551 } else if (errorType == 2) {
553 s << "Type 1 roundoff's = " << roundoffType1;
554 s << ", Type 2 = " << roundoffType2 << std::endl;
555 s << "Roundoff error 2 prevents tolerance from being achieved ";
556 s << "in intGKP\n";
558 } else if (errorType == 3) {
560 s << "Bad integrand behavior found in the integration interval ";
561 s << "in intGKP\n";
563 }
564}
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
#define integ_dbg2
Definition Integrate.h:149
Reports errors that are due to events beyond the control of the program.
Definition Runtime.h:104
T empty(T... args)
T endl(T... args)
T fabs(T... args)
T max(T... args)
T min(T... args)
bool intGKPNA(UnaryFunctionT func, IntRegion< Arg > &reg, Arg const epsabs, Arg const epsrel, std::map< Arg, Arg > *fxmap=nullptr)
Non-adaptive integration of the function f over the region 'reg'.
Definition Integrate.h:298
T pop(T... args)
T push(T... args)
T size(T... args)
void SetArea(const T &a, const T &e)
Definition Integrate.h:225
T const & Err() const
Definition Integrate.h:223
T const & Area() const
Definition Integrate.h:224
void SubDivide(std::vector< IntRegion< T > > *children)
Definition Integrate.h:189
T const & Right() const
Definition Integrate.h:222
T const & Left() const
Definition Integrate.h:221
T top(T... args)

◆ intGKPNA()

template<typename UnaryFunctionT , typename Arg >
bool lsst::afw::math::details::intGKPNA ( UnaryFunctionT func,
IntRegion< Arg > & reg,
Arg const epsabs,
Arg const epsrel,
std::map< Arg, Arg > * fxmap = nullptr )
inline

Non-adaptive integration of the function f over the region 'reg'.

Note
The algorithm computes first a Gaussian quadrature value then successive Kronrod/Patterson extensions to this result. The functions terminates when the difference between successive approximations (rescaled according to rescale_error) is less than either epsabs or epsrel * I, where I is the latest estimate of the integral. The order of the Gauss/Kronron/Patterson scheme is determined by which file is included above. Currently schemes starting with order 1 and order 10 are calculated. There seems to be little practical difference in the integration times using the two schemes, so I haven't bothered to calculate any more.

Definition at line 298 of file Integrate.h.

300 {
301 Arg const a = reg.Left();
302 Arg const b = reg.Right();
303
304 Arg const halfLength = 0.5 * (b - a);
305 Arg const absHalfLength = fabs(halfLength);
306 Arg const center = 0.5 * (b + a);
307 Arg const fCenter = func(center);
308#ifdef COUNTFEVAL
309 nfeval++;
310#endif
311
312 assert(gkp_wb<Arg>(0).size() == gkp_x<Arg>(0).size() + 1);
313 Arg area1 = gkp_wb<Arg>(0).back() * fCenter;
314 std::vector<Arg> fv1, fv2;
315 fv1.reserve(2 * gkp_x<Arg>(0).size() + 1);
316 fv2.reserve(2 * gkp_x<Arg>(0).size() + 1);
317 for (size_t k = 0; k < gkp_x<Arg>(0).size(); k++) {
318 Arg const abscissa = halfLength * gkp_x<Arg>(0)[k];
319 Arg const fval1 = func(center - abscissa);
320 Arg const fval2 = func(center + abscissa);
321 area1 += gkp_wb<Arg>(0)[k] * (fval1 + fval2);
322 fv1.push_back(fval1);
323 fv2.push_back(fval2);
324 if (fxmap) {
325 (*fxmap)[center - abscissa] = fval1;
326 (*fxmap)[center + abscissa] = fval2;
327 }
328 }
329#ifdef COUNTFEVAL
330 nfeval += gkp_x<Arg>(0).size() * 2;
331#endif
332
333 integ_dbg2 << "level 0 rule: area = " << area1 << std::endl;
334
335 Arg err = 0;
336 bool calcabsasc = true;
337 Arg resabs = 0.0, resasc = 0.0;
338 for (int level = 1; level < NGKPLEVELS; level++) {
339 assert(gkp_wa<Arg>(level).size() == fv1.size());
340 assert(gkp_wa<Arg>(level).size() == fv2.size());
341 assert(gkp_wb<Arg>(level).size() == gkp_x<Arg>(level).size() + 1);
342 Arg area2 = gkp_wb<Arg>(level).back() * fCenter;
343 // resabs = approximation to integral of abs(f)
344 if (calcabsasc) {
345 resabs = fabs(area2);
346 }
347 for (size_t k = 0; k < fv1.size(); k++) {
348 area2 += gkp_wa<Arg>(level)[k] * (fv1[k] + fv2[k]);
349 if (calcabsasc) {
350 resabs += gkp_wa<Arg>(level)[k] * (fabs(fv1[k]) + fabs(fv2[k]));
351 }
352 }
353 for (size_t k = 0; k < gkp_x<Arg>(level).size(); k++) {
354 Arg const abscissa = halfLength * gkp_x<Arg>(level)[k];
355 Arg const fval1 = func(center - abscissa);
356 Arg const fval2 = func(center + abscissa);
357 Arg const fval = fval1 + fval2;
358 area2 += gkp_wb<Arg>(level)[k] * fval;
359 if (calcabsasc) {
360 resabs += gkp_wb<Arg>(level)[k] * (fabs(fval1) + fabs(fval2));
361 }
362 fv1.push_back(fval1);
363 fv2.push_back(fval2);
364 if (fxmap) {
365 (*fxmap)[center - abscissa] = fval1;
366 (*fxmap)[center + abscissa] = fval2;
367 }
368 }
369#ifdef COUNTFEVAL
370 nfeval += gkp_x<Arg>(level).size() * 2;
371#endif
372 if (calcabsasc) {
373 Arg const mean = area1 * Arg(0.5);
374 // resasc = approximation to the integral of abs(f-mean)
375 resasc = gkp_wb<Arg>(level).back() * fabs(fCenter - mean);
376 for (size_t k = 0; k < gkp_wa<Arg>(level).size(); k++) {
377 resasc += gkp_wa<Arg>(level)[k] * (fabs(fv1[k] - mean) + fabs(fv2[k] - mean));
378 }
379 for (size_t k = 0; k < gkp_x<Arg>(level).size(); k++) {
380 resasc += gkp_wb<Arg>(level)[k] * (fabs(fv1[k] - mean) + fabs(fv2[k] - mean));
381 }
382 resasc *= absHalfLength;
383 resabs *= absHalfLength;
384 }
385 area2 *= halfLength;
386 err = rescale_error(fabs(area2 - area1), resabs, resasc);
387 if (err < resasc) {
388 calcabsasc = false;
389 }
390
391 integ_dbg2 << "at level " << level << " area2 = " << area2;
392 integ_dbg2 << " +- " << err << std::endl;
393
394 // test for convergence.
395 if (err < epsabs || err < epsrel * fabs(area2)) {
396 reg.SetArea(area2, err);
397 return true;
398 }
399 area1 = area2;
400 }
401
402 // failed to converge
403 reg.SetArea(area1, err);
404
405 integ_dbg2 << "Failed to reach tolerance with highest-order GKP rule";
406
407 return false;
408}
table::Key< int > b
table::Key< int > a
T rescale_error(T err, T const &resabs, T const &resasc)
Definition Integrate.h:264
T push_back(T... args)
T reserve(T... args)

◆ MinRep()

template<class T >
T lsst::afw::math::details::MinRep ( )
inline

Definition at line 248 of file Integrate.h.

248 {
250}

◆ norm()

template<class T >
T lsst::afw::math::details::norm ( const T & x)
inline

Definition at line 160 of file Integrate.h.

160 {
161 return x * x;
162}

◆ real()

template<class T >
T lsst::afw::math::details::real ( const T & x)
inline

Definition at line 165 of file Integrate.h.

165 {
166 return x;
167}

◆ rescale_error()

template<class T >
T lsst::afw::math::details::rescale_error ( T err,
T const & resabs,
T const & resasc )
inline

Definition at line 264 of file Integrate.h.

264 {
265 if (resasc != 0.0 && err != 0.0) {
266 T const scale = (200.0 * err / resasc);
267 if (scale < 1.0) {
268 err = resasc * scale * sqrt(scale);
269 } else {
270 err = resasc;
271 }
272 }
273 if (resabs > MinRep<T>() / (50.0 * Epsilon<T>())) {
274 T const min_err = 50.0 * Epsilon<T>() * resabs;
275 if (min_err > err) {
276 err = min_err;
277 }
278 }
279 return err;
280}