Main Lemma Repository
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DigitalFilterIntegratorAnderson.h 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567
  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 02/07/2011
  9. @version $Id: digitalfilterintegrator.h 124 2014-02-07 04:26:26Z tirons $
  10. **/
  11. #pragma once
  12. #ifndef DIGITALFILTERINTEGRATOR_INC
  13. #define DIGITALFILTERINTEGRATOR_INC
  14. #include "IntegrationKernel.h"
  15. namespace Lemma {
  16. // ===================================================================
  17. // Class: DigitalFilterIntegratorAnderson
  18. /**
  19. \brief Reimplimentation of Walt Anderson's digital filtering
  20. algorithms which are public domain.
  21. \details Walt Anderson wrote several routines for digital filtering
  22. that reused a lot of boilerplate code. The original fortran
  23. codes are available at:
  24. ftp://ftpext.usgs.gov/pub/cr/co/denver/musette/pub/anderson/
  25. This is an abstract class. Concrete classes must define the
  26. a function to make arguments.
  27. Template specilizations are found in the implimentation file
  28. digitalfilterintegrator.cpp. This was necessary to support
  29. the design paradigm of Lemma.
  30. */
  31. // ===================================================================
  32. template <typename Scalar>
  33. class DigitalFilterIntegratorAnderson : public LemmaObject {
  34. /** Prints out basic info about the class, Complex implimentation */
  35. template <typename Scalar2>
  36. friend std::ostream &operator<<(std::ostream &stream,
  37. const DigitalFilterIntegratorAnderson<Scalar2> &ob);
  38. public:
  39. // ==================== LIFECYCLE =======================
  40. /** Default protected constructor. */
  41. explicit DigitalFilterIntegratorAnderson (const ctor_key& key);
  42. /** Default protected constructor. */
  43. ~DigitalFilterIntegratorAnderson ();
  44. /**
  45. * @return a YAML::Node serial object
  46. */
  47. YAML::Node Serialize() const;
  48. /** Returns the name of the underlying class, similiar to Python's type */
  49. virtual std::string GetName() const {
  50. return this->CName;
  51. }
  52. // ==================== OPERATORS =======================
  53. // ==================== OPERATIONS =======================
  54. /** Sets the number of desired convolutions. From Anderson, where
  55. this value is called NB:
  56. NUMBER OF LAGGED CONVOLUTIONS DESIRED (NB.GE.1). USE
  57. NB=1 IF B=BMIN=BMAX (I.E.,NO LAGGING DESIRED). USE
  58. NB>1 IF B IS LAGGED IN (BMIN,BMAX), WHERE
  59. BMIN=BMAX*DEXP(-.1D0*(NB-1)) DOES NOT UNDERFLOW THE DEXP
  60. RANGE. THE B-LAGGED SPACING IS .1D0 IN LOG-SPACE. FOR
  61. CONVENIENCE IN SPLINE INTERPOLATION LATER, EACH B IN
  62. (BMIN,BMAX) IS RETURNED IN ARRAY ARG(I),I=1,NB, WHERE
  63. ARG(I+1)/ARG(I)=DEXP(.1D0) FOR ALL I. IF BMAX>BMIN>0 IS
  64. GIVEN, THEN AN EFFECTIVE VALUE OF NB IS DETERMINED AS
  65. NB=DINT(10.*DLOG(BMAX/BMIN))+I, WHERE I>1 IS RECOMMENDED,
  66. PARTICULARLY IF USING SUBSEQUENT SPLINE INTERPOLATION FOR
  67. A DIFFERENT B-SPACING THAN USED IN THE DIGITAL FILTER. IF
  68. SPLINE INTERPOLATION IS TO BE USED LATER, IT IS GENERALLY
  69. BEST TO USE DLOG(ARG(I)) INSTEAD OF ARG(I) -VS- DANS(I),
  70. FOR I=1,NB.
  71. */
  72. void SetNumConv(const int& i);
  73. /** Evaluates related integrals */
  74. void ComputeRelated(const Real& rho,
  75. IntegrationKernel<Scalar>* Kernel);
  76. /** Evaluates the integral
  77. @param[in]tol REQUESTED TRUNCATION TOLERANCE AT BOTH FILTER TAILS
  78. FOR ADAPTIVE CONVOLUTION FOR ALL NB TRANSFORMS. THE
  79. TRUNCATION CRITERION IS ESTABLISHED DURING CONVOLUTION IN
  80. A FIXED ABSCISSA RANGE (USING WEIGHTS 426-461) OF THE
  81. COSINE FILTER AS THE MAXIMUM ABSOLUTE CONVOLVED PRODUCT
  82. TIMES TOL. THE CONVOLUTION SUMMATION IS TERMINATED
  83. ON EITHER SIDE OF THE FIXED RANGE WHENEVER THE ABSOLUTE
  84. PRODUCT .LE. THE TRUNCATION CRITERION. IN GENERAL, A
  85. DECREASING TOLERANCE WILL PRODUCE HIGHER ACCURACY SINCE
  86. MORE FILTER WEIGHTS ARE USED (UNLESS EXPONENT UNDERFLOW
  87. OCCURS IN THE TRANSFORM INPUT FUNCTION EVALUATION).
  88. ONE MAY SET TOL=0.D0 TO OBTAIN MAXIMUM ACCURACY FOR ALL
  89. NB DOUBLE-PRECISION COSINE TRANSFORMS IN DANS(NB).
  90. HOWEVER, THE ACTUAL RELATIVE ERRORS CANNOT BE EXPECTED TO
  91. BE SMALLER THAN ABOUT .1D-12 REGARDLESS OF THE TOLERANCE
  92. VALUE USED, SINCE DOUBLE-PRECISION FILTER WEIGHTS AND A
  93. DOUBLE-PRECISION FUNCTION ARE USED. IN ANY EVENT,
  94. ONE SHOULD ALWAYS CHOOSE TOL<<DESIRED RELATIVE ERROR.
  95. ** ACCURACY WARNING ** SOME HIGHLY OSCILLATORY FUNCTIONS
  96. FUN(G) AND (OR) LIMITING CASES OF B NEAR MACHINE-ZERO
  97. (OR INFINITY) SHOULD BE AVOIDED, OTHERWISE UNSATISFACTORY
  98. RESULTS (E.G., RELATIVE & ABSOLUTE ERRORS>>TOL) MAY OCCUR.
  99. @param[in] ntol NUMBER OF CONSECUTIVE TIMES THE TRUNCATION CRITERION (TOL)
  100. IS TO BE MET AT EITHER FILTER TAIL BEFORE FILTER
  101. TRUNCATION OCCURS. NTOL=1 SHOULD BE USED FOR INPUT
  102. FUNCTIONS THAT DO NOT HAVE MANY ZEROS IN (0,INFINITY). FOR
  103. OSCILLATORY FUNCTIONS WITH MANY ZEROS, NTOL>1 MAY BE USED
  104. TO INSURE A PREMATURE CUTOFF DOES NOT OCCUR FOR TRUNCATION
  105. (SEE USE OF ITOL,NTOL,TOL IN THE CODE BELOW).
  106. @param[in] rho integration argument argument
  107. */
  108. void Compute(const Real& rho, const int& ntol, const Real& tol);
  109. /** Attaches the integration kernel */
  110. void AttachKernel(IntegrationKernel<Scalar> *Kernel);
  111. /** Detaches the integration kernel */
  112. void DetachKernel( );
  113. // ==================== ACCESS =======================
  114. /** Returns the Vector of Abscissa arguments
  115. */
  116. VectorXr GetAbscissaArguments();
  117. Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic > GetAnswer();
  118. /** Returns the number of evaluations of kernel */
  119. int GetNumFun();
  120. // ==================== INQUIRY =======================
  121. protected:
  122. // ==================== LIFECYCLE =======================
  123. // ==================== DATA MEMBERS =========================
  124. /** A rewrite of Anderson's Pseudo-subroutine. */
  125. void StoreRetreive(const int& idx, const int& lag, const Real& y,
  126. Scalar& Zsum, const int& jrel, Scalar& C);
  127. // ==================== OPERATIONS ==============================
  128. /** Sets the filter weights as prescribed by Anderson. This is called
  129. automatically when the SetBesselOrder(int ) is called. This is
  130. a protected function and cannot be called directly.
  131. */
  132. virtual void SetFilterWeights()=0;
  133. /** Computes the absolute maximum of the scalar */
  134. Scalar AbsMax(const Scalar& C, const Scalar& Cmax);
  135. // ==================== DATA MEMBERS ==============================
  136. /** The hankel transform wavenumber embedded in the integral */
  137. Real Lambda;
  138. /** Number of times kernel was evaluated */
  139. int NumFun;
  140. /** Number of lagged convolutions
  141. must be greater or equal to 1
  142. It is set automatically in the @see Compute function so
  143. that \f$ \rho \exp\left( -.1*(\mathtt{NumConv} -1) \right) \f$
  144. does not underflow the exponent range
  145. */
  146. int NumConv;
  147. /** Number of related kernels */
  148. int NumRel;
  149. /** Used as base for filter abscissa generation */
  150. Real ABSCISSA;
  151. /** Also used in abscissa generation \f$ ABSE = \exp{.1} \f$ */
  152. const Real ABSE;
  153. /** Also used in abscissa generation \f$ ABSER = 1 / \exp{.1} \f$ */
  154. const Real ABSER;
  155. /** Counter for calculated */
  156. int icount;
  157. /** Index of special case low side convolution filter weights */
  158. int ilow;
  159. /** Index of special case right side convolution filter weights */
  160. int ihi;
  161. /** Kernel Calculator */
  162. IntegrationKernel<Scalar> *IntKernel;
  163. /** Holds answer, dimensions are NumConv, and NumberRelated. */
  164. Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> Ans;
  165. /** Filter weight coefficients.
  166. */
  167. VectorXr FilterWeights;
  168. /** Stored abscissa arguments
  169. */
  170. VectorXr Arg;
  171. /** Work from Anderson
  172. */
  173. Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> Work;
  174. /// Key used internally
  175. Eigen::Matrix<int, Eigen::Dynamic, 1> Key;
  176. private:
  177. /** ASCII string representation of the class name */
  178. static constexpr auto CName = "DigitalFilterIntegratorAnderson.h";
  179. }; // ----- end of class DigitalFilterIntegratorAnderson -----
  180. /////////////////////////////////////////
  181. /////////////////////////////////////////
  182. // Templated implimentation //
  183. /////////////////////////////////////////
  184. /////////////////////////////////////////
  185. template <typename Scalar>
  186. std::ostream &operator<<(std::ostream &stream, const DigitalFilterIntegratorAnderson<Scalar> &ob) {
  187. stream << ob.Serialize() << "\n";
  188. return stream;
  189. }
  190. // ==================== LIFECYCLE =======================
  191. template <typename Scalar>
  192. DigitalFilterIntegratorAnderson<Scalar>::
  193. DigitalFilterIntegratorAnderson(const ctor_key& key) :
  194. LemmaObject(key), Lambda(0), NumFun(0), NumConv(0), NumRel(0),
  195. ABSCISSA(0),
  196. ABSE(1.10517091807564762), // exp(.1)
  197. ABSER(0.904837418035959573), // 1/exp(.1)
  198. ilow(0), ihi(0), IntKernel(NULL) {
  199. }
  200. template <typename Scalar>
  201. YAML::Node DigitalFilterIntegratorAnderson<Scalar>::Serialize() const {
  202. YAML::Node node = LemmaObject::Serialize();
  203. node.SetTag( GetName() );
  204. //node["Type"] = enum2String(Type);
  205. //node["Location"] = Location;
  206. //node["Phat"] = Phat;
  207. //node["Freqs"] = Freqs;
  208. //node["Phase"] = Phase;
  209. //node["Moment"] = Moment;
  210. return node;
  211. }
  212. template <typename Scalar>
  213. DigitalFilterIntegratorAnderson<Scalar>::~DigitalFilterIntegratorAnderson( ) {
  214. }
  215. template <typename Scalar>
  216. Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic >
  217. DigitalFilterIntegratorAnderson<Scalar>::GetAnswer() {
  218. return Ans;
  219. }
  220. // ==================== OPERATIONS =======================
  221. template <typename Scalar>
  222. void DigitalFilterIntegratorAnderson<Scalar>::SetNumConv(const int& i) {
  223. this->NumConv = i;
  224. }
  225. template <typename Scalar>
  226. void DigitalFilterIntegratorAnderson<Scalar>::
  227. AttachKernel(IntegrationKernel<Scalar> *ck) {
  228. if (this->IntKernel == ck) return;
  229. if (this->IntKernel != NULL) {
  230. this->IntKernel->DetachFrom(this);
  231. }
  232. ck->AttachTo(this);
  233. this->IntKernel = ck;
  234. }
  235. template <typename Scalar>
  236. void DigitalFilterIntegratorAnderson<Scalar>::DetachKernel( ) {
  237. if (this->IntKernel != NULL) {
  238. this->IntKernel->DetachFrom(this);
  239. }
  240. this->IntKernel = NULL;
  241. }
  242. // template < >
  243. // inline Complex DigitalFilterIntegratorAnderson<Complex>::AbsMax(const Complex& C,
  244. // const Complex& Cmax) {
  245. // return Complex(std::max(std::abs(real(C)), std::real(Cmax)),
  246. // std::max(std::abs(imag(C)), std::imag(Cmax)) );
  247. // }
  248. // template < >
  249. // Real DigitalFilterIntegratorAnderson<Real>::AbsMax(const Real& C,
  250. // const Real& Cmax) {
  251. // return std::max(C, Cmax);
  252. // }
  253. template <typename Scalar>
  254. VectorXr DigitalFilterIntegratorAnderson<Scalar>::GetAbscissaArguments() {
  255. return this->Arg;
  256. }
  257. // ///////////////////////////////////////////
  258. // // Computes the transform
  259. //
  260. // template < >
  261. // void DigitalFilterIntegratorAnderson<Real>::Compute(const Real& rho,
  262. // const int& ntol, const Real& tol) {
  263. //
  264. // Real y1 = this->ABSCISSA/rho;
  265. // this->Key.setZero();
  266. //
  267. // // Check to make sure everything is set
  268. // if (rho<=0) {
  269. // throw std::runtime_error("In DigitalFilterIntegratorAnderson Argument rho < 0.");
  270. // }
  271. //
  272. // if (this->NumConv<1) {
  273. // throw std::runtime_error("In DigitalFilterIntegratorAnderson NumConv is less than 1.");
  274. // }
  275. //
  276. // if (this->IntKernel == NULL) {
  277. // throw std::runtime_error("In DigitalFilterIntegratorAnderson Unset Kernel Calculator");
  278. // }
  279. //
  280. // Arg = VectorXr::Zero(this->NumConv);
  281. // Real y = std::pow(rho*ABSER, this->NumConv-1);
  282. //
  283. // if (y <= 0) {
  284. // std::cerr << "Exponent Underflow Error";
  285. // throw std::underflow_error("Exponent underflow");
  286. // }
  287. //
  288. // this->Work.resize(Eigen::NoChange, this->IntKernel->GetNumRel());
  289. //
  290. // // Main Loop
  291. // int itol = 0;
  292. // int none = 0;
  293. // this->NumFun = 0;
  294. // int idx = 0;
  295. // int istore = 0;
  296. // Real Sum(0.);
  297. // Real Cmax(0.);
  298. // Real C(0.);
  299. // Ans.resize(this->NumConv, this->IntKernel->GetNumRel());
  300. // Ans.setZero();
  301. // // 1010 Loop
  302. // for (int ilag=0; ilag < this->NumConv; ++ilag) {
  303. // istore = this->NumConv - 1 - ilag;
  304. // if (ilag > 0) y1 *= ABSE;
  305. // Arg(istore) = ABSCISSA/y1;
  306. //
  307. // // 1000 Loop
  308. // for (int irel=0; irel < this->IntKernel->GetNumRel(); ++irel) {
  309. // //this->SetBesselOrder(this->Ckernel->GetBesselOrder(irel));
  310. // none = 0;
  311. // itol = ntol;
  312. // Sum = Real(0);
  313. // Cmax = Real(0);
  314. // y = y1;
  315. // // Begin right side convolution at weight 298
  316. // // counting from 0
  317. // idx = ilow;
  318. // y *= ABSE;
  319. // // Code Block 20 in Anderson
  320. // do {
  321. // this->StoreRetreive(idx, ilag, y, Sum, irel, C);
  322. // Cmax = AbsMax(C, Cmax);
  323. // ++idx;
  324. // y *= ABSE;
  325. // } while (idx <= ihi);
  326. // //if (real(Cmax) == 0 && imag(Cmax) == 0) none = 1;
  327. // if (Cmax == Real(0)) none = 1;
  328. // Cmax *= tol;
  329. // // Code Block 30 in Anderson
  330. // do {
  331. // this->StoreRetreive(idx, ilag, y, Sum, irel, C);
  332. // if (std::abs(C) <= Cmax) {
  333. // --itol;
  334. // if (itol < 0 || idx > FilterWeights.size()-1) break;
  335. // } else {
  336. // itol = ntol;
  337. // }
  338. // ++idx;
  339. // y *= ABSE;
  340. // } while (idx < FilterWeights.size());
  341. // itol = ntol;
  342. // y = y1;
  343. // // Code Block 60 in Anderson
  344. // idx = ilow-1;
  345. // do {
  346. // this->StoreRetreive(idx, ilag, y, Sum, irel, C);
  347. // if (std::abs(C) <= Cmax && none == 0) {
  348. // --itol;
  349. // if (itol < 0 || idx < 0) break;
  350. // } else {
  351. // itol = ntol;
  352. // }
  353. // --idx;
  354. // y *= ABSER;
  355. // } while (idx>=0);
  356. // Ans(istore, irel) = Sum/Arg(istore);
  357. // } // End of 1000 loop
  358. // } // End of 1010 loop
  359. // }
  360. //
  361. //
  362. // template < >
  363. // void DigitalFilterIntegratorAnderson<Complex>::Compute(const Real &rho,
  364. // const int& ntol, const Real &tol) {
  365. //
  366. // Real y1 = this->ABSCISSA/rho;
  367. //
  368. // this->Key.setZero();
  369. //
  370. // // Check to make sure everything is set
  371. // if (rho<=0) {
  372. // throw std::runtime_error("In DigitalFilterIntegratorAnderson Argument rho < 0.");
  373. // }
  374. //
  375. // if (this->NumConv<1) {
  376. // throw std::runtime_error("In DigitalFilterIntegratorAnderson NumConv is less than 1.");
  377. // }
  378. //
  379. // if (this->IntKernel == NULL) {
  380. // throw std::runtime_error("In DigitalFilterIntegratorAnderson Unset Kernel Calculator");
  381. // }
  382. //
  383. // Arg = VectorXr::Zero(this->NumConv);
  384. // Real y = std::pow(rho*ABSER, this->NumConv-1);
  385. //
  386. // if (y <= 0) {
  387. // std::cerr << "Exponent Underflow Error";
  388. // throw std::underflow_error("Exponent underflow");
  389. // }
  390. //
  391. // this->Work.resize(Eigen::NoChange, this->IntKernel->GetNumRel());
  392. //
  393. // // Main Loop
  394. // int itol = 0;
  395. // int none = 0;
  396. // this->NumFun = 0;
  397. // int idx = 0;
  398. // int istore = 0;
  399. // Complex Zsum(0.);
  400. // Complex Cmax(0.);
  401. // Complex C(0.);
  402. // Ans.resize(this->NumConv, this->IntKernel->GetNumRel());
  403. // Ans.setZero();
  404. // // 1010 Loop
  405. // for (int ilag=0; ilag < this->NumConv; ++ilag) {
  406. // istore = this->NumConv - 1 - ilag;
  407. // if (ilag > 0) y1 *= ABSE;
  408. // Arg(istore) = ABSCISSA/y1;
  409. // // 1000 Loop
  410. // for (int irel=0; irel < this->IntKernel->GetNumRel(); ++irel) {
  411. // //this->SetBesselOrder(this->Ckernel->GetBesselOrder(irel));
  412. // none = 0;
  413. // itol = ntol;
  414. // Zsum = Complex(0);
  415. // Cmax = Complex(0);
  416. // y = y1;
  417. // // Begin right side convolution at weight 298
  418. // // counting from 0
  419. // idx = ilow;
  420. // y *= ABSE;
  421. // // Code Block 20 in Anderson
  422. // do {
  423. // this->StoreRetreive(idx, ilag, y, Zsum, irel, C);
  424. // Cmax = AbsMax(C, Cmax);
  425. // ++idx;
  426. // y *= ABSE;
  427. // } while (idx <= ihi);
  428. // //if (real(Cmax) == 0 && imag(Cmax) == 0) none = 1;
  429. // if (Cmax == Complex(0)) none = 1;
  430. // Cmax *= tol;
  431. // // Code Block 30 in Anderson
  432. // do {
  433. // this->StoreRetreive(idx, ilag, y, Zsum, irel, C);
  434. // if ( std::abs(real(C)) <= real(Cmax) &&
  435. // std::abs(imag(C)) <= imag(Cmax) ) {
  436. // --itol;
  437. // if (itol < 0 || idx > FilterWeights.size()-1) break;
  438. // } else {
  439. // itol = ntol;
  440. // }
  441. // ++idx;
  442. // y *= ABSE;
  443. // } while (idx < FilterWeights.size());
  444. // itol = ntol;
  445. // y = y1;
  446. // // Code Block 60 in Anderson
  447. // idx = ilow-1;
  448. // do {
  449. // this->StoreRetreive(idx, ilag, y, Zsum, irel, C);
  450. // if ( std::abs(real(C)) <= real(Cmax) &&
  451. // std::abs(imag(C)) <= imag(Cmax) &&
  452. // none == 0 ) {
  453. // --itol;
  454. // if (itol < 0 || idx < 0) break;
  455. // } else {
  456. // itol = ntol;
  457. // }
  458. // --idx;
  459. // y *= ABSER;
  460. // } while (idx>=0);
  461. // Ans(istore, irel) = Zsum/Arg(istore);
  462. // } // End of 1000 loop
  463. // } // End of 1010 loop
  464. // }
  465. template <typename Scalar>
  466. int DigitalFilterIntegratorAnderson<Scalar>::GetNumFun() {
  467. return NumFun;
  468. }
  469. // generic rewrite of store-retreive 'pseudo-subroutine'
  470. template <typename Scalar>
  471. void DigitalFilterIntegratorAnderson<Scalar>::StoreRetreive(const int &idx,
  472. const int& lag, const Real& y, Scalar& Sum,
  473. const int& jrel, Scalar& C) {
  474. int look = idx+lag;
  475. int iq = look/FilterWeights.size();
  476. int ir = look%FilterWeights.size();
  477. int iroll = iq*(FilterWeights.size()-1);
  478. if(this->Key(ir) <= iroll) {
  479. this->Key(ir) = iroll + ir;
  480. this->Lambda = y;
  481. ++this->NumFun;
  482. for (int ir2=0; ir2<IntKernel->GetNumRel(); ++ir2) {
  483. this->Work(ir, ir2) = this->IntKernel->Argument(this->Lambda, ir2);
  484. }
  485. }
  486. C = this->Work(ir, jrel) * this->FilterWeights(idx);
  487. Sum += C;
  488. return;
  489. }
  490. } // ----- end of Lemma name -----
  491. #endif // ----- #ifndef DIGITALFILTERINTEGRATOR_INC -----