Lemma is an Electromagnetics API
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

GQChave.cpp 42KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165
  1. /* This file is part of Lemma, a geophysical modelling and inversion API */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /**
  6. @file
  7. @author Trevor Irons
  8. @date 01/02/2010
  9. @version $Id: hankeltransformgaussianquadrature.cpp 200 2014-12-29 21:11:55Z tirons $
  10. **/
  11. // Description: Port of Alan Chave's gaussian quadrature algorithm, which
  12. // is public domain, code listed in published article:
  13. // Chave, A. D., 1983, Numerical integration of related Hankel transforms by
  14. // quadrature and continued fraction expansion: Geophysics, 48
  15. // 1671--1686 doi: 10.1190/1.1441448
  16. #include "GQChave.h"
  17. namespace Lemma{
  18. std::ostream &operator<<(std::ostream &stream, const GQChave &ob) {
  19. stream << ob.Serialize() << "\n";
  20. return stream;
  21. }
  22. // Initialise static members
  23. const VectorXr GQChave::WT =
  24. (VectorXr(254) << // (WT(I),I=1,20)
  25. 0.55555555555555555556e+00,0.88888888888888888889e+00,
  26. 0.26848808986833344073e+00,0.10465622602646726519e+00,
  27. 0.40139741477596222291e+00,0.45091653865847414235e+00,
  28. 0.13441525524378422036e+00,0.51603282997079739697e-01,
  29. 0.20062852937698902103e+00,0.17001719629940260339e-01,
  30. 0.92927195315124537686e-01,0.17151190913639138079e+00,
  31. 0.21915685840158749640e+00,0.22551049979820668739e+00,
  32. 0.67207754295990703540e-01,0.25807598096176653565e-01,
  33. 0.10031427861179557877e+00,0.84345657393211062463e-02,
  34. 0.46462893261757986541e-01,0.85755920049990351154e-01,
  35. // (WT(I),I=21,40)
  36. 0.10957842105592463824e+00,0.25447807915618744154e-02,
  37. 0.16446049854387810934e-01,0.35957103307129322097e-01,
  38. 0.56979509494123357412e-01,0.76879620499003531043e-01,
  39. 0.93627109981264473617e-01,0.10566989358023480974e+00,
  40. 0.11195687302095345688e+00,0.11275525672076869161e+00,
  41. 0.33603877148207730542e-01,0.12903800100351265626e-01,
  42. 0.50157139305899537414e-01,0.42176304415588548391e-02,
  43. 0.23231446639910269443e-01,0.42877960025007734493e-01,
  44. 0.54789210527962865032e-01,0.12651565562300680114e-02,
  45. 0.82230079572359296693e-02,0.17978551568128270333e-01,
  46. // (WT(I),I=41,60)
  47. 0.28489754745833548613e-01,0.38439810249455532039e-01,
  48. 0.46813554990628012403e-01,0.52834946790116519862e-01,
  49. 0.55978436510476319408e-01,0.36322148184553065969e-03,
  50. 0.25790497946856882724e-02,0.61155068221172463397e-02,
  51. 0.10498246909621321898e-01,0.15406750466559497802e-01,
  52. 0.20594233915912711149e-01,0.25869679327214746911e-01,
  53. 0.31073551111687964880e-01,0.36064432780782572640e-01,
  54. 0.40715510116944318934e-01,0.44914531653632197414e-01,
  55. 0.48564330406673198716e-01,0.51583253952048458777e-01,
  56. 0.53905499335266063927e-01,0.55481404356559363988e-01,
  57. // (WT(I),I=61,80)
  58. 0.56277699831254301273e-01,0.56377628360384717388e-01,
  59. 0.16801938574103865271e-01,0.64519000501757369228e-02,
  60. 0.25078569652949768707e-01,0.21088152457266328793e-02,
  61. 0.11615723319955134727e-01,0.21438980012503867246e-01,
  62. 0.27394605263981432516e-01,0.63260731936263354422e-03,
  63. 0.41115039786546930472e-02,0.89892757840641357233e-02,
  64. 0.14244877372916774306e-01,0.19219905124727766019e-01,
  65. 0.23406777495314006201e-01,0.26417473395058259931e-01,
  66. 0.27989218255238159704e-01,0.18073956444538835782e-03,
  67. 0.12895240826104173921e-02,0.30577534101755311361e-02,
  68. // (WT(I),I=81,100)
  69. 0.52491234548088591251e-02,0.77033752332797418482e-02,
  70. 0.10297116957956355524e-01,0.12934839663607373455e-01,
  71. 0.15536775555843982440e-01,0.18032216390391286320e-01,
  72. 0.20357755058472159467e-01,0.22457265826816098707e-01,
  73. 0.24282165203336599358e-01,0.25791626976024229388e-01,
  74. 0.26952749667633031963e-01,0.27740702178279681994e-01,
  75. 0.28138849915627150636e-01,0.50536095207862517625e-04,
  76. 0.37774664632698466027e-03,0.93836984854238150079e-03,
  77. 0.16811428654214699063e-02,0.25687649437940203731e-02,
  78. 0.35728927835172996494e-02,0.46710503721143217474e-02,
  79. // (WT(I),I=101,120)
  80. 0.58434498758356395076e-02,0.70724899954335554680e-02,
  81. 0.83428387539681577056e-02,0.96411777297025366953e-02,
  82. 0.10955733387837901648e-01,0.12275830560082770087e-01,
  83. 0.13591571009765546790e-01,0.14893641664815182035e-01,
  84. 0.16173218729577719942e-01,0.17421930159464173747e-01,
  85. 0.18631848256138790186e-01,0.19795495048097499488e-01,
  86. 0.20905851445812023852e-01,0.21956366305317824939e-01,
  87. 0.22940964229387748761e-01,0.23854052106038540080e-01,
  88. 0.24690524744487676909e-01,0.25445769965464765813e-01,
  89. 0.26115673376706097680e-01,0.26696622927450359906e-01,
  90. // (WT(I),I=121,140)
  91. 0.27185513229624791819e-01,0.27579749566481873035e-01,
  92. 0.27877251476613701609e-01,0.28076455793817246607e-01,
  93. 0.28176319033016602131e-01,0.28188814180192358694e-01,
  94. 0.84009692870519326354e-02,0.32259500250878684614e-02,
  95. 0.12539284826474884353e-01,0.10544076228633167722e-02,
  96. 0.58078616599775673635e-02,0.10719490006251933623e-01,
  97. 0.13697302631990716258e-01,0.31630366082226447689e-03,
  98. 0.20557519893273465236e-02,0.44946378920320678616e-02,
  99. 0.71224386864583871532e-02,0.96099525623638830097e-02,
  100. 0.11703388747657003101e-01,0.13208736697529129966e-01,
  101. // (WT(I),I=141,160)
  102. 0.13994609127619079852e-01,0.90372734658751149261e-04,
  103. 0.64476204130572477933e-03,0.15288767050877655684e-02,
  104. 0.26245617274044295626e-02,0.38516876166398709241e-02,
  105. 0.51485584789781777618e-02,0.64674198318036867274e-02,
  106. 0.77683877779219912200e-02,0.90161081951956431600e-02,
  107. 0.10178877529236079733e-01,0.11228632913408049354e-01,
  108. 0.12141082601668299679e-01,0.12895813488012114694e-01,
  109. 0.13476374833816515982e-01,0.13870351089139840997e-01,
  110. 0.14069424957813575318e-01,0.25157870384280661489e-04,
  111. 0.18887326450650491366e-03,0.46918492424785040975e-03,
  112. // (WT(I),I=161,180)
  113. 0.84057143271072246365e-03,0.12843824718970101768e-02,
  114. 0.17864463917586498247e-02,0.23355251860571608737e-02,
  115. 0.29217249379178197538e-02,0.35362449977167777340e-02,
  116. 0.41714193769840788528e-02,0.48205888648512683476e-02,
  117. 0.54778666939189508240e-02,0.61379152800413850435e-02,
  118. 0.67957855048827733948e-02,0.74468208324075910174e-02,
  119. 0.80866093647888599710e-02,0.87109650797320868736e-02,
  120. 0.93159241280693950932e-02,0.98977475240487497440e-02,
  121. 0.10452925722906011926e-01,0.10978183152658912470e-01,
  122. 0.11470482114693874380e-01,0.11927026053019270040e-01,
  123. // (WT(I),I=181,200)
  124. 0.12345262372243838455e-01,0.12722884982732382906e-01,
  125. 0.13057836688353048840e-01,0.13348311463725179953e-01,
  126. 0.13592756614812395910e-01,0.13789874783240936517e-01,
  127. 0.13938625738306850804e-01,0.14038227896908623303e-01,
  128. 0.14088159516508301065e-01,0.69379364324108267170e-05,
  129. 0.53275293669780613125e-04,0.13575491094922871973e-03,
  130. 0.24921240048299729402e-03,0.38974528447328229322e-03,
  131. 0.55429531493037471492e-03,0.74028280424450333046e-03,
  132. 0.94536151685852538246e-03,0.11674841174299594077e-02,
  133. 0.14049079956551446427e-02,0.16561127281544526052e-02,
  134. // (WT(I),I=201,220)
  135. 0.19197129710138724125e-02,0.21944069253638388388e-02,
  136. 0.24789582266575679307e-02,0.27721957645934509940e-02,
  137. 0.30730184347025783234e-02,0.33803979910869203823e-02,
  138. 0.36933779170256508183e-02,0.40110687240750233989e-02,
  139. 0.43326409680929828545e-02,0.46573172997568547773e-02,
  140. 0.49843645647655386012e-02,0.53130866051870565663e-02,
  141. 0.56428181013844441585e-02,0.59729195655081658049e-02,
  142. 0.63027734490857587172e-02,0.66317812429018878941e-02,
  143. 0.69593614093904229394e-02,0.72849479805538070639e-02,
  144. 0.76079896657190565832e-02,0.79279493342948491103e-02,
  145. // (WT(I),I=221,240)
  146. 0.82443037630328680306e-02,0.85565435613076896192e-02,
  147. 0.88641732094824942641e-02,0.91667111635607884067e-02,
  148. 0.94636899938300652943e-02,0.97546565363174114611e-02,
  149. 0.10039172044056840798e-01,0.10316812330947621682e-01,
  150. 0.10587167904885197931e-01,0.10849844089337314099e-01,
  151. 0.11104461134006926537e-01,0.11350654315980596602e-01,
  152. 0.11588074033043952568e-01,0.11816385890830235763e-01,
  153. 0.12035270785279562630e-01,0.12244424981611985899e-01,
  154. 0.12443560190714035263e-01,0.12632403643542078765e-01,
  155. 0.12810698163877361967e-01,0.12978202239537399286e-01,
  156. // (WT(I),I=241,254)
  157. 0.13134690091960152836e-01,0.13279951743930530650e-01,
  158. 0.13413793085110098513e-01,0.13536035934956213614e-01,
  159. 0.13646518102571291428e-01,0.13745093443001896632e-01,
  160. 0.13831631909506428676e-01,0.13906019601325461264e-01,
  161. 0.13968158806516938516e-01,0.14017968039456608810e-01,
  162. 0.14055382072649964277e-01,0.14080351962553661325e-01,
  163. 0.14092845069160408355e-01,0.14094407090096179347e-01).finished();
  164. const VectorXr GQChave::WA =
  165. (VectorXr(127) << // (WT(I),I=1,20)
  166. // (WA(I),I=1,20)
  167. 0.77459666924148337704e+00,0.96049126870802028342e+00,
  168. 0.43424374934680255800e+00,0.99383196321275502221e+00,
  169. 0.88845923287225699889e+00,0.62110294673722640294e+00,
  170. 0.22338668642896688163e+00,0.99909812496766759766e+00,
  171. 0.98153114955374010687e+00,0.92965485742974005667e+00,
  172. 0.83672593816886873550e+00,0.70249620649152707861e+00,
  173. 0.53131974364437562397e+00,0.33113539325797683309e+00,
  174. 0.11248894313318662575e+00,0.99987288812035761194e+00,
  175. 0.99720625937222195908e+00,0.98868475754742947994e+00,
  176. 0.97218287474858179658e+00,0.94634285837340290515e+00,
  177. // (WA(I),I=21,40)
  178. 0.91037115695700429250e+00,0.86390793819369047715e+00,
  179. 0.80694053195021761186e+00,0.73975604435269475868e+00,
  180. 0.66290966002478059546e+00,0.57719571005204581484e+00,
  181. 0.48361802694584102756e+00,0.38335932419873034692e+00,
  182. 0.27774982202182431507e+00,0.16823525155220746498e+00,
  183. 0.56344313046592789972e-01,0.99998243035489159858e+00,
  184. 0.99959879967191068325e+00,0.99831663531840739253e+00,
  185. 0.99572410469840718851e+00,0.99149572117810613240e+00,
  186. 0.98537149959852037111e+00,0.97714151463970571416e+00,
  187. 0.96663785155841656709e+00,0.95373000642576113641e+00,
  188. // (WA(I),I=41,60)
  189. 0.93832039777959288365e+00,0.92034002547001242073e+00,
  190. 0.89974489977694003664e+00,0.87651341448470526974e+00,
  191. 0.85064449476835027976e+00,0.82215625436498040737e+00,
  192. 0.79108493379984836143e+00,0.75748396638051363793e+00,
  193. 0.72142308537009891548e+00,0.68298743109107922809e+00,
  194. 0.64227664250975951377e+00,0.59940393024224289297e+00,
  195. 0.55449513263193254887e+00,0.50768775753371660215e+00,
  196. 0.45913001198983233287e+00,0.40897982122988867241e+00,
  197. 0.35740383783153215238e+00,0.30457644155671404334e+00,
  198. 0.25067873030348317661e+00,0.19589750271110015392e+00,
  199. // (WA(I),I=61,80)
  200. 0.14042423315256017459e+00,0.84454040083710883710e-01,
  201. 0.28184648949745694339e-01,0.99999759637974846462e+00,
  202. 0.99994399620705437576e+00,0.99976049092443204733e+00,
  203. 0.99938033802502358193e+00,0.99874561446809511470e+00,
  204. 0.99780535449595727456e+00,0.99651414591489027385e+00,
  205. 0.99483150280062100052e+00,0.99272134428278861533e+00,
  206. 0.99015137040077015918e+00,0.98709252795403406719e+00,
  207. 0.98351865757863272876e+00,0.97940628167086268381e+00,
  208. 0.97473445975240266776e+00,0.96948465950245923177e+00,
  209. 0.96364062156981213252e+00,0.95718821610986096274e+00,
  210. // (WA(I),I=81,100)
  211. 0.95011529752129487656e+00,0.94241156519108305981e+00,
  212. 0.93406843615772578800e+00,0.92507893290707565236e+00,
  213. 0.91543758715576504064e+00,0.90514035881326159519e+00,
  214. 0.89418456833555902286e+00,0.88256884024734190684e+00,
  215. 0.87029305554811390585e+00,0.85735831088623215653e+00,
  216. 0.84376688267270860104e+00,0.82952219463740140018e+00,
  217. 0.81462878765513741344e+00,0.79909229096084140180e+00,
  218. 0.78291939411828301639e+00,0.76611781930376009072e+00,
  219. 0.74869629361693660282e+00,0.73066452124218126133e+00,
  220. 0.71203315536225203459e+00,0.69281376977911470289e+00,
  221. // (WA(I),I=101,120)
  222. 0.67301883023041847920e+00,0.65266166541001749610e+00,
  223. 0.63175643771119423041e+00,0.61031811371518640016e+00,
  224. 0.58836243444766254143e+00,0.56590588542365442262e+00,
  225. 0.54296566649831149049e+00,0.51955966153745702199e+00,
  226. 0.49570640791876146017e+00,0.47142506587165887693e+00,
  227. 0.44673538766202847374e+00,0.42165768662616330006e+00,
  228. 0.39621280605761593918e+00,0.37042208795007823014e+00,
  229. 0.34430734159943802278e+00,0.31789081206847668318e+00,
  230. 0.29119514851824668196e+00,0.26424337241092676194e+00,
  231. 0.23705884558982972721e+00,0.20966523824318119477e+00,
  232. // (WA(I),I=121,127)
  233. 0.18208649675925219825e+00,0.15434681148137810869e+00,
  234. 0.12647058437230196685e+00,0.98482396598119202090e-01,
  235. 0.70406976042855179063e-01,0.42269164765363603212e-01,
  236. 0.14093886410782462614e-01).finished();
  237. /*
  238. const Real PI2 = 0.6366197723675813;
  239. const Real X01P = 0.4809651115391545e01;
  240. const Real XMAX = std::numeric_limits<Real>::max();
  241. const Real XSMALL = 0.9094947017729281e-12;
  242. const Real J0_X01 = 0.2404825557695772e01;
  243. const Real J0_X02 = 0.1043754397719454e-15;
  244. const Real J0_X11 = 0.5520078110286310e01;
  245. const Real J0_X12 = 0.8088597146146419e-16;
  246. const Real FUDGE = 6.071532166000000e-18;
  247. const Real FUDGEX = 1.734723476000000e-18;
  248. const Real TWOPI1 = 0.6283185005187988e01;
  249. const Real TWOPI2 = 0.3019915981956752e-06;
  250. const Real RTPI2 = 0.7978845608028652e0;
  251. const Real XMIN = std::numeric_limits<Real>::min();
  252. const Real J1_X01 = 0.3831705970207512e1;
  253. const Real J1_X02 = -0.5967810507509414e-15;
  254. const Real J1_X11 = 0.7015586669815619e1;
  255. const Real J1_X12 = -0.5382308663841630e-15;
  256. */
  257. GQChave::GQChave( const ctor_key& key ) : HankelTransform( key ) {
  258. //karg.resize(255, 100);
  259. //kern.resize(510, 100);
  260. Xr.resize(100);
  261. Xi.resize(100);
  262. Dr.resize(100);
  263. Di.resize(100);
  264. Sr.resize(100);
  265. Si.resize(100);
  266. Cfcor.resize(100);
  267. Cfcoi.resize(100);
  268. }
  269. GQChave::GQChave( const YAML::Node& node, const ctor_key& key ) : HankelTransform(node, key) {
  270. }
  271. /////////////////////////////////////////////////////////////
  272. GQChave::~GQChave() {
  273. }
  274. /////////////////////////////////////////////////////////////
  275. std::shared_ptr<GQChave> GQChave::NewSP() {
  276. return std::make_shared<GQChave>( ctor_key() );
  277. }
  278. //--------------------------------------------------------------------------------------
  279. // Class: GQChave
  280. // Method: DeSerialize
  281. // Description: Factory method, converts YAML node into object
  282. //--------------------------------------------------------------------------------------
  283. std::shared_ptr<GQChave> GQChave::DeSerialize( const YAML::Node& node ) {
  284. if (node.Tag() != "GQChave") {
  285. throw DeSerializeTypeMismatch( "GQChave", node.Tag());
  286. }
  287. return std::make_shared<GQChave> ( node, ctor_key() );
  288. }
  289. //--------------------------------------------------------------------------------------
  290. // Class: GQChave
  291. // Method: Serialize
  292. // Description: Converts object into Serialized version
  293. //--------------------------------------------------------------------------------------
  294. YAML::Node GQChave::Serialize() const {
  295. YAML::Node node = HankelTransform::Serialize();
  296. node.SetTag( GetName() );
  297. //node["LayerConductivity"] = LayerConductivity;
  298. return node;
  299. }
  300. /////////////////////////////////////////////////////////////
  301. //--------------------------------------------------------------------------------------
  302. // Class: GQChave
  303. // Method: GetName
  304. // Description: Class identifier
  305. //--------------------------------------------------------------------------------------
  306. inline std::string GQChave::GetName ( ) const {
  307. return CName;
  308. } // ----- end of method GQChave::GetName -----
  309. Complex GQChave::Zgauss(const int &ikk, const EMMODE &mode,
  310. const int &itype, const Real &rho, const Real &wavef,
  311. KernelEM1DBase* Kernel){
  312. // TI, TODO, change calls to Zgauss to reflect this, go and fix so we
  313. // dont subract 1 from this everywhere
  314. //Kernel->SetIk(ikk+1);
  315. //Kernel->SetMode(mode);
  316. //ik = ikk+1;
  317. //mode = imode;
  318. karg.resize(255, 100);
  319. kern.resize(510, 100);
  320. Real Besr(0);
  321. Real Besi(0);
  322. // Parameters
  323. int nl(1); // Lower limit for gauss order to start comp
  324. int nu(7); // upper limit for gauss order
  325. #ifdef LEMMA_SINGLE_PRECISION
  326. Real rerr = 1e-5; // Error, for double Kihand set to .1e-10, .1e-11
  327. Real aerr = 1e-6;
  328. #else // ----- not LEMMA_SINGLE_PRECISION -----
  329. Real rerr = 1e-11; // Error, for double Kihand set to .1e-10, .1e-11
  330. Real aerr = 1e-12;
  331. #endif // ----- not LEMMA_SINGLE_PRECISION -----
  332. int npcs(1);
  333. int inew(0);
  334. //const int NTERM = 100;
  335. //BESINT.karg.resize(255, NTERM);
  336. //BESINT.kern.resize(510, NTERM);
  337. //this->karg.setZero();
  338. //this->kern.setZero();
  339. //std::cout << "calling Besautn" << std::endl;
  340. Besautn(Besr, Besi, itype, nl, nu, rho, rerr, aerr, npcs, inew, wavef, Kernel);
  341. return Complex(Besr, Besi);
  342. }
  343. //////////////////////////////////////////////////////////////////
  344. void GQChave::
  345. Besautn(Real &besr, Real &besi,
  346. const int &besselOrder,
  347. const int &lowerGaussLimit,
  348. const int &upperGaussLimit,
  349. const Real &rho,
  350. const Real &relativeError,
  351. const Real &absError,
  352. const int& numPieces,
  353. int &inew,
  354. const Real &aorb,
  355. KernelEM1DBase* Kernel) {
  356. HighestGaussOrder = 0;
  357. NumberPartialIntegrals = 0;
  358. NumberFunctionEvals = 0;
  359. inew = 0;
  360. if (lowerGaussLimit > upperGaussLimit) {
  361. besr = 0;
  362. besi = 0;
  363. throw LowerGaussLimitGreaterThanUpperGaussLimit();
  364. }
  365. int ncntrl = 0;
  366. int nw = std::max(inew, 1);
  367. // temps
  368. Real besr_1(0);
  369. Real besi_1(0);
  370. int ierr(0);
  371. int ierr1(0);
  372. int ierr2(0);
  373. VectorXi xsum(1);
  374. //xsum.setZero(); // TODO xsum doesn't do a god damn thing
  375. int nsum(0);
  376. // Check for Rtud
  377. //std::cout << "calling Bestrn" << std::endl;
  378. Bestrn(besr_1, besi_1, besselOrder, lowerGaussLimit, rho,
  379. .1*relativeError, .1*absError,
  380. numPieces, xsum, nsum, nw, ierr, ncntrl, aorb, Kernel);
  381. if (ierr != 0 && lowerGaussLimit == 7) {
  382. HighestGaussOrder = lowerGaussLimit;
  383. return;
  384. } else {
  385. Real oldr = besr_1;
  386. Real oldi = besi_1;
  387. for (int n=lowerGaussLimit+1; n<=upperGaussLimit; ++n) {
  388. int nw2 = 2;
  389. Bestrn(besr_1, besi_1, besselOrder, n, rho, .1*relativeError,
  390. .1*absError, numPieces, xsum, nsum, nw2, ierr,
  391. ncntrl, aorb, Kernel);
  392. if (ierr != 0 && n==7) {
  393. besr_1 = oldr;
  394. besi_1 = oldi;
  395. HighestGaussOrder = n;
  396. std::cerr << "CONVERGENCE FAILED AT SMALL ARGUMNENT!\n";
  397. ierr1 = ierr + 10;
  398. break;
  399. } else if (std::abs(besr_1-oldr) <=
  400. relativeError*std::abs(besr_1)+absError &&
  401. std::abs(besi_1-oldi) <=
  402. relativeError*std::abs(besi_1)+absError) {
  403. HighestGaussOrder = n;
  404. break;
  405. } else {
  406. oldr = besr_1;
  407. oldi = besi_1;
  408. }
  409. }
  410. }
  411. inew = 0;
  412. ncntrl = 1;
  413. nw=std::max(inew, 1);
  414. Real besr_2, besi_2;
  415. //karg.setZero();
  416. //kern.setZero();
  417. HighestGaussOrder = 0;
  418. NumberPartialIntegrals = 0;
  419. NumberFunctionEvals = 0;
  420. Bestrn(besr_2, besi_2, besselOrder, lowerGaussLimit, rho,
  421. .1*relativeError, .1*absError,
  422. numPieces, xsum, nsum, nw, ierr, ncntrl, aorb, Kernel);
  423. if (ierr != 0 && lowerGaussLimit == 7) {
  424. HighestGaussOrder = lowerGaussLimit;
  425. return;
  426. } else {
  427. Real oldr = besr_2;
  428. Real oldi = besi_2;
  429. for (int n=lowerGaussLimit+1; n<=upperGaussLimit; ++n) {
  430. int nw2 = 2;
  431. Bestrn(besr_2, besi_2, besselOrder, n, rho, .1*relativeError,
  432. .1*absError, numPieces, xsum, nsum, nw2, ierr,
  433. ncntrl, aorb, Kernel);
  434. if (ierr != 0 && n==7) {
  435. besr_2 = oldr;
  436. besi_2 = oldi;
  437. HighestGaussOrder = n;
  438. std::cerr << "CONVERGENCE FAILED AT SMALL ARGUMNENT!\n";
  439. ierr2 = ierr + 20;
  440. break;
  441. } else if (std::abs(besr_2-oldr) <=
  442. relativeError*std::abs(besr_2)+absError &&
  443. std::abs(besi_2-oldi) <=
  444. relativeError*std::abs(besi_2)+absError) {
  445. HighestGaussOrder = n;
  446. break;
  447. } else {
  448. oldr = besr_2;
  449. oldi = besi_2;
  450. }
  451. }
  452. }
  453. besr = besr_1 + besr_2;
  454. besi = besi_1 + besi_2;
  455. ierr = ierr1 + ierr2;
  456. return;
  457. }
  458. /////////////////////////////////////////////////////////////
  459. void GQChave::
  460. Bestrn(Real &BESR, Real &BESI, const int &IORDER,
  461. const int& NG, const Real& rho,
  462. const Real& RERR, const Real& AERR, const int& NPCS,
  463. const VectorXi& XSUM, int& NSUM, int& NEW,
  464. int& IERR, int& NCNTRL, const Real& AORB, KernelEM1DBase* Kernel) {
  465. //std::cout << "Bestrn setZero " << NEW << std::endl;
  466. //Xr.array() = 0.;
  467. //Xi.array() = 0.;
  468. Xr.setZero();
  469. Xi.setZero();
  470. Dr.setZero();
  471. Di.setZero();
  472. Sr.setZero();
  473. Si.setZero();
  474. Cfcor.setZero();
  475. Cfcoi.setZero();
  476. Dr.setZero();
  477. Di.setZero();
  478. //std::cout << "Bestrn wat " << NEW << std::endl;
  479. Dr(0) = (Real)(-1);
  480. const int NTERM = 100;
  481. const int NSTOP = 100;
  482. int NPO;
  483. //std::cout << "Bestrn NEW " << NEW << std::endl;
  484. if (NEW == 2) {
  485. NPO = nps;
  486. } else {
  487. Nk.setZero();
  488. nps = 0;
  489. NPO=NTERM;
  490. }
  491. // Trivial?
  492. if (IORDER != 0 && rho == 0) {
  493. BESR = 0;
  494. BESI = 0;
  495. IERR = 0;
  496. return;
  497. }
  498. NumberPartialIntegrals=0;
  499. int NW = NEW;
  500. np = 0; // TI, zero based indexing
  501. int NPB = 1; // 0?
  502. int L = 0;
  503. Real B = 0.;
  504. Real A = 0.;
  505. Real SUMR = 0.;
  506. Real SUMI = 0.;
  507. Real XSUMR = 0.;
  508. Real XSUMI = 0.;
  509. Real TERMR(0), TERMI(0);
  510. // COMPUTE BESSEL TRANSFORM EXPLICITLY ON (0,XSUM(NSUM))
  511. if (NSUM > 0) {
  512. std::cerr << "NSUM GREATER THAN ZERO UNTESTED" << std::endl;
  513. Real LASTR=0.0;
  514. Real LASTI=0.0;
  515. for (int N=1; N<=NSUM; ++N) {
  516. if (NW == 2 && np > NPO) NW=1;
  517. if (np > NTERM) NW=0;
  518. A=B;
  519. B=XSUM(N);
  520. Besqud(A, B, TERMR, TERMI, NG, NW, IORDER, rho, Kernel);
  521. XSUMR += TERMR;
  522. XSUMI += TERMI;
  523. if ( (std::abs(XSUMR-LASTR) <= RERR*std::abs(XSUMR)+AERR) &&
  524. (std::abs(XSUMI-LASTI) <= RERR*std::abs(XSUMI)+AERR)) {
  525. BESR=XSUMR;
  526. BESI=XSUMI;
  527. IERR=0;
  528. nps = std::max(np, nps);
  529. return;
  530. } else {
  531. ++np;
  532. LASTR=XSUMR;
  533. LASTI=XSUMI;
  534. }
  535. }
  536. // TODO, evaluate this case triggering cerr, as well as sttement below
  537. //while ( ZeroJ(NPB,IORDER) > XSUM(NSUM*rho)) {
  538. while ( ZeroJ(NPB,IORDER) > XSUM( (int)(NSUM*rho) )) {
  539. ++NPB;
  540. }
  541. }
  542. //std::cout << "Bestrn NEW " << NEW << std::endl;
  543. // ENTRY POINT FOR PADE SUMMATION OF PARTIAL INTEGRANDS
  544. Real LASTR=0.e0;
  545. Real LASTI=0.e0;
  546. if (NCNTRL == 0) {
  547. A = 0.;
  548. B = ZeroJ(NPB,IORDER) / rho;
  549. if (B > AORB) {
  550. B = AORB;
  551. }
  552. } else {
  553. A = AORB;
  554. B = ZeroJ(NPB,IORDER)/rho;
  555. while (B <= A) {
  556. ++NPB;
  557. B = ZeroJ(NPB,IORDER)/rho;
  558. }
  559. }
  560. // CALCULATE TERMS AND SUM WITH PADECF, QUITTING WHEN CONVERGENCE IS
  561. // OBTAINED
  562. if (NCNTRL != 0) {
  563. for (int N=1; N<=NSTOP; ++N) {
  564. if (NPCS == 1) {
  565. if ((NW==2) && (np > NPO)) {
  566. NW=1;
  567. }
  568. if (np > NTERM) {
  569. NW=0;
  570. }
  571. Besqud(A,B,TERMR,TERMI,NG,NW,IORDER,rho,Kernel);
  572. ++np;
  573. } else {
  574. std::cout << "In the else conditional\n";
  575. TERMR=0.;
  576. TERMI=0.;
  577. Real XINC=(B-A)/NPCS;
  578. Real AA=A;
  579. Real BB=A+XINC;
  580. for (int I=1; I<=NPCS; ++I) {
  581. if ((NW == 2) && (np > NPO)) NW=1;
  582. if (np > NTERM) NW=0;
  583. Real TR, TI;
  584. Besqud(AA, BB, TR, TI, NG, NW, IORDER, rho, Kernel);
  585. TERMR+=TR;
  586. TERMI+=TI;
  587. AA=BB;
  588. BB=BB+XINC;
  589. ++np;
  590. }
  591. }
  592. ++NumberPartialIntegrals;
  593. Sr(L) = TERMR;
  594. Si(L) = TERMI;
  595. Padecf(SUMR,SUMI,L);
  596. if ((std::abs(SUMR-LASTR) <= RERR*std::abs(SUMR)+AERR) &&
  597. (std::abs(SUMI-LASTI) <= RERR*std::abs(SUMI)+AERR)) {
  598. BESR=XSUMR+SUMR;
  599. BESI=XSUMI+SUMI;
  600. IERR=0;
  601. nps = std::max(np-1, nps);
  602. return;
  603. } else {
  604. LASTR=SUMR;
  605. LASTI=SUMI;
  606. ++NPB;
  607. A=B;
  608. B=ZeroJ(NPB,IORDER)/rho;
  609. ++L;
  610. }
  611. }
  612. BESR=XSUMR+SUMR;
  613. BESI=XSUMI+SUMI;
  614. IERR=1;
  615. nps = std::max(np, nps);
  616. return;
  617. }
  618. // GUSSIAN QUADRATURE ONLY IN THE INTERVAL IN WHICH K_0 IS LESS THAN
  619. // LAMBDA
  620. //std::cout << "NCNTRL " << NCNTRL << " NPCS " << NPCS << std::endl;
  621. for (int N=1; N<=NSTOP; ++N) {
  622. //std::cout << "NSTOP" << NSTOP << std::endl;
  623. if (NPCS == 1) {
  624. if ((NW==2) && (np > NPO)) {
  625. NW=1;
  626. }
  627. if (np > NTERM) {
  628. NW=0;
  629. }
  630. // Problem here, A not getting initialised
  631. //std::cout << "A " << A << " B " << B << std::endl;
  632. Besqud(A, B, TERMR, TERMI, NG, NW, IORDER, rho, Kernel);
  633. ++np;
  634. } else {
  635. TERMR=0.;
  636. TERMI=0.;
  637. Real XINC=(B-A)/NPCS;
  638. Real AA=A;
  639. Real BB=A+XINC;
  640. Real TR(0), TI(0);
  641. for (int I=1; I<NPCS; ++I) {
  642. if ((NW == 2) && (np > NPO)) {
  643. NW=1;
  644. }
  645. if (np > NTERM) {
  646. NW=0;
  647. }
  648. //std::cout << "AA " << AA << " BB " << BB << std::endl;
  649. Besqud(AA, BB, TR, TI, NG, NW, IORDER, rho, Kernel);
  650. TERMR+=TR;
  651. TERMI+=TI;
  652. AA=BB;
  653. BB=BB+XINC;
  654. ++np;
  655. }
  656. }
  657. if (B >= AORB) {
  658. BESR=XSUMR+TERMR;
  659. BESI=XSUMI+TERMI;
  660. IERR=0;
  661. nps = std::max(np, nps); // TI np is zero based
  662. return;
  663. } else {
  664. XSUMR = XSUMR + TERMR;
  665. XSUMI = XSUMI + TERMI;
  666. ++NPB;
  667. A = B;
  668. B = ZeroJ(NPB,IORDER)/rho;
  669. if (B >= AORB) B = AORB;
  670. }
  671. }
  672. return;
  673. }
  674. /////////////////////////////////////////////////////////////
  675. void GQChave::
  676. Besqud(const Real &LowerLimit, const Real &UpperLimit,
  677. Real &Besr, Real &Besi, const int &npoints,
  678. const int &NEW,
  679. const int &besselOrder, const Real &rho,
  680. KernelEM1DBase* Kernel) {
  681. const int NTERM = 100;
  682. // Filter Weights
  683. Eigen::Matrix<int , 7, 1> NWA;
  684. Eigen::Matrix<int , 7, 1> NWT;
  685. Eigen::Matrix<Real, 254, 1> FUNCT;
  686. Eigen::Matrix<Real, 64, 1> FR1;
  687. Eigen::Matrix<Real, 64, 1> FI1;
  688. Eigen::Matrix<Real, 64, 1> FR2;
  689. Eigen::Matrix<Real, 64, 1> FI2;
  690. Eigen::Matrix<Real, 64, 1> BES1;
  691. Eigen::Matrix<Real, 64, 1> BES2;
  692. // Init Vals
  693. NWT << 1, 3, 7, 15, 31, 63, 127;
  694. NWA << 1, 2, 4, 8, 16, 32, 64;
  695. // CHECK FOR TRIVIAL CASE
  696. if (LowerLimit >= UpperLimit) {
  697. Besr = 0.;
  698. Besi = 0.;
  699. //std::cout << "Lower limit > Upper limit " << NEW << std::endl;
  700. //std::cout << "Lower limit " << LowerLimit << "Upper Limit " << UpperLimit <<std::endl;
  701. return;
  702. }
  703. // Temp vars for function generation
  704. Real diff(0);
  705. Real FZEROR(0);
  706. Real FZEROI(0);
  707. Real SUM(0);
  708. int KN(0);
  709. int LA(0);
  710. int LK(0);
  711. int N(0);
  712. int K;
  713. int NW;
  714. Real ACUMR;
  715. Real ACUMI;
  716. Real BESF;
  717. switch (NEW) {
  718. // CONSTRUCT FUNCT FROM SAVED KERNELS
  719. case (2):
  720. diff = (UpperLimit-LowerLimit)/2.;
  721. FZEROR = kern(0, np);
  722. FZEROI = kern(1, np);
  723. K = std::min(Nk(np)-1, npoints-1);
  724. NW=NWT(K);
  725. LK=2;
  726. for (N=0; N<2*NW; N+=2) {
  727. FUNCT(N) = kern(LK , np) +
  728. kern(LK+2, np) ;
  729. FUNCT(N+1) = kern(LK+1, np) +
  730. kern(LK+3, np) ;
  731. LK=LK+4;
  732. }
  733. if (Nk(np) >= npoints) {
  734. ACUMR = _dot(NW, WT.tail(255-NW), 1, FUNCT, 2);
  735. ACUMI = _dot(NW, WT.tail(255-NW), 1, FUNCT.tail<253>(), 2);
  736. Besr = (ACUMR+WT(2*NW)*FZEROR)*diff;
  737. Besi = (ACUMI+WT(2*NW)*FZEROI)*diff;
  738. return;
  739. } else {
  740. // COMPUTE ADDITIONAL ORDERS BEFORE TAKING DOT PRODUCT
  741. SUM= (UpperLimit+LowerLimit)/2.;
  742. KN = K +1;
  743. LA = LK/2;
  744. }
  745. break;
  746. default:
  747. // SCALE FACTORS
  748. SUM = (UpperLimit+LowerLimit) / 2.;
  749. diff = (UpperLimit-LowerLimit) / 2.;
  750. // ONE POINT GAUSS
  751. //Kernel(SUM,FZEROR,FZEROI,TEM,GEOM,PARA);
  752. Complex tba = Kernel->BesselArg(SUM);
  753. //cout.precision(16);
  754. //std::cout << "SUM " << "\t" << SUM << "\t" << tba << "\n";
  755. ++NumberFunctionEvals;
  756. BESF = Jbess(SUM*rho,besselOrder);
  757. FZEROR = BESF*std::real(tba);//FZEROR;
  758. FZEROI = BESF*std::imag(tba);//FZEROI;
  759. if (NEW == 1) {
  760. karg(0, np) = SUM;
  761. kern(0, np) = FZEROR;
  762. kern(1, np) = FZEROI;
  763. LA=1;
  764. LK=2;
  765. }
  766. N = 0; // TI was 1, 0 based index
  767. KN = 0;
  768. } // End of new switch
  769. // STEP THROUGH GAUSS ORDERS (NG = Number Gauss)
  770. for (int K=KN; K<npoints; ++K) {
  771. // COMPUTE NEW FUNCTION VALUES
  772. int NA = NWA(K) - 1; // NWA assumes 1 based indexing
  773. //std::cout << "Besqud NA=" << NA << std::endl;
  774. for (int J=0; J<NWA(K); ++J) {
  775. Real X = WA(NA)*diff;
  776. Real SUMP = SUM+X;
  777. Real SUMM = SUM-X;
  778. ++NA;
  779. //std::cout << "Calling from here\n";
  780. //Kernel(SUMP, FR1(J), FI1(J), TEM, GEOM, PARA);
  781. //Kernel(SUMM, FR2(J), FI2(J), TEM, GEOM, PARA);
  782. Complex bes1 = Kernel->BesselArg(SUMP);
  783. //std::cout << "SUMP" << "\t" << SUMP << "\t" << bes1 << "\n";
  784. Complex bes2 = Kernel->BesselArg(SUMM);
  785. //std::cout << "SUMM" << "\t" << SUMM << "\t" << bes1 << "\n";
  786. FR1(J) = std::real(bes1);
  787. FI1(J) = std::imag(bes1);
  788. FR2(J) = std::real(bes2);
  789. FI2(J) = std::imag(bes2);
  790. NumberFunctionEvals +=2;
  791. BES1(J)=Jbess(SUMP*rho, besselOrder);
  792. BES2(J)=Jbess(SUMM*rho, besselOrder);
  793. if (NEW >= 1) {
  794. karg(LA , np) = SUMP;
  795. karg(LA+1, np) = SUMM;
  796. LA += 2;
  797. }
  798. }
  799. // COMPUTE PRODUCTS OF KERNELS AND BESSEL FUNCTIONS
  800. // TODO vectorize
  801. for (int J=0; J<NWA(K); ++J) {
  802. FR1(J ) = BES1(J)*FR1(J);
  803. FI1(J ) = BES1(J)*FI1(J);
  804. FR2(J ) = BES2(J)*FR2(J);
  805. FI2(J ) = BES2(J)*FI2(J);
  806. FUNCT(N ) = FR1(J)+FR2(J);
  807. FUNCT(N+1) = FI1(J)+FI2(J);
  808. N+=2;
  809. }
  810. if (NEW >= 1) {
  811. for (int J=0; J<NWA(K); ++J) {
  812. kern(LK , np) = FR1(J);
  813. kern(LK+1, np) = FI1(J);
  814. kern(LK+2, np) = FR2(J);
  815. kern(LK+3, np) = FI2(J);
  816. LK=LK+4;
  817. }
  818. }
  819. }
  820. // COMPUTE DOT PRODUCT OF WEIGHTS WITH INTEGRAND VALUES
  821. NW=NWT(npoints-1);
  822. ACUMR = _dot(NW, WT.tail(255-NW), 1, FUNCT , 2);
  823. ACUMI = _dot(NW, WT.tail(255-NW), 1, FUNCT.tail<253>(), 2);
  824. Besr = (ACUMR+WT(2*NW-1)*FZEROR)*diff;
  825. Besi = (ACUMI+WT(2*NW-1)*FZEROI)*diff;
  826. if (np <= NTERM) Nk(np) = npoints;
  827. return;
  828. }
  829. /////////////////////////////////////////////////////////////
  830. void GQChave::
  831. Padecf(Real &SUMR, Real &SUMI, const int &N) {
  832. if (N < 2) {
  833. // INITIALIZE FOR RECURSIVE CALCULATIONS
  834. //if (N == 0) {
  835. // Xr.setZero();
  836. // Xi.setZero();
  837. //Xr = Eigen::Matrix<Real, Eigen::Dynamic, 1>::Zero(100);
  838. //Xi = Eigen::Matrix<Real, Eigen::Dynamic, 1>::Zero(100);
  839. //}
  840. Dr(N) = Sr(N);
  841. Di(N) = Si(N);
  842. Real DENOM;
  843. switch (N) {
  844. case 0:
  845. DENOM = 1;
  846. Cfcor(N) = -(-1.*Dr(N)) / DENOM;
  847. Cfcoi(N) = -(-1.*Di(N)) / DENOM;
  848. break;
  849. default:
  850. DENOM = Dr(N-1)*Dr(N-1) +
  851. Di(N-1)*Di(N-1);
  852. Cfcor(N) = -(Dr(N-1)*Dr(N) +
  853. Di(N-1)*Di(N) ) / DENOM;
  854. Cfcoi(N) = -(Dr(N-1)*Di(N ) -
  855. Dr(N )*Di(N-1) ) / DENOM;
  856. }
  857. CF(SUMR, SUMI, Cfcor, Cfcoi, N);
  858. return;
  859. } else {
  860. int L = 2*(int)((N)/2) - 1;//+1;// - 1; // - 1; // - 1;
  861. // UPDATE X VECTORS FOR RECURSIVE CALCULATION OF CF COEFFICIENTS
  862. for (int K = L; K >= 3; K-= 2) {
  863. Xr(K) = Xr(K-1)+Cfcor(N-1)*Xr(K-2) -
  864. Cfcoi(N-1)*Xi(K-2);
  865. Xi(K) = Xi(K-1)+Cfcor(N-1)*Xi(K-2) +
  866. Cfcoi(N-1)*Xr(K-2);
  867. }
  868. Xr(1) = Xr(0)+Cfcor(N-1);
  869. Xi(1) = Xi(0)+Cfcoi(N-1);
  870. // INTERCHANGE ODD AND EVEN PARTS
  871. for (int K=0; K<L; K+=2) {
  872. Real T1 = Xr(K);
  873. Real T2 = Xi(K);
  874. Xr(K) = Xr(K+1);
  875. Xi(K) = Xi(K+1);
  876. Xr(K+1) = T1;
  877. Xi(K+1) = T2;
  878. }
  879. // COMPUTE FIRST COEFFICIENTS
  880. Dr(N) = Sr(N);
  881. Di(N) = Si(N);
  882. // Dr getting fucked up here
  883. for (int K=0; K<std::max(1, L/2+1); ++K) {
  884. Dr(N) += Sr(N-K-1)*Xr(2*K) -
  885. Si(N-K-1)*Xi(2*K);
  886. Di(N) += Si(N-K-1)*Xr(2*K) +
  887. Sr(N-K-1)*Xi(2*K);
  888. }
  889. // COMPUTE NEW CF COEFFICIENT
  890. Real DENOM = Dr(N-1)*Dr(N-1) +
  891. Di(N-1)*Di(N-1);
  892. //std::cout << "DENOM " << DENOM << std::endl;
  893. Cfcor(N)=-(Dr(N )*Dr(N-1) +
  894. Di(N)*Di(N-1))/DENOM;
  895. Cfcoi(N)=-(Dr(N-1)*Di(N ) -
  896. Dr(N)*Di(N-1))/DENOM;
  897. // EVALUATE CONTINUED FRACTION
  898. CF(SUMR,SUMI,Cfcor,Cfcoi,N);
  899. return;
  900. }
  901. }
  902. /////////////////////////////////////////////////////////////
  903. void GQChave::CF(Real& RESR, Real &RESI,
  904. const VectorXr& CFCOR,
  905. const VectorXr& CFCOI,
  906. const int &N) {
  907. ////////////////////////////////////////////////
  908. // ONE Seems sort of stupid, maybe use ? instead
  909. // TODO benchmark difference
  910. //RESR = ONE(N)+CFCOR(N);
  911. RESR = (!N ? 0:1) + CFCOR(N);
  912. RESI = CFCOI(N);
  913. for (int K=N-1; K>=0; --K) {
  914. Real DENOM=RESR*RESR + RESI*RESI;
  915. Real RESRO=RESR;
  916. //RESR=ONE(K)+(RESR*CFCOR(K)+RESI*CFCOI(K))/DENOM;
  917. RESR = (!K ? 0:1) + (RESR*CFCOR(K)+RESI*CFCOI(K))/DENOM;
  918. RESI=(RESRO*CFCOI(K)-RESI*CFCOR(K))/DENOM;
  919. }
  920. return;
  921. }
  922. /////////////////////////////////////////////////////////////
  923. Real GQChave::
  924. ZeroJ(const int &nzero, const int &besselOrder) {
  925. Real ZT1 = -1.e0/8.e0;
  926. Real ZT2 = 124.e0/1536.e0;
  927. Real ZT3 = -120928.e0/491520.e0;
  928. Real ZT4 = 401743168.e0/220200960.e0;
  929. Real OT1 = 3.e0/8.e0;
  930. Real OT2 = -36.e0/1536.e0;
  931. Real OT3 = 113184.e0/491520.e0;
  932. Real OT4 = -1951209.e0/220200960.e0;
  933. Real BETA(0);
  934. switch (besselOrder) {
  935. case 0:
  936. BETA=(nzero-.25e0)*PI;
  937. return BETA-ZT1/BETA-ZT2/std::pow(BETA,3) -
  938. ZT3/std::pow(BETA,5)-ZT4/std::pow(BETA,7);
  939. case 1:
  940. BETA=(nzero+.25e0)*PI;
  941. return BETA-OT1/BETA-OT2/std::pow(BETA,3) -
  942. OT3/std::pow(BETA,5)-OT4/std::pow(BETA,7);
  943. default:
  944. throw 77;
  945. }
  946. //return 0.;
  947. }
  948. /////////////////////////////////////////////////////////////
  949. // Dot product allowing non 1 based incrementing
  950. Real GQChave::_dot(const int&n,
  951. const Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> &X1,
  952. const int &inc1,
  953. const Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic> &X2,
  954. const int &inc2) {
  955. int k;
  956. if (inc2 > 0) {
  957. k=0;
  958. } else {
  959. k = n*std::abs(inc2);
  960. }
  961. Real dot=0.0;
  962. if (inc1 > 0) {
  963. for (int i=0; i<n; i += inc1) {
  964. dot += X1(i)*X2(k);
  965. k += inc2;
  966. }
  967. } else {
  968. for (int i=n-1; i>=0; i += inc1) {
  969. dot += X1(i)*X2(k);
  970. k += inc2;
  971. }
  972. }
  973. return dot;
  974. }
  975. /////////////////////////////////////////////////////////////
  976. //
  977. #ifdef HAVE_BOOST_SPECIAL_FUNCTIONS
  978. Real GQChave::Jbess(const Real &x, const int &IORDER) {
  979. switch (IORDER) {
  980. case 0:
  981. //return boost::math::detail::bessel_j0(X);
  982. return boost::math::cyl_bessel_j(0, x);
  983. break;
  984. case 1:
  985. //return boost::math::detail::bessel_j1(x);
  986. return boost::math::cyl_bessel_j(1, x);
  987. break;
  988. default:
  989. throw std::runtime_error("Non 0 or 1 Bessel argument specified in GQChave");
  990. }
  991. }
  992. #else
  993. Real GQChave::Jbess(const Real &x, const int &IORDER) {
  994. std::cerr << "GQChave requires boost special functions module";
  995. return 0;
  996. }
  997. #endif
  998. //////////////////////////////////////////////////////
  999. // Exception classes
  1000. LowerGaussLimitGreaterThanUpperGaussLimit::
  1001. LowerGaussLimitGreaterThanUpperGaussLimit() :
  1002. runtime_error("LOWER GAUSS LIMIT > UPPER GAUSS LIMIT") {}
  1003. } // ----- end of Lemma name -----