Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
tline.h
Go to the documentation of this file.
1#ifndef TLINE_H
2#define TLINE_H
3
4/*
5Copyright (c) 2005 Igor B. Smirnov
6
7The file can be used, copied, modified, and distributed
8according to the terms of GNU Lesser General Public License version 2.1
9as published by the Free Software Foundation,
10and provided that the above copyright notice, this permission notice,
11and notices about any modifications of the original text
12appear in all copies and in supporting documentation.
13The file is provided "as is" without express or implied warranty.
14*/
15
16#include <vector>
18#include "wcpplib/math/minmax.h"
19
20//#define TLINE_REDUCE_TO_RAW_ARR // useful for acceleration of PointCoorMesh
21// if the type D keeps elements in consecutive array
22// whose address can be obtained as address of the first element.
23// In PointCoorMesh this all is switched by the following way:
24//#ifndef TLINE_REDUCE_TO_RAW_ARR
25// D* amesh;
26//#else
27// T* amesh;
28//#endif
29// In constructors the assignment is switched by the following way:
30//#ifndef TLINE_REDUCE_TO_RAW_ARR
31// amesh = famesh;
32// xmin = (*amesh)[0];
33// xmax = (*amesh)[q-1];
34//#else
35// amesh = &((*famesh)[0]);
36// xmin = amesh[0];
37// xmax = amesh[q-1];
38//#endif
39// Note that in both cases only the address is kept in this class and the
40// corresponding object is not copied.
41// If Copying is necessary, one can use CopiedPointCoorMesh.
42// Note that class CopiedPointCoorMesh, based on DynLinArr,
43// also provides acceleration based on the use of raw array
44// address and switched on by TLINE_REDUCE_TO_RAW_ARR.
45// Note that this class does not use .acu() functions of DynLinArr,
46// allowing for the use of unchecked fast access
47// (since these functions were written after tline was done).
48
49//#define CHECK_POINT_MESH //verifies that the points are in increasing order.
50// It is indeed long and may be inacceptable for some applications.
51
52namespace Heed {
53
54/// Mesh with equal steps.
55/// Determined by the number of "bins", minimum and maximum.
56/// The object of this class keeps all ingredients in it.
57/// It can be therefore copied and deleted freely.
58/// T is the type of returned value.
59/// T cannot be const.
60/// At construction q has meaning of number of intervals.
61
62template <class T>
64 public:
65 /// Get number of intervals.
66 inline long get_qi(void) const { return q; }
67
68 inline T get_xmin(void) const { return xmin; }
69 inline T get_xmax(void) const { return xmax; }
70
71 /// Get single coordinate of the point in the mesh.
72 /// It can be last point of the last interval.
73 inline void get_scoor(long n, T& b) const { b = xmin + n * step; }
74 /// Get interval. Return 1 if interval is found.
75 inline int get_interval(long n, T& b1, T& b2) const {
76 if (n < 0 || n >= q) return 0;
77 b1 = xmin + n * step;
78 b2 = b1 + step;
79 return 1;
80 }
81
82 /** Get interval.
83 * \param x coordinate
84 * \param n1 bin number
85 */
86 virtual int get_interval(T x, long& n1) const;
87
88 // The same as above, but returns more information:
89 // n1, b1: the bin number and left border,
90 // n2, b2: the next bin number and its left
91 virtual int get_interval(T x, long& n1, T& b1, long& n2, T& b2) const;
92
93 virtual int get_interval_extrap(T x, long& n1, T& b1, long& n2, T& b2) const;
94 // returns 1 if x inside xmin and xmax and therefore b1 and b2,
95 // returns 0 if x < xmin
96 // In this case n1 = 0, n2 = 1, b1 and b2 are corresponding.
97 // returns 2 if x > xmax
98 // In this case n1 = q-1, n2 = q, b1 and b2 are corresponding.
99
100 inline int get_step(long n, T& fstep) const {
101 if (n < 0 || n >= q) return 0;
102 fstep = step;
103 return 1;
104 }
105
106 EqualStepCoorMesh<T>() : q(0), xmin(0), xmax(0), step(0) {}
107 EqualStepCoorMesh<T>(long fq, T fxmin, T fxmax);
108 void print(std::ostream& file) const;
109
110 private:
111 // Number of steps or intervals.
112 /// Attention: if you count the number of points with the
113 /// last point of the last step there will be q+1 points.
114 long q;
115 T xmin;
116 T xmax;
117 T step;
118};
119
120template <class T>
122 : q(fq), xmin(fxmin), xmax(fxmax) {
123 mfunname(
124 "template<class T> EqualStepCoorMesh<T>::EqualStepCoorMesh<T>(long "
125 "fq, T fxmin, T fxmax)");
126 check_econd11(q, < 0, mcerr);
127 check_econd24(q, ==, 0, &&, xmin, <, xmax, mcerr);
128 check_econd12(xmin, >, xmax, mcerr);
129 step = (fxmax - fxmin) / q;
130 check_econd11(step, == 0, mcerr);
131}
132
133template <class T>
134int EqualStepCoorMesh<T>::get_interval(T x, long& n1) const {
135 if (x < xmin || x >= xmax) {
136 n1 = 0;
137 return 0;
138 }
139 n1 = long((x - xmin) / step);
140 if (n1 < 0) {
141 mcerr << "ERROR in EqualStepCoorMesh<T>::get_interval: n1 < 0\n";
142 print(mcerr);
143 Iprintn(mcerr, x);
144 Iprintn(mcerr, n1);
145 spexit(mcerr);
146 }
147 return 1;
148}
149
150template <class T>
151int EqualStepCoorMesh<T>::get_interval(T x, long& n1, T& b1, long& n2,
152 T& b2) const {
153 if (x < xmin || x >= xmax) {
154 n1 = 0;
155 n2 = 0;
156 b1 = 0;
157 b2 = 0;
158 return 0;
159 }
160 n1 = long((x - xmin) / step);
161 n2 = n1 + 1;
162 b1 = xmin + step * n1;
163 b2 = b1 + step;
164 if (n1 < 0 || n2 > q || b2 > xmax) {
165 mcerr << "ERROR in EqualStepCoorMesh<T>::get_interval:\n"
166 << "n1 < 0 || n2 > q || b2 > xmax\n";
167 print(mcerr);
168 Iprintn(mcerr, x);
169 Iprint4n(mcerr, n1, n2, b1, b2);
170 spexit(mcerr);
171 }
172 return 1;
173}
174
175template <class T>
176int EqualStepCoorMesh<T>::get_interval_extrap(T x, long& n1, T& b1, long& n2,
177 T& b2) const {
178 int i_ret = 1;
179
180 if (x < xmin) {
181 i_ret = 0;
182 n1 = 0;
183 n2 = 1;
184 b1 = xmin;
185 b2 = xmin + step;
186 } else if (x >= xmax) {
187 i_ret = 2;
188 n1 = q - 1;
189 n2 = q;
190 b1 = xmax - step;
191 b2 = xmax;
192 } else {
193 n1 = long((x - xmin) / step);
194 n2 = n1 + 1;
195 if (n2 == q) {
196 b2 = xmax;
197 b1 = b2 - step;
198 } else {
199 b1 = xmin + step * n1;
200 b2 = b1 + step;
201 if (n1 < 0 || n2 > q || b2 > xmax) {
202 mcerr << "ERROR in EqualStepCoorMesh<T>::get_interval_extrap:\n"
203 << "n1 < 0 || n2 > q || b2 > xmax\n";
204 print(mcerr);
205 Iprint4n(mcerr, n1, n2, b1, b2);
206 spexit(mcerr);
207 }
208 }
209 }
210 return i_ret;
211}
212
213template <class T>
214void EqualStepCoorMesh<T>::print(std::ostream& file) const {
215 Ifile << "EqualStepCoorMesh<T>:\n";
216 indn.n += 2;
217 Ifile << "Type of T is (in internal notations) " << typeid(T).name() << '\n';
218 Iprint4n(file, q, xmin, xmax, step);
219 indn.n -= 2;
220}
221
222template <class T>
223std::ostream& operator<<(std::ostream& file, const EqualStepCoorMesh<T>& f) {
224 f.print(file);
225 return file;
226}
227
228template <class T>
229std::istream& operator>>(std::istream& file, EqualStepCoorMesh<T>& f) {
230 mfunname("istream& operator>>(istream& file, EqualStepCoorMesh<T>& f)");
231 definp_endpar dep(&file, 0, 1, 0);
232 set_position("Type of T is (in internal notations)", *dep.istrm, dep.s_rewind,
233 dep.s_req_sep);
234 long q;
235 T xmin;
236 T xmax;
237 DEFINPAP(q);
238 DEFINPAP(xmin);
239 DEFINPAP(xmax);
240 f = EqualStepCoorMesh<T>(q, xmin, xmax);
241 return file;
242}
243
244template <class T>
246 if (f1.get_qi() != f2.get_qi() || f1.get_xmin() != f2.get_xmin() ||
247 f1.get_xmax() != f2.get_xmax())
248 return 0;
249 else
250 return 1;
251}
252
253template <class T>
255 T prec) {
256 if (f1.get_qi() != f2.get_qi() ||
257 !apeq_mant(f1.get_xmin(), f2.get_xmin(), prec) ||
258 !apeq_mant(f1.get_xmax(), f2.get_xmax(), prec)) {
259 Iprintn(mcout, !apeq_mant(f1.get_xmin(), f2.get_xmin(), prec));
260 Iprintn(mcout, !apeq_mant(f1.get_xmax(), f2.get_xmax(), prec));
261 return 0;
262 } else
263 return 1;
264}
265
266template <class T>
268 if (f1.get_qi() != f2.get_qi() || f1.get_xmin() != f2.get_xmin() ||
269 f1.get_xmax() != f2.get_xmax())
270 return 1;
271 else
272 return 0;
273}
274
275template <class T, class D>
276// D is anything allowing indexing
277long t_find_interval(double x, long q, const D& coor) {
278 long n1, n2, n3;
279#ifndef TLINE_REDUCE_TO_RAW_ARR
280 if (q <= 1) return -1;
281 if (x < coor[0] || x > coor[q - 1]) return -1;
282 if (x < coor[1]) return 0;
283 if (x >= coor[q - 2]) return q - 2;
284 n1 = 0;
285 n2 = q - 1;
286 while (n2 - n1 > 1) {
287 n3 = n1 + (n2 - n1) / 2;
288 if (x < coor[n3])
289 n2 = n3;
290 else
291 n1 = n3;
292 }
293 return n1;
294#else
295 T* arr = &(coor[0]); // take the address of the first element
296 if (q <= 1) return -1;
297 if (x < arr[0] || x > arr[q - 1]) return -1;
298 if (x < arr[1]) return 0;
299 if (x >= arr[q - 2]) return q - 2;
300 n1 = 0;
301 n2 = q - 1;
302 while (n2 - n1 > 1) {
303 n3 = n1 + (n2 - n1) / 2;
304 if (x < arr[n3])
305 n2 = n3;
306 else
307 n1 = n3;
308 }
309 return n1;
310
311#endif
312}
313
314// Use (scan) only end of the array starting from index n_start
315// as if it is 0
316// The return index:
317// -1 if less than corr[n_start] or more than coor[q-1]
318// Index if inside
319
320template <class T, class D>
321long t_find_interval_end(double x, long q, const D& coor, long n_start) {
322 long n1, n2, n3;
323 if (n_start < 0 || n_start > q - 1) {
324 mcerr << " ERROR in t_find_interval_end(...):\n";
325 mcerr << "n_start < 0 || n_start > q-1\n";
326 Iprint2n(mcout, n_start, q);
327 spexit(mcerr);
328 }
329#ifndef TLINE_REDUCE_TO_RAW_ARR
330 // if(q <= 1) return -1;
331 if (q - n_start <= 1) return -1;
332 if (x < coor[n_start] || x > coor[q - 1]) return -1;
333 if (x < coor[n_start + 1]) return n_start;
334 if (x >= coor[q - 2]) return q - 2;
335 n1 = n_start;
336 n2 = q - 1;
337 while (n2 - n1 > 1) {
338 n3 = n1 + (n2 - n1) / 2;
339 if (x < coor[n3])
340 n2 = n3;
341 else
342 n1 = n3;
343 }
344 return n1;
345#else
346 T* arr = &(coor[0]); // take the address of the first element
347 // if(q <= 1) return -1;
348 if (q - n_start <= 1) return -1;
349 if (x < arr[n_start] || x > arr[q - 1]) return -1;
350 if (x < arr[n_start + 1]) return n_start;
351 if (x >= arr[q - 2]) return q - 2;
352 n1 = n_start;
353 n2 = q - 1;
354 while (n2 - n1 > 1) {
355 n3 = n1 + (n2 - n1) / 2;
356 if (x < arr[n3])
357 n2 = n3;
358 else
359 n1 = n3;
360 }
361 return n1;
362
363#endif
364}
365
366/// Generic mesh with arbitrary steps.
367/// The array determining the step edges is located somewhere outside.
368/// In object of this class only the raw pointer is contained with consequences:
369
370/*
371Attention, here there is a raw pointer to mesh.
372It is not possible to use the passive pointer since
373if D is plain array, the reference cannot be registered.
374This is deviation from methodology, but it is not clear what can
375be done here. The mesh cannot be copyed or deleted after the PointCoorMesh
376is initialized. Obviously, the latter should be initialized immidiately
377before the use and not keept permanentely.
378Obviously again, that sooner or later the user can forget about this
379(the author also once almost forgot and was at the edge of error)
380and try to initialize it permanantely and then copy together with the mesh.
381This would be an error, which again confirms the correctness of the
382object management methodology, which forbids to place the raw pointers
383in classes. This class (below) may be understood as a temporary exclusion,
384which should be treated with great care.
385At construction q has meaning of number of points.
386 */
387
388template <class T, class D>
390 public:
391 inline long get_qi(void) const { return q - 1; }
392 inline T get_xmin(void) const { return xmin; }
393 inline T get_xmax(void) const { return xmax; }
394 inline void get_scoor(long n, T& b) const {
395#ifndef TLINE_REDUCE_TO_RAW_ARR
396 b = (*amesh)[n];
397#else
398 b = amesh[n];
399#endif
400 }
401 virtual int get_interval(long n, T& b1, T& b2) const {
402 if (n < 0 || n >= q - 1) return 0;
403#ifndef TLINE_REDUCE_TO_RAW_ARR
404 b1 = (*amesh)[n];
405 b2 = (*amesh)[n + 1];
406#else
407 b1 = amesh[n];
408 b2 = amesh[n + 1];
409#endif
410 return 1;
411 }
412
413 int get_interval(T x, long& n1) const;
414
415 int get_interval(T x, long& n1, T& b1, long& n2, T& b2) const;
416
417 int get_interval_extrap(T x, long& n1, T& b1, long& n2, T& b2) const;
418
419 inline int get_step(long n, T& fstep) const {
420 if (n < 0 || n >= q - 1) return 0;
421 T b1, b2;
422 get_interval(n, b1, b2);
423 fstep = b2 - b1;
424 return 1;
425 }
426
428 : q(0), xmin(0), xmax(0), x_old(0), n_old(-1), amesh(NULL) {
429 ;
430 }
431 PointCoorMesh<T, D>(long fq, // number of points, number of intervals
432 // is fq - 1.
433 D* famesh); // dimension is fq and the last index is fq-1
434 // This is the end point of the last interval
435 virtual ~PointCoorMesh<T, D>() {}
436 void check(void); // check that the points are sequencial.
437 // This is also done in constructor above provided that
438 // macro CHECK_POINT_MESH is initialized.
439
440 virtual void print(std::ostream& file) const;
441
442 private:
443 long q; // the number of points
444 // The number of intervals is q-1.
445 // Therefore q has to be 2 or more
446#ifndef TLINE_REDUCE_TO_RAW_ARR
447 D* amesh;
448#else
449 T* amesh;
450#endif
451 T xmin;
452 T xmax;
453 // auxiliary thing to accelerate finding intervals
454 mutable T x_old; // previous x for finding interval
455 mutable long n_old; // -1 if there is nothing
456};
457
458template <class T, class D>
460 : q(fq), x_old(0), n_old(-1) {
461 if (q <= 1) {
462 mcerr << "ERROR in PointCoorMesh<T,D>::PointCoorMesh<T,D>:\n"
463 << "q <= 1\n";
464 Iprintn(mcerr, q);
465 spexit(mcerr);
466 }
467#ifndef TLINE_REDUCE_TO_RAW_ARR
468 // amesh.put( famesh );
469 amesh = famesh;
470 xmin = (*amesh)[0];
471 xmax = (*amesh)[q - 1];
472#else
473 amesh = &((*famesh)[0]);
474 xmin = amesh[0];
475 xmax = amesh[q - 1];
476#endif
477 // check consistence
478 if (xmin > xmax) {
479 mcerr << "ERROR in PointCoorMesh<T,D>::PointCoorMesh<T,D>:\n"
480 << "xmin > xmax\n";
481 Iprint2n(mcerr, xmin, xmax);
482 spexit(mcerr);
483 }
484#ifdef CHECK_POINT_MESH
485 long n;
486 for (n = 0; n < q - 1; n++) {
487#ifndef TLINE_REDUCE_TO_RAW_ARR
488 if ((*amesh)[n] >= (*amesh)[n + 1])
489#else
490 if (amesh[n] >= amesh[n + 1])
491#endif
492 {
493 mcerr << "ERROR in PointCoorMesh<T,D>::PointCoorMesh<T,D>:\n"
494 << "amesh[n] >= amesh[n+1]\n";
495#ifndef TLINE_REDUCE_TO_RAW_ARR
496 Iprint3n(mcerr, n, (*amesh)[n], (*amesh)[n + 1]);
497#else
498 Iprint3n(mcerr, n, amesh[n], amesh[n + 1]);
499#endif
500 spexit(mcerr);
501 }
502 }
503#endif
504}
505
506template <class T, class D>
508 long n;
509 for (n = 0; n < q - 1; n++) {
510#ifndef TLINE_REDUCE_TO_RAW_ARR
511 if ((*amesh)[n] >= (*amesh)[n + 1])
512#else
513 if (amesh[n] >= amesh[n + 1])
514#endif
515 {
516 mcerr << "ERROR in PointCoorMesh<T,D>::check(void):\n"
517 << "amesh[n] >= amesh[n+1]\n";
518#ifndef TLINE_REDUCE_TO_RAW_ARR
519 Iprint3n(mcerr, n, (*amesh)[n], (*amesh)[n + 1]);
520#else
521 Iprint3n(mcerr, n, amesh[n], amesh[n + 1]);
522#endif
523 spexit(mcerr);
524 }
525 }
526}
527
528template <class T, class D>
529int PointCoorMesh<T, D>::get_interval(T x, long& n1) const {
530 if (x < xmin || x >= xmax) {
531 n1 = 0;
532 return 0;
533 }
534#ifndef TLINE_REDUCE_TO_RAW_ARR
535 if (n_old >= 0 && x_old <= x) {
536 n1 = t_find_interval_end<T, D>(x, q, *amesh, n_old);
537 } else {
538 n1 = t_find_interval<T, D>(x, q, *amesh);
539 }
540// n1 = t_find_interval< T , D >(x, q, amesh);
541#else
542 if (n_old >= 0 && x_old <= x) {
543 n1 = t_find_interval_end<T, T*>(x, q, amesh, n_old);
544 } else {
545 n1 = t_find_interval<T, T*>(x, q, amesh);
546 }
547// n1 = t_find_interval< T , T* >(x, q, &amesh);
548#endif
549
550 if (n1 < 0) {
551 mcerr << "ERROR in PointCoorMesh<T,D>::get_interval:\n"
552 << "n1 < 0\n";
553 print(mcerr);
554 Iprintn(mcerr, n1);
555 spexit(mcerr);
556 }
557 n_old = n1;
558 x_old = x;
559 return 1;
560}
561
562template <class T, class D>
563int PointCoorMesh<T, D>::get_interval(T x, long& n1, T& b1, long& n2,
564 T& b2) const {
565 if (x < xmin || x >= xmax) {
566 n1 = 0;
567 n2 = 0;
568 b1 = 0;
569 b2 = 0;
570 return 0;
571 }
572#ifndef TLINE_REDUCE_TO_RAW_ARR
573 if (n_old >= 0 && x_old <= x) {
574 n1 = t_find_interval_end<T, D>(x, q, *amesh, n_old);
575 } else {
576 n1 = t_find_interval<T, D>(x, q, *amesh);
577 }
578// n1 = t_find_interval< T , D >(x, q, amesh);
579#else
580 if (n_old >= 0 && x_old <= x) {
581 n1 = t_find_interval_end<T, T*>(x, q, amesh, n_old);
582 } else {
583 n1 = t_find_interval<T, T*>(x, q, amesh);
584 }
585// n1 = t_find_interval< T , T* >(x, q, &amesh);
586#endif
587 n2 = n1 + 1;
588 if (n1 < 0 || n1 >= q || n2 < 0 || n2 >= q) {
589 mcerr << "ERROR in PointCoorMesh<T,D>::get_interval:\n"
590 << "n1 < 0 || n1 >= q || n2 < 0 || n2 >= q\n";
591 print(mcerr);
592 Iprint2n(mcerr, n1, n2);
593 spexit(mcerr);
594 }
595#ifndef TLINE_REDUCE_TO_RAW_ARR
596 b1 = (*amesh)[n1];
597 b2 = (*amesh)[n2];
598#else
599 b1 = amesh[n1];
600 b2 = amesh[n2];
601#endif
602 if (b1 < xmin || b1 > xmax || b2 < xmin || b2 > xmax) {
603 mcerr << "ERROR in PointCoorMesh<T,D>::get_interval:\n"
604 << "b1 < xmin || b1 > xmax || b2 < xmin || b2 > xmax\n";
605 print(mcerr);
606 Iprint2n(mcerr, b1, b2);
607 spexit(mcerr);
608 }
609 n_old = n1;
610 x_old = x;
611 return 1;
612}
613
614template <class T, class D>
615int PointCoorMesh<T, D>::get_interval_extrap(T x, long& n1, T& b1, long& n2,
616 T& b2) const {
617 int i_ret = 1;
618
619 if (x < xmin) {
620 i_ret = 0;
621 n1 = 0;
622 n2 = 1;
623 b1 = xmin;
624#ifndef TLINE_REDUCE_TO_RAW_ARR
625 b2 = (*amesh)[1];
626#else
627 b2 = amesh[1];
628#endif
629 } else if (x >= xmax) {
630 i_ret = 2;
631 n1 = q - 2;
632 n2 = q - 1;
633#ifndef TLINE_REDUCE_TO_RAW_ARR
634 b1 = (*amesh)[q - 2];
635#else
636 b1 = amesh[q - 2];
637#endif
638 b2 = xmax;
639 } else {
640#ifndef TLINE_REDUCE_TO_RAW_ARR
641 if (n_old >= 0 && x_old <= x) {
642 n1 = t_find_interval_end<T, D>(x, q, *amesh, n_old);
643 } else {
644 n1 = t_find_interval<T, D>(x, q, *amesh);
645 }
646// n1 = t_find_interval< T , D >(x, q, amesh);
647#else
648 if (n_old >= 0 && x_old <= x) {
649 n1 = t_find_interval_end<T, T*>(x, q, amesh, n_old);
650 } else {
651 n1 = t_find_interval<T, T*>(x, q, amesh);
652 }
653// n1 = t_find_interval< T , T* >(x, q, &amesh);
654#endif
655 n2 = n1 + 1;
656 if (n1 < 0 || n1 >= q || n2 < 0 || n2 >= q) {
657 mcerr << "ERROR in PointCoorMesh<T,D>::get_interval:\n"
658 << "n1 < 0 || n1 >= q || n2 < 0 || n2 >= q\n";
659 print(mcerr);
660 Iprint2n(mcerr, n1, n2);
661 spexit(mcerr);
662 }
663#ifndef TLINE_REDUCE_TO_RAW_ARR
664 b1 = (*amesh)[n1];
665 b2 = (*amesh)[n2];
666#else
667 b1 = amesh[n1];
668 b2 = amesh[n2];
669#endif
670 if (b1 < xmin || b1 > xmax || b2 < xmin || b2 > xmax) {
671 mcerr << "ERROR in PointCoorMesh<T,D>::get_interval:\n"
672 << "b1 < xmin || b1 > xmax || b2 < xmin || b2 > xmax\n";
673 print(mcerr);
674 Iprint2n(mcerr, b1, b2);
675 spexit(mcerr);
676 }
677 n_old = n1;
678 x_old = x;
679 }
680 return i_ret;
681}
682
683template <class T, class D>
684void PointCoorMesh<T, D>::print(std::ostream& file) const {
685 Ifile << "PointCoorMesh<T,D>:\n";
686 indn.n += 2;
687 Ifile << "Type of T is (in internal notations) " << typeid(T).name() << '\n';
688 Ifile << "Type of D is (in internal notations) " << typeid(D).name() << '\n';
689 Iprint3n(file, q, xmin, xmax);
690 Iprint2n(file, n_old, x_old);
691#ifndef TLINE_REDUCE_TO_RAW_ARR
692 // Ifile << "(*amesh)=" << (*amesh) << '\n';
693 Ifile << "(*amesh)=" << (*amesh)[0] << '\n';
694#else
695 Ifile << "amesh:" << '\n';
696 long n;
697 indn.n += 2;
698 for (n = 0; n < q; n++) {
699 Ifile << "n=" << n << " amesh[n]=" << noindent << amesh[n] << yesindent
700 << '\n';
701 }
702 file << yesindent;
703 indn.n -= 2;
704#endif
705 indn.n -= 2;
706}
707
708template <class T, class D>
709std::ostream& operator<<(std::ostream& file, const PointCoorMesh<T, D>& f) {
710 f.print(file);
711 return file;
712}
713
714// ---------------------------------------------------------------------
715// The generic mesh which has arbitrary steps.
716// The array determining the step edges is located right in this object.
717// Note that it is difficult to make this class derived from previous one
718// due to possibility of it without ifndef TLINE_REDUCE_TO_RAW_ARR.
719// Then the previous class keeps address of D, not necessary
720// raw array or DynLinArr.
721// Note also that TLINE_REDUCE_TO_RAW_ARR works here too.
722
723//#define TLINE_COPIED_USE_ADDRESS // doublfull option.
724// If TLINE_REDUCE_TO_RAW_ARR is defined, it allows to access to content
725// of DynLinArr as to raw array.
726// If TLINE_COPIED_USE_ADDRESS is not defined, access goes through object,
727// and with doundary checks if they are activated for DynLinArr.
728// Perhaps the latter might be slower.
729
730//-------------------------------------------------------------
731
732// Step array is like a histogram.
733// Each value of y represents constant height in each interval
734// If mesh is defined by points,
735// its size should be longer by unity than the number of y-points,
736// the last x-point being represent the end of the last bin.
737
738/*
739// Extract value defined by this array for abscissa x
740template <class T, class D, class M>
741T t_value_step_ar(const M& mesh, const D& y, // array of function values
742 T x, int s_include_last_point = 0)
743 // 0 - not include, 1 - include
744{
745 mfunname("double t_value_step_ar(...)");
746 double xmin = mesh.get_xmin();
747 double xmax = mesh.get_xmax();
748 // Iprint3n(mcout, x, xmin, xmax);
749 if (x < xmin) return 0;
750 if (s_include_last_point == 0) {
751 if (x >= xmax) return 0;
752 } else {
753 if (x > xmax) return 0;
754 }
755 long n1, n2;
756 T b1, b2;
757 int i_ret = 0;
758 i_ret = mesh.get_interval(x, n1, b1, n2, b2);
759 check_econd11(i_ret, != 1, mcerr);
760 return y[n1];
761}
762
763// The same for two-dimensional array D
764template <class T, class D, class M1, class M2>
765T t_value_step_ar(const M1& mesh1, const M2& mesh2,
766 const D& y, // array of function values
767 T x1, T x2, int s_include_last_point = 0)
768 // 0 - not include, 1 - include
769{
770 mfunname("double t_value_step_ar(...)");
771 double x1min = mesh1.get_xmin();
772 double x1max = mesh1.get_xmax();
773 // Iprint3n(mcout, x, xmin, xmax);
774 if (x1 < x1min) return 0;
775 if (s_include_last_point == 0) {
776 if (x1 >= x1max) return 0;
777 } else {
778 if (x1 > x1max) return 0;
779 }
780 double x2min = mesh2.get_xmin();
781 double x2max = mesh2.get_xmax();
782 // Iprint3n(mcout, x, xmin, xmax);
783 if (x2 < x2min) return 0;
784 if (s_include_last_point == 0) {
785 if (x2 >= x2max) return 0;
786 } else {
787 if (x2 > x2max) return 0;
788 }
789 long n11, n12;
790 long n21, n22;
791 T b1, b2;
792 int i_ret = 0;
793
794 i_ret = mesh1.get_interval(x1, n11, b1, n12, b2);
795 check_econd11(i_ret, != 1, mcerr);
796
797 i_ret = mesh2.get_interval(x2, n21, b1, n22, b2);
798
799 check_econd11(i_ret, != 1, mcerr);
800 return y[n11][n21];
801}
802*/
803
804// Fill the array y like a histogram adding value val (or 1) for bin
805// corresponding to abscissa x
806/*
807template <class T, class D, class M>
808void t_hfill_step_ar(const M& mesh, const D& y, // array of function values
809 T x, T val = 1, int s_include_last_point = 0)
810 // 0 - not include, 1 - include
811{
812 mfunname("double t_hfill_step_ar(...)");
813 double xmin = mesh.get_xmin();
814 double xmax = mesh.get_xmax();
815 // Iprint3n(mcout, x, xmin, xmax);
816 if (x < xmin) return;
817 if (s_include_last_point == 0) {
818 if (x >= xmax) return;
819 } else {
820 if (x > xmax) return;
821 }
822 long n1;
823 int i_ret = 0;
824 i_ret = mesh.get_interval(x, n1);
825 check_econd11(i_ret, != 1, mcerr);
826 y[n1] += val;
827 return;
828}
829
830// The same as above, but with "ac" access instead of "[]".
831// Useful if D is DynArr.
832
833template <class T, class D, class M>
834void t_hfill_step_ar_ac(const M& mesh, const D& y, // array of function values
835 T x, T val = 1, int s_include_last_point = 0)
836 // 0 - not include, 1 - include
837{
838 mfunname("double t_hfill_step_ar(...)");
839 double xmin = mesh.get_xmin();
840 double xmax = mesh.get_xmax();
841 // Iprint3n(mcout, x, xmin, xmax);
842 if (x < xmin) return;
843 if (s_include_last_point == 0) {
844 if (x >= xmax) return;
845 } else {
846 if (x > xmax) return;
847 }
848 long n1;
849 int i_ret = 0;
850 i_ret = mesh.get_interval(x, n1);
851 check_econd11(i_ret, != 1, mcerr);
852 y.ac(n1) += val;
853 return;
854}
855
856// The same but for two-dimensional array:
857template <class T, class D, class M1, class M2>
858void t_hfill_step_ar_ac(const M1& mesh1, const M2& mesh2,
859 const D& y, // array of function values
860 T x1, T x2, T val = 1, int s_include_last_point = 0)
861 // 0 - not include, 1 - include
862{
863 mfunname("double t_hfill_step_ar(...)");
864 double x1min = mesh1.get_xmin();
865 double x1max = mesh1.get_xmax();
866 double x2min = mesh2.get_xmin();
867 double x2max = mesh2.get_xmax();
868 // Iprint3n(mcout, x, xmin, xmax);
869 if (x1 < x1min) return;
870 if (s_include_last_point == 0) {
871 if (x1 >= x1max) return;
872 } else {
873 if (x1 > x1max) return;
874 }
875 if (x2 < x2min) return;
876 if (s_include_last_point == 0) {
877 if (x2 >= x2max) return;
878 } else {
879 if (x2 > x2max) return;
880 }
881 long n1;
882 int i_ret1 = 0;
883 i_ret1 = mesh1.get_interval(x1, n1);
884 check_econd11(i_ret1, != 1, mcerr);
885 long n2;
886 int i_ret2 = 0;
887 i_ret2 = mesh2.get_interval(x2, n2);
888 check_econd11(i_ret2, != 1, mcerr);
889 y.ac(n1, n2) += val;
890 return;
891}
892*/
893
894/*
895Integrate the function represented by array y (interpreted as
896rectangular bins with height determined by the values y[n])
897from x1 to x2, taking either pure integral by x (for xpower = 0,
898that is it will be sum of function values multiplied by
899bin width)
900or int(f * x * dx) (for xpower = 1,
901the integration of product of function by x).
902*/
903
904template <class T, class D, class M>
905T t_integ_step_ar(const M& mesh, const D& y, // array of function values
906 T x1, T x2, int xpower) // currently 0 or 1
907{
908 mfunname("double t_integ_step_ar(...)");
909
910 check_econd21(xpower, != 0 &&, != 1, mcerr);
911 check_econd12(x1, >, x2, mcerr);
912 long qi = mesh.get_qi();
913 check_econd12(qi, <, 1, mcerr);
914 // if(x1 > x2) return 0;
915 double xmin = mesh.get_xmin();
916 double xmax = mesh.get_xmax();
917 if (x2 <= xmin) return 0;
918 if (x1 >= xmax) return 0;
919 if (x1 == x2) return 0;
920 long istart, iafterend; // indexes to sum total intervals
921 T s(0);
922 if (x1 <= xmin) {
923 x1 = xmin;
924 istart = 0;
925 } else {
926 long n1, n2;
927 T b1, b2;
928 int i_ret = 0;
929 i_ret = mesh.get_interval(x1, n1, b1, n2, b2);
930 // Iprint2n(mcout, x1, i_ret);
931 // Iprint4n(mcout, n1, b1, n2, b2);
932 check_econd11(i_ret, != 1, mcerr);
933 if (b2 - x1 > 0) { // otherwise it could be only equal to 0
934 if (x2 <= b2) { // if x2 in the same interval
935 if (xpower == 0) {
936 s = (x2 - x1) * y[n1];
937 } else {
938 s = 0.5 * (x2 * x2 - x1 * x1) * y[n1];
939 }
940 return s;
941 }
942 if (xpower == 0) {
943 s += (b2 - x1) * y[n1];
944 } else {
945 s += 0.5 * (b2 * b2 - x1 * x1) * y[n1];
946 }
947 }
948 istart = n2;
949 }
950 if (x2 >= xmax) {
951 x2 = xmax;
952 iafterend = qi;
953 } else {
954 long n1, n2;
955 T b1, b2;
956 int i_ret = 0;
957 i_ret = mesh.get_interval(x2, n1, b1, n2, b2);
958 // Iprint2n(mcout, x2, i_ret);
959 // Iprint4n(mcout, n1, b1, n2, b2);
960 check_econd11(i_ret, != 1, mcerr);
961 if (x2 - b1 > 0) {
962 if (xpower == 0) {
963 s += (x2 - b1) * y[n1];
964 } else {
965 s += 0.5 * (x2 * x2 - b1 * b1) * y[n1];
966 }
967 }
968 iafterend = n1;
969 }
970 // Iprint2n(mcout, istart, iafterend);
971 long i;
972 double b;
973 mesh.get_scoor(istart, b);
974 if (xpower == 0) {
975 for (i = istart; i < iafterend; i++) {
976 double a = b;
977 mesh.get_scoor(i + 1, b);
978 s += (b - a) * y[i];
979 }
980 } else {
981 for (i = istart; i < iafterend; i++) {
982 double a = b;
983 mesh.get_scoor(i + 1, b);
984 s += 0.5 * (b * b - a * a) * y[i];
985 }
986 }
987 return s;
988}
989
990/*
991Generic integration.
992fun can be modulating function - very convenient sometimes.
993np is number of interval.
994It can be used to obtain weight in a global array.
995*/
996template <class T, class D, class M>
998 const D& y, // array of function values
999 T (*fun)(long np, T xp1, T xp2, T yp, T xmin, T xmax,
1000 T x1, T x2),
1001 // This function should produce integral
1002 // form x1 to x2.
1003 T x1, T x2) {
1004 mfunname("double t_integ_step_ar(...)");
1005
1006 check_econd12(x1, >, x2, mcerr);
1007 long qi = mesh.get_qi();
1008 check_econd12(qi, <, 1, mcerr);
1009 // if(x1 > x2) return 0;
1010 double xmin = mesh.get_xmin();
1011 double xmax = mesh.get_xmax();
1012 if (x2 <= xmin) return 0;
1013 if (x1 >= xmax) return 0;
1014 if (x1 == x2) return 0;
1015 long istart, iafterend; // indexes to sum total intervals
1016 T s(0);
1017 if (x1 <= xmin) {
1018 x1 = xmin;
1019 istart = 0;
1020 } else {
1021 long n1, n2;
1022 T b1, b2;
1023 int i_ret = 0;
1024 i_ret = mesh.get_interval(x1, n1, b1, n2, b2);
1025 // Iprint2n(mcout, x1, i_ret);
1026 // Iprint4n(mcout, n1, b1, n2, b2);
1027 check_econd11(i_ret, != 1, mcerr);
1028 if (b2 - x1 > 0) // otherwise it could be only equal to 0
1029 {
1030 if (x2 <= b2) // if x2 in the same interval
1031 {
1032 s = fun(n1, b1, b2, y[n1], xmin, xmax, x1, x2);
1033 return s;
1034 }
1035 s = fun(n1, b1, b2, y[n1], xmin, xmax, x1, x2);
1036 }
1037 istart = n2;
1038 }
1039 if (x2 >= xmax) {
1040 x2 = xmax;
1041 iafterend = qi;
1042 } else {
1043 long n1, n2;
1044 T b1, b2;
1045 int i_ret = 0;
1046 i_ret = mesh.get_interval(x2, n1, b1, n2, b2);
1047 // Iprint2n(mcout, x2, i_ret);
1048 // Iprint4n(mcout, n1, b1, n2, b2);
1049 check_econd11(i_ret, != 1, mcerr);
1050 if (x2 - b1 > 0) {
1051 s += fun(n1, b1, b2, y[n1], xmin, xmax, b1, x2);
1052 }
1053 iafterend = n1;
1054 }
1055 // Iprint2n(mcout, istart, iafterend);
1056 long i;
1057 double b;
1058 mesh.get_scoor(istart, b);
1059 for (i = istart; i < iafterend; i++) {
1060 double a = b;
1061 mesh.get_scoor(i + 1, b);
1062 s += fun(i, a, b, y[i], xmin, xmax, a, b);
1063 }
1064 // Iprintn(mcout, s);
1065
1066 // T t;
1067 return s;
1068}
1069
1070// simplified version for total integration along all the mesh
1071// It is without "power" as function above.
1072// So it is sum of functions multiplied by bin widths.
1073/*
1074template <class T, class D, class M>
1075T t_total_integ_step_ar(const M& mesh, const D& y // array of function values
1076 ) {
1077 mfunname("double t_total_integ_step_ar(...)");
1078
1079 long qi = mesh.get_qi();
1080 check_econd12(qi, <, 1, mcerr);
1081 // if(x1 > x2) return 0;
1082 long istart, iafterend; // indexes to sum total intervals
1083 T s(0);
1084 istart = 0;
1085 iafterend = qi;
1086 // Iprint2n(mcout, istart, iafterend);
1087 long i;
1088 double b;
1089 mesh.get_scoor(istart, b);
1090 for (i = istart; i < iafterend; i++) {
1091 double a = b;
1092 mesh.get_scoor(i + 1, b);
1093 s += (b - a) * y[i];
1094 }
1095
1096 // T t;
1097 return s;
1098}
1099
1100// total integration of two dimensional array in both dimensions
1101
1102template <class T, class D, class M1, class M2>
1103T t_total_integ_step_ar(const M1& mesh1, const M2& mesh2,
1104 const D& y // array of function values
1105 ) {
1106 mfunname("double t_total_integ_step_ar(...)");
1107
1108 long qi1 = mesh1.get_qi();
1109 check_econd12(qi1, <, 1, mcerr);
1110 long qi2 = mesh2.get_qi();
1111 check_econd12(qi2, <, 1, mcerr);
1112 // if(x1 > x2) return 0;
1113 long istart1, iafterend1; // indexes to sum total intervals
1114 T s1(0);
1115 istart1 = 0;
1116 iafterend1 = qi1;
1117 // Iprint2n(mcout, istart, iafterend);
1118 long i1;
1119 double b1;
1120 mesh1.get_scoor(istart1, b1);
1121 for (i1 = istart1; i1 < iafterend1; i1++) {
1122 double a1 = b1;
1123 mesh1.get_scoor(i1 + 1, b1);
1124 // time to obtain integral by the second dimension
1125 // if(x1 > x2) return 0;
1126 long istart2, iafterend2; // indexes to sum total intervals
1127 T s2(0);
1128 istart2 = 0;
1129 iafterend2 = qi2;
1130 // Iprint2n(mcout, istart, iafterend);
1131 long i2;
1132 double b2;
1133 mesh2.get_scoor(istart2, b2);
1134 for (i2 = istart2; i2 < iafterend2; i2++) {
1135 double a2 = b2;
1136 mesh2.get_scoor(i2 + 1, b2);
1137 s2 += (b2 - a2) * y[i1][i2];
1138 }
1139 // OK, integral = s2
1140 s1 += (b1 - a1) * s2;
1141 }
1142
1143 // T t;
1144 return s1;
1145}
1146
1147// Faster version adapted for DynArr
1148
1149template <class T, class M1, class M2>
1150T t_total_integ_step_ar(const M1& mesh1, const M2& mesh2,
1151 const DynArr<T>& y // array of function values
1152 ) {
1153 mfunname("double t_total_integ_step_ar(...)");
1154
1155 long qi1 = mesh1.get_qi();
1156 check_econd12(qi1, <, 1, mcerr);
1157 check_econd12(qi1, !=, y.get_qel()[0], mcerr);
1158 long qi2 = mesh2.get_qi();
1159 check_econd12(qi2, <, 1, mcerr);
1160 check_econd12(qi2, !=, y.get_qel()[1], mcerr);
1161 // if(x1 > x2) return 0;
1162 long istart1, iafterend1; // indexes to sum total intervals
1163 T s1(0);
1164 istart1 = 0;
1165 iafterend1 = qi1;
1166 // Iprint2n(mcout, istart, iafterend);
1167 long i1;
1168 double b1;
1169 mesh1.get_scoor(istart1, b1);
1170 for (i1 = istart1; i1 < iafterend1; i1++) {
1171 double a1 = b1;
1172 mesh1.get_scoor(i1 + 1, b1);
1173
1174 // time to obtain integral by the second dimension
1175
1176 // if(x1 > x2) return 0.0;
1177 long istart2, iafterend2; // indexes to sum total intervals
1178 T s2(0.0);
1179 istart2 = 0;
1180 iafterend2 = qi2;
1181 // Iprint2n(mcout, istart, iafterend);
1182 long i2;
1183 double b2;
1184 mesh2.get_scoor(istart2, b2);
1185 for (i2 = istart2; i2 < iafterend2; i2++) {
1186 double a2 = b2;
1187 mesh2.get_scoor(i2 + 1, b2);
1188 s2 += (b2 - a2) * y.acu(i1, i2);
1189 }
1190
1191 // OK, integral = s2
1192
1193 s1 += (b1 - a1) * s2;
1194 }
1195
1196 // T t;
1197 return s1;
1198}
1199*/
1200
1201/* Finds value x, such that the integral of y (rectangular bins)
1202is equal to integ.
1203*/
1204// This program is not fast enough for
1205// serial random number generation.
1206// For the last purpose it is more smart to integrate the array
1207// once. This program integrates it each time.
1208/*
1209template <class T, class D, class M>
1210T t_find_x_for_integ_step_ar(const M& mesh,
1211 const D& y, // array of function values
1212 T integ, int* s_err) // for power = 0 only
1213{
1214 mfunname("double t_integ_step_ar(...)");
1215
1216 *s_err = 0;
1217 // check_econd11(xpower , != 0 , mcerr);
1218 check_econd11(integ, < 0.0, mcerr);
1219 long qi = mesh.get_qi();
1220 check_econd12(qi, <, 1, mcerr);
1221 // if(x1 > x2) return 0.0;
1222 double xmin = mesh.get_xmin();
1223 double xmax = mesh.get_xmax();
1224 if (integ == 0.0) return xmin;
1225 T s(0.0);
1226 long n = 0;
1227 T xp1(0.0);
1228 T xp2(0.0);
1229 mesh.get_scoor(n, xp2);
1230 for (n = 0; n < qi; n++) {
1231 xp1 = xp2;
1232 mesh.get_scoor(n + 1, xp2);
1233 T step = xp2 - xp1;
1234 T s1 = s + y[n] * step;
1235 // Iprint3n(mcout, n, s1, integ);
1236 if (s1 > integ) break;
1237 if (s1 == integ) return xp2;
1238 s = s1;
1239 }
1240
1241 if (n == qi) {
1242 *s_err = 1;
1243 return xmax;
1244 }
1245 double x = xp1;
1246 // Iprint3n(mcout, n, s, x);
1247 x += (integ - s) / y[n];
1248 // Iprintn(mcout, x);
1249 return x;
1250}
1251*/
1252// The following program the same as previous, but
1253// considers the array already integrated.
1254// The algorithm is then much faster, since it uses binary search.
1255// It is used, in particular, for random numbers generation.
1256
1257template <class T, class D, class M>
1259 const D& y, // array of function values
1260 T integ, int* s_err) // for power = 0 only
1261{
1262 mfunname("double t_find_x_for_already_integ_step_ar(...)");
1263
1264 *s_err = 0;
1265 // check_econd11(xpower , != 0 , mcerr);
1266 check_econd11(integ, < 0.0, mcerr);
1267 long qi = mesh.get_qi();
1268 check_econd12(qi, <, 1, mcerr);
1269 // if(x1 > x2) return 0.0;
1270 double xmin = mesh.get_xmin();
1271 double xmax = mesh.get_xmax();
1272 if (integ == 0.0) return xmin;
1273 if (integ > y[qi - 1]) {
1274 *s_err = 1;
1275 return xmax;
1276 }
1277 if (integ == y[qi - 1]) return xmax;
1278 if (integ < y[0]) { // answer in the first bin
1279 T xp1(0.0);
1280 T xp2(0.0);
1281 mesh.get_scoor(0, xp1);
1282 mesh.get_scoor(1, xp2);
1283 return xp1 + (xp2 - xp1) * integ / y[0];
1284 }
1285 // binary search
1286 long nl = 0;
1287 long nr = qi - 1;
1288 long nc;
1289 while (nr - nl > 1) {
1290 nc = (nr + nl) / 2;
1291 if (integ < y[nc])
1292 nr = nc;
1293 else
1294 nl = nc;
1295 }
1296 // Iprint2n(mcout, nl, nr);
1297 T xl(0.0);
1298 T xr(0.0);
1299 mesh.get_scoor(nl + 1, xl);
1300 mesh.get_scoor(nr + 1, xr);
1301 // Note "+1" in the previous two expressions.
1302 // This arises from the fact that the nl'th element of
1303 // y-array contains integral of nl'th bin plus all previous bins.
1304 // So y[nl] is related to x of nl+1.
1305 T a = (xr - xl) / (y[nr] - y[nl]);
1306 T ret = xl + a * (integ - y[nl]);
1307
1308 return ret;
1309}
1310
1311// The same as previous, but return entire number, faster.
1312// Mesh should be entire too.
1313// In the contrary to the previous function
1314// y is interpreted here as y[i] is sum from 0 to y[i].
1315// Not to y[i+1], as for smooth case.
1316// But "+1" is persisting anyway.
1317// For example, if gamma is between the first (n=0) and second (n=1)
1318// bins by prob.density, then the solution is the second bin (n=1),
1319// not the first as one could think naively!
1320
1321template <class T, class D, class M>
1323 const M& mesh, const D& y, // array of function values
1324 T integ, int* s_err) // for power = 0 only
1325{
1326 mfunname("double t_find_entire_x_for_already_integ_step_ar(...)");
1327 // Iprintn(mcout, mesh);
1328 // Iprintn(mcout, integ);
1329 *s_err = 0;
1330 // check_econd11(xpower , != 0 , mcerr);
1331 check_econd11(integ, < 0.0, mcerr);
1332 long qi = mesh.get_qi();
1333 check_econd12(qi, <, 1, mcerr);
1334 // if(x1 > x2) return 0.0;
1335 long xmin = mesh.get_xmin();
1336 long xmax = mesh.get_xmax();
1337 if (integ == 0) return xmin;
1338 if (integ > y[qi - 1]) {
1339 *s_err = 1;
1340 return xmax;
1341 }
1342 if (integ == y[qi - 1]) return xmax;
1343 if (integ < y[0]) { // answer in the first bin
1344 long xp1(0);
1345 mesh.get_scoor(0, xp1);
1346 return xp1;
1347 }
1348 // binary search
1349 long nl = 0;
1350 long nr = qi - 1;
1351 long nc;
1352 while (nr - nl > 1) {
1353 nc = (nr + nl) / 2;
1354 if (integ < y[nc])
1355 nr = nc;
1356 else
1357 nl = nc;
1358 }
1359 // Iprint2n(mcout, nl, nr);
1360 // Iprint2n(mcout, y[nl], y[nr]);
1361 // Iprint2n(mcout, nl, nr);
1362 long x(0);
1363 mesh.get_scoor(nr, x);
1364 // Iprintn(mcout, x);
1365
1366 return x;
1367}
1368
1369// prepare histogram for generation of the random numbers
1370// return integral
1371// initialize probability density function
1372// y and integ_y can point to the same array
1373
1374template <class T, class D, class M>
1375T t_hispre_step_ar(const M& mesh, const D& y, // array of function values
1376 D& integ_y // return integrated array
1377 ) {
1378 mfunname("double t_hispre_step_ar(...)");
1379
1380 // check_econd11(xpower , != 0 , mcerr);
1381 long qi = mesh.get_qi();
1382 check_econd12(qi, <, 1, mcerr);
1383
1384 T s(0.0);
1385 long n = 0;
1386 T xp1(0.0);
1387 T xp2(0.0);
1388 mesh.get_scoor(n, xp2);
1389 for (n = 0; n < qi; n++) {
1390 xp1 = xp2;
1391 mesh.get_scoor(n + 1, xp2);
1392 T step = xp2 - xp1;
1393 check_econd11a(y[n], < 0.0,
1394 "n=" << n << " xp1=" << xp1 << " xp2=" << xp2 << '\n',
1395 mcerr);
1396 s = s + y[n] * step;
1397 integ_y[n] = s;
1398 // Iprint3n(mcout, n, s1, integ);
1399 }
1400 // TODO!! (HS)
1401 // check_econd11a(s, <= 0.0, "y=" << y << " integ_y=" << integ_y << '\n',
1402 // mcerr);
1403 for (n = 0; n < qi; n++) {
1404 integ_y[n] /= s;
1405 }
1406 return s;
1407}
1408
1409// generate random number
1410
1411template <class T, class D, class M>
1412T t_hisran_step_ar(const M& mesh, const D& integ_y, T rannum) {
1413 mfunname("double t_hisran_step_ar(...)");
1414 // check_econd11(xpower , != 0 , mcerr);
1415 long qi = mesh.get_qi();
1416 long s_same = apeq_mant(integ_y[qi - 1], 1.0, 1.0e-12);
1417 check_econd11a(s_same, != 1.0, "integ_y[qi-1]=" << integ_y[qi - 1] << '\n',
1418 mcerr);
1419
1420 // Iprintn(mcout, rannum);
1421 // check_econd11(integ_y[qi-1] , != 1.0 , mcerr);
1422 int s_err;
1423
1424 T ret = t_find_x_for_already_integ_step_ar(mesh, // dimension q
1425 integ_y, // dimension q-1
1426 rannum, &s_err);
1427 // TODO (HS)!!
1428 // check_econd11a(s_err, != 0, "mesh=" << mesh << " integ_y=" << integ_y
1429 // << " rannum=" << rannum << '\n',
1430 // mcerr);
1431 return ret;
1432 // return t_find_x_for_already_integ_step_ar
1433 // (mesh, // dimension q
1434 // integ_y, // dimension q-1
1435 // rannum,
1436 // &s_err);
1437}
1438
1439// opposite to generate random number: find integral probability
1440// for a certain absciss
1441
1442template <class T, class D, class M>
1443T t_opposite_hisran_step_ar(const M& mesh, const D& integ_y, T x) {
1444 mfunname("double t_opposite_hisran_step_ar(...)");
1445
1446 // check_econd11(xpower , != 0 , mcerr);
1447 long qi = mesh.get_qi();
1448 long s_same = apeq_mant(integ_y[qi - 1], 1.0, 1.0e-12);
1449 check_econd11a(s_same, != 1.0, "integ_y[qi-1]=" << integ_y[qi - 1] << '\n',
1450 mcerr);
1451
1452 long n1;
1453 T b1;
1454 long n2;
1455 T b2;
1456
1457 mesh.get_interval_extrap(x, n1, b1, n2, b2);
1458 T y1;
1459 T y2;
1460 if (n1 == 0) {
1461 y1 = 0.0;
1462 y2 = integ_y[0];
1463 } else {
1464 y1 = integ_y[n1 - 1];
1465 y2 = integ_y[n2 - 1];
1466 }
1467 T res = y1 + ((y2 - y1) / (b2 - b1)) * (x - b1);
1468 return res;
1469}
1470
1471// generate entire random number
1472
1473template <class T, class D, class M>
1474long t_entire_hisran_step_ar(const M& mesh, const D& integ_y, T rannum) {
1475 mfunname("double t_entire_hisran_step_ar(...)");
1476
1477 // check_econd11(xpower , != 0 , mcerr);
1478 long qi = mesh.get_qi();
1479 long s_same = apeq_mant(integ_y[qi - 1], 1.0, 1.0e-12);
1480 check_econd11a(s_same, != 1.0, "integ_y[qi-1]=" << integ_y[qi - 1] << '\n',
1481 mcerr);
1482 // check_econd11(integ_y[qi-1] , != 1.0 , mcerr);
1483 int s_err;
1484
1485 long ret =
1487 integ_y, // dimension q-1
1488 rannum, &s_err);
1489 check_econd11a(s_err, != 0, "mesh=" << mesh << " integ_y=" << integ_y
1490 << " rannum=" << rannum << '\n',
1491 mcerr);
1492 return ret;
1493 // return t_find_entire_x_for_already_integ_step_ar
1494 // (mesh, // dimension q
1495 // integ_y, // dimension q-1
1496 // rannum,
1497 // &s_err);
1498}
1499
1500/*
1501This is mean of "step array".
1502*/
1503template <class T, class D, class M>
1504T t_mean_step_ar(const M& mesh, const D& y, // array of function values
1505 T x1, T x2, int& s_err) {
1506 mfunname("double t_mean_step_ar(...)");
1507 s_err = 0;
1508 T integ = t_integ_step_ar(mesh, y, x1, x2, 0);
1509 if (integ == 0) {
1510 s_err = 1;
1511 return 0.0;
1512 }
1513 T xinteg = t_integ_step_ar(mesh, y, x1, x2, 1);
1514 return xinteg / integ;
1515}
1516
1517template <class T>
1518T t_value_straight_2point(T x1, T y1, T x2, T y2, T x, int s_ban_neg) {
1519 mfunname("double t_value_straight_2point(...)");
1520 check_econd12(x1, ==, x2, mcerr);
1521
1522 T a = (y2 - y1) / (x2 - x1);
1523 // Less numerical precision
1524 // T b = y[n1];
1525 // T res = a * ( x - x1) + b;
1526 // More numerical precision (although it is not proved),
1527 // starting from what is closer to x
1528 T res;
1529 T dx1 = x - x1;
1530 T adx1 = (dx1 > 0) ? dx1 : -dx1; // absolute value
1531 // if(dx1 > 0)
1532 // adx1 = dx1;
1533 // else
1534 // adx1 = -dx1;
1535 T dx2 = x - x2;
1536 T adx2 = (dx2 > 0) ? dx2 : -dx2; // absolute value
1537 // if(dx2 > 0)
1538 // adx2 = dx2;
1539 // else
1540 // adx2 = -dx2;
1541 if (adx1 < adx2) // x is closer to x1
1542 {
1543 res = a * dx1 + y1;
1544 } else {
1545 res = a * dx2 + y2;
1546 }
1547 if (s_ban_neg == 1 && res < 0.0) res = 0.0;
1548 return res;
1549}
1550
1551template <class T>
1552T t_integ_straight_2point(T x1, T y1, T x2, T y2, T xl, T xr,
1553 int xpower, // currently 0 or 1
1554 int s_ban_neg)
1555 // 0 - not include, 1 - include
1556{
1557 mfunname("double t_integ_straight_2point(...)");
1558 check_econd12(x1, ==, x2, mcerr);
1559
1560 T a = (y2 - y1) / (x2 - x1);
1561 T b = y1;
1562 T yl = a * (xl - x1) + b;
1563 T yr = a * (xr - x1) + b;
1564 if (s_ban_neg == 1) {
1565 if (yl <= 0.0 && yr <= 0.0) return 0.0;
1566 if (yl < 0.0 || yr < 0.0) {
1567 T xz = x1 - b / a;
1568 if (yl < 0.0) {
1569 xl = xz;
1570 yl = 0.0;
1571 } else {
1572 xr = xz;
1573 yr = 0.0;
1574 }
1575 }
1576 }
1577 T res;
1578 if (xpower == 0)
1579 res = 0.5 * a * (xr * xr - xl * xl) + (b - a * x1) * (xr - xl);
1580 else
1581 res = a * (xr * xr * xr - xl * xl * xl) / 3.0 +
1582 0.5 * (b - a * x1) * (xr * xr - xl * xl);
1583
1584 return res;
1585}
1586
1587// Extract value defined by this array for abscissa x
1588// y have dimension q or qi+1.
1589template <class T, class D, class M>
1591 const D& y, // array of function values
1592 T x, int s_ban_neg, int s_extrap_left, T left_bond,
1593 int s_extrap_right, T right_bond) {
1594 // 0 - not include, 1 - include
1595 mfunname("double t_value_straight_point_ar(...)");
1596 double xmin = mesh.get_xmin();
1597 double xmax = mesh.get_xmax();
1598 // Iprint3n(mcout, x, xmin, xmax);
1599 if (x < left_bond) return 0.0;
1600 if (x > right_bond) return 0.0;
1601 if (x < xmin && s_extrap_left == 0) return 0.0;
1602 if (x > xmax && s_extrap_right == 0) return 0.0;
1603 long n1, n2;
1604 T b1, b2;
1605 mesh.get_interval_extrap(x, n1, b1, n2, b2);
1606 T x1;
1607 mesh.get_scoor(n1, x1);
1608 T x2;
1609 mesh.get_scoor(n2, x2);
1610 return t_value_straight_2point(x1, y[n1], x2, y[n2], x, s_ban_neg);
1611}
1612
1613// Extract value defined by this array for abscissa x
1614template <class T, class D, class M>
1616 const M& mesh, const D& y, // array of function values
1617 T (*funval)(T xp1, T yp1, T xp2, T yp2, T xmin,
1618 T xmax, // may be necessary for shape determination
1619 T x),
1620 T x, int s_extrap_left, T left_bond, int s_extrap_right, T right_bond) {
1621 // 0 - not include, 1 - include
1622 mfunname("double t_value_generic_point_ar(...)");
1623 double xmin = mesh.get_xmin();
1624 double xmax = mesh.get_xmax();
1625 // Iprint3n(mcout, x, xmin, xmax);
1626 if (x < left_bond) return 0.0;
1627 if (x > right_bond) return 0.0;
1628 if (x < xmin && s_extrap_left == 0) return 0.0;
1629 if (x > xmax && s_extrap_right == 0) return 0.0;
1630 long n1, n2;
1631 T b1, b2;
1632 mesh.get_interval_extrap(x, n1, b1, n2, b2);
1633 T x1;
1634 mesh.get_scoor(n1, x1);
1635 T x2;
1636 mesh.get_scoor(n2, x2);
1637 return funval(x1, y[n1], x2, y[n2], left_bond, right_bond, x);
1638}
1639
1640// power function x^pw
1641
1642// not debugged
1643// No, perhaps already checked in some application.
1644// If power function cannot be drawn, it exits.
1645
1646template <class T>
1647T t_value_power_2point(T x1, T y1, T x2, T y2, T x) {
1648 mfunname("double t_value_power_2point(...)");
1649
1650 check_econd11(y1, <= 0.0, mcerr);
1651 check_econd11(y2, <= 0.0, mcerr);
1652 check_econd12(y1, ==, y2, mcerr);
1653 check_econd12(x1, ==, x2, mcerr);
1654 T res = y1;
1655 if (x1 <= 0.0 && x2 >= 0.0) {
1656 mcerr << "T t_value_power_2point(...): \n";
1657 mcerr << "x's are of different sign, power cannot be drawn\n";
1658 spexit(mcerr);
1659 } else {
1660 T pw = log(y1 / y2) / log(x1 / x2);
1661 // check_econd11(pw , == -1.0 , mcerr);
1662 res = y1 * pow(x, pw) / pow(x1, pw);
1663 }
1664 return res;
1665}
1666/*
1667// in the case of zero of different signs of x it uses linear interpolation
1668template <class T>
1669T t_value_power_extended_2point(T x1, T y1, T x2, T y2, T x) {
1670 mfunname("double t_value_power_2point(...)");
1671
1672 check_econd11(y1, <= 0.0, mcerr);
1673 check_econd11(y2, <= 0.0, mcerr);
1674 check_econd12(y1, ==, y2, mcerr);
1675 check_econd12(x1, ==, x2, mcerr);
1676 T res;
1677 if (x1 <= 0.0 && x2 >= 0.0) {
1678 res = y1 + (x - x1) * (y2 - y1) / (x2 - x1);
1679 } else {
1680 T pw = log(y1 / y2) / log(x1 / x2);
1681 // check_econd11(pw , == -1.0 , mcerr);
1682 res = y1 * pow(x, pw) / pow(x1, pw);
1683 }
1684 return res;
1685}
1686*/
1687
1688template <class T>
1689T t_value_exp_2point(T x1, T y1, T x2, T y2, T x) {
1690 mfunname("double t_value_exp_2point(...)");
1691
1692 check_econd11(y1, <= 0.0, mcerr);
1693 check_econd11(y2, <= 0.0, mcerr);
1694 check_econd12(y1, ==, y2, mcerr);
1695 check_econd12(x1, ==, x2, mcerr);
1696 T res;
1697
1698 T a = log(y1 / y2) / (x1 - x2);
1699 T c = y1 / exp(a * x1);
1700 // check_econd11(pw , == -1.0 , mcerr);
1701 res = c * exp(a * x);
1702 ;
1703 return res;
1704}
1705
1706template <class T>
1707T t_integ_power_2point(T x1, T y1, T x2, T y2, T xl, T xr)
1708 // 0 - not include, 1 - include
1709{
1710 mfunname("double t_integ_power_2point(...)");
1711
1712 check_econd11(y1, <= 0.0, mcerr);
1713 check_econd11(y2, <= 0.0, mcerr);
1714 check_econd12(y1, ==, y2, mcerr);
1715 check_econd12(x1, ==, x2, mcerr);
1716 T pw = log(y1 / y2) / log(x1 / x2);
1717 check_econd11(pw, == -1.0, mcerr);
1718 T k = y1 * pow(x1, -pw);
1719 T t = k / (1 + pw) * (pow(xr, (pw + 1)) - pow(xl, (pw + 1)));
1720 return t;
1721}
1722
1723template <class T, class D, class M>
1725 const D& y, // array of function values
1726 T x1, T x2, // intervals of integration
1727 int xpower, // currently 0 or 1
1728 int s_ban_neg, int s_extrap_left, T left_bond,
1729 int s_extrap_right, T right_bond) {
1730 mfunname("double t_integ_straight_point_ar(...)");
1731
1732 // mcout<<"Strart t_integ_straight_point_ar\n";
1733 check_econd21(xpower, != 0 &&, != 1, mcerr);
1734 check_econd12(x1, >, x2, mcerr);
1735 long qi = mesh.get_qi();
1736 check_econd12(qi, <, 1, mcerr);
1737 // if(x1 > x2) return 0.0;
1738 double xmin = mesh.get_xmin();
1739 double xmax = mesh.get_xmax();
1740 if (x2 <= xmin && s_extrap_left == 0) return 0.0;
1741 if (x1 >= xmax && s_extrap_right == 0) return 0.0;
1742 if (x2 <= left_bond) return 0.0;
1743 if (x1 >= right_bond) return 0.0;
1744 T s(0.0);
1745 if (x1 < left_bond) x1 = left_bond;
1746 if (x2 > right_bond) x2 = right_bond;
1747 if (x1 <= xmin && s_extrap_left == 0) x1 = xmin;
1748 if (x2 > xmax && s_extrap_left == 0) x2 = xmax;
1749 long np1, np2;
1750 T bp1, bp2;
1751 int i_ret = 0;
1752 // restore the interval in which x1 reside
1753 i_ret = mesh.get_interval_extrap(x1, np1, bp1, np2, bp2);
1754 // restore the x-coordinates of given points
1755 T xp1;
1756 mesh.get_scoor(np1, xp1);
1757 T xp2;
1758 mesh.get_scoor(np2, xp2);
1759 T res;
1760 T yp1 = y[np1];
1761 T yp2 = y[np2];
1762 if (i_ret == 2 || x2 <= xp2) // then all in one interval
1763 {
1764 res = t_integ_straight_2point<T>(xp1, yp1, xp2, yp2, x1, x2, xpower,
1765 s_ban_neg);
1766 } else {
1767 // integrate only till end of the current interval
1768 T x1i = x1;
1769 T x2i = xp2;
1770 res = t_integ_straight_2point<T>(xp1, yp1, xp2, yp2, x1i, x2i, xpower,
1771 s_ban_neg);
1772 // x2i = x1; // prepere for loop
1773 int s_stop = 0;
1774 do {
1775 np1 = np2;
1776 np2++;
1777 xp1 = xp2;
1778 mesh.get_scoor(np2, xp2);
1779 x1i = x2i;
1780 if (xp2 >= x2) {
1781 x2i = x2; // till end of integral
1782 s_stop = 1;
1783 } else {
1784 if (np2 == qi) // end of the mesh, but x2 is farther
1785 {
1786 x2i = x2; // till end of integral
1787 s_stop = 1;
1788 } else {
1789 x2i = xp2; // till end of current interval
1790 s_stop = 0;
1791 }
1792 }
1793 yp1 = yp2;
1794 yp2 = y[np2];
1795 res += t_integ_straight_2point<T>(xp1, yp1, xp2, yp2, x1i, x2i, xpower,
1796 s_ban_neg);
1797 // Iprint2n(mcout, xp1, xp2);
1798 // Iprint2n(mcout, x1i, x2i);
1799 // Iprint2n(mcout, yp1, yp2);
1800 // Iprint2n(mcout, res, s_stop);
1801
1802 } while (s_stop == 0);
1803 }
1804 return res;
1805}
1806
1807template <class T, class D, class M>
1809 const D& y, // array of function values
1810 T x1, T x2, int s_extrap_left, T left_bond,
1811 int s_extrap_right, T right_bond, int& s_err) {
1812 mfunname("double t_mean_straight_point_ar(...)");
1813 s_err = 0;
1814 T integ = t_integ_straight_point_ar(mesh, y, x1, x2, 0, 1, s_extrap_left,
1815 left_bond, s_extrap_right, right_bond);
1816 if (integ == 0) {
1817 s_err = 1;
1818 return 0.0;
1819 }
1820 T xinteg = t_integ_straight_point_ar(mesh, y, x1, x2, 1, 1, s_extrap_left,
1821 left_bond, s_extrap_right, right_bond);
1822 return xinteg / integ;
1823}
1824
1825// template<class T>
1826// typedef T(*GENERICFUN)(T xp1, T yp1, T xp2, T yp2,
1827// T xmin, T xmax, T x1, T x2);
1828// typedef T(*GENERICFUN)(T, T, T, T,
1829// T, T, T, T);
1830
1831template <class T, class D, class M>
1833 const M& mesh, const D& y, // array of function values
1834 // GENERICFUN fun,
1835 T (*fun)(T xp1, T yp1, T xp2, T yp2, T xmin, T xmax, T x1, T x2), T x1,
1836 T x2, int s_extrap_left, T left_bond, int s_extrap_right, T right_bond) {
1837 mfunname("double t_integ_generic_point_ar(...)");
1838
1839 // mcout<<"Strart t_integ_straight_point_ar\n";
1840 // check_econd21(xpower , != 0 && , != 1 , mcerr);
1841 check_econd12(x1, >, x2, mcerr);
1842 long qi = mesh.get_qi();
1843 check_econd12(qi, <, 1, mcerr);
1844 // if(x1 > x2) return 0.0;
1845 double xmin = mesh.get_xmin();
1846 double xmax = mesh.get_xmax();
1847 if (x2 <= xmin && s_extrap_left == 0) return 0.0;
1848 if (x1 >= xmax && s_extrap_right == 0) return 0.0;
1849 if (x2 <= left_bond) return 0.0;
1850 if (x1 >= right_bond) return 0.0;
1851 // long istart, iafterend; // indexes to sum total intervals
1852 if (x1 < left_bond) x1 = left_bond;
1853 if (x2 > right_bond) x2 = right_bond;
1854 if (x1 <= xmin && s_extrap_left == 0) x1 = xmin;
1855 if (x2 > xmax && s_extrap_left == 0) x2 = xmax;
1856 long np1, np2;
1857 T bp1, bp2;
1858 int i_ret = 0;
1859 // restore the interval in which x1 reside
1860 i_ret = mesh.get_interval_extrap(x1, np1, bp1, np2, bp2);
1861 // restore the x-coordinates of given points
1862 T xp1;
1863 mesh.get_scoor(np1, xp1);
1864 T xp2;
1865 mesh.get_scoor(np2, xp2);
1866 T res;
1867 T yp1 = y[np1];
1868 T yp2 = y[np2];
1869 if (i_ret == 2 || x2 <= xp2) // then all in one interval
1870 {
1871 res = fun(xp1, yp1, xp2, yp2, xmin, xmax, x1, x2);
1872 } else {
1873 // integrate only till end of the current interval
1874 T x1i = x1;
1875 T x2i = xp2;
1876 res = fun(xp1, yp1, xp2, yp2, xmin, xmax, x1i, x2i);
1877 // x2i = x1; // prepere for loop
1878 int s_stop = 0;
1879 do {
1880 np1 = np2;
1881 np2++;
1882 xp1 = xp2;
1883 mesh.get_scoor(np2, xp2);
1884 x1i = x2i;
1885 if (xp2 >= x2) {
1886 x2i = x2; // till end of integral
1887 s_stop = 1;
1888 } else {
1889 if (np2 == qi) // end of the mesh, but x2 is farther
1890 {
1891 x2i = x2; // till end of integral
1892 s_stop = 1;
1893 } else {
1894 x2i = xp2; // till end of current interval
1895 s_stop = 0;
1896 }
1897 }
1898 yp1 = yp2;
1899 yp2 = y[np2];
1900 res += fun(xp1, yp1, xp2, yp2, xmin, xmax, x1i, x2i);
1901 // Iprint2n(mcout, xp1, xp2);
1902 // Iprint2n(mcout, x1i, x2i);
1903 // Iprint2n(mcout, yp1, yp2);
1904 // Iprint2n(mcout, res, s_stop);
1905
1906 } while (s_stop == 0);
1907 }
1908 return res;
1909}
1910
1911// find width at half-height of a histogram
1912// doing straight line interpolation between centers of the bins
1913//(like straight_point_ar).
1914// But the mesh is understood as a range of the left points.
1915// if there are several maximal bin with the same height
1916// it will decline from the first one, which might be
1917// not accurate, although the result is anyway reasonable.
1918/*
1919template <class T, class D, class M>
1920T t_width_at_hheight_step_ar(const M& mesh, const D& y) {
1921 // 0 - not include, 1 - include
1922 mfunname("double t_width_at_hheight_step_ar(...)");
1923 // mcout<<"t_width_at_hheight_step_ar is started\n";
1924 long qi = mesh.get_qi();
1925 long n;
1926 T ymax = 0;
1927 long nmax;
1928 for (n = 0; n < qi; ++n) {
1929 if (y[n] > ymax) {
1930 check_econd11(y[n], < 0.0, mcerr);
1931 ymax = y[n];
1932 nmax = n;
1933 }
1934 }
1935 // Iprint2n(mcout, ymax, nmax);
1936 if (ymax == 0) return 0;
1937 T ylev = ymax / 2.0;
1938 T s2 = 0;
1939 long q = 0;
1940 for (n = nmax; n < qi; n++) {
1941
1942 if (y[n] > ylev && y[n + 1] <= ylev) {
1943 T x1, x2;
1944 mesh.get_interval(n, x1, x2);
1945 T step1, step2;
1946 mesh.get_step(n, step1);
1947 mesh.get_step(n + 1, step2);
1948 step1 = step1 / 2.0;
1949 step2 = step2 / 2.0;
1950 s2 += t_value_straight_2point(y[n], x1 + step1, y[n + 1], x2 + step2,
1951 ylev, 0);
1952 // Iprint2n(mcout, x1, x2);
1953 // Iprint2n(mcout, x1+step1, x2+step2);
1954 // Iprint2n(mcout, y[n], y[n+1]);
1955 // Iprint2n(mcout, n, t_value_straight_2point(y[n], x1+step1, y[n+1],
1956 // x2+step2, ylev, 0));
1957 q++;
1958 }
1959 }
1960 check_econd11(q, <= 0, mcerr);
1961 s2 = s2 / q;
1962 T s1 = 0;
1963 q = 0;
1964 for (n = nmax; n >= 0; n--) {
1965 if (y[n] > ylev && y[n - 1] <= ylev) {
1966 T x1, x2;
1967 mesh.get_interval(n - 1, x1, x2);
1968 T step1, step2;
1969 mesh.get_step(n - 1, step1);
1970 mesh.get_step(n, step2);
1971 step1 = step1 / 2.0;
1972 step2 = step2 / 2.0;
1973 s1 += t_value_straight_2point(y[n - 1], x1 + step1, y[n], x2 + step2,
1974 ylev, 0);
1975 // Iprint2n(mcout, x1, x2);
1976 // Iprint2n(mcout, x1+step1, x2+step2);
1977 // Iprint2n(mcout, y[n-1], y[n]);
1978 // Iprint2n(mcout, n, t_value_straight_2point(y[n-1], x1+step1, y[n],
1979 // x2+step2, ylev, 0));
1980 q++;
1981 }
1982 }
1983 check_econd11(q, <= 0, mcerr);
1984 s1 = s1 / q;
1985 // Iprint3n(mcout, s1, s2, s2 - s1);
1986 return s2 - s1;
1987}
1988*/
1989}
1990
1991#endif
#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream)
Definition: FunNameStack.h:191
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:155
#define check_econd11a(a, signb, add, stream)
Definition: FunNameStack.h:172
#define check_econd24(a1, sign1, b1, sign0, a2, sign2, b2, stream)
Definition: FunNameStack.h:211
#define spexit(stream)
Definition: FunNameStack.h:256
#define check_econd12(a, sign, b, stream)
Definition: FunNameStack.h:163
#define mfunname(string)
Definition: FunNameStack.h:45
T get_xmin(void) const
Definition: tline.h:68
void get_scoor(long n, T &b) const
Definition: tline.h:73
void print(std::ostream &file) const
Definition: tline.h:214
T get_xmax(void) const
Definition: tline.h:69
int get_step(long n, T &fstep) const
Definition: tline.h:100
virtual int get_interval_extrap(T x, long &n1, T &b1, long &n2, T &b2) const
Definition: tline.h:176
int get_interval(long n, T &b1, T &b2) const
Get interval. Return 1 if interval is found.
Definition: tline.h:75
long get_qi(void) const
Get number of intervals.
Definition: tline.h:66
T get_xmin(void) const
Definition: tline.h:392
virtual void print(std::ostream &file) const
Definition: tline.h:684
void check(void)
Definition: tline.h:507
int get_interval_extrap(T x, long &n1, T &b1, long &n2, T &b2) const
Definition: tline.h:615
void get_scoor(long n, T &b) const
Definition: tline.h:394
T get_xmax(void) const
Definition: tline.h:393
int get_step(long n, T &fstep) const
Definition: tline.h:419
long get_qi(void) const
Definition: tline.h:391
virtual int get_interval(long n, T &b1, T &b2) const
Definition: tline.h:401
PointCoorMesh(void)
Definition: tline.h:427
std::istream * istrm
Definition: definp.h:34
#define DEFINPAP(name)
Definition: definp.h:78
Definition: BGMesh.cpp:6
T t_opposite_hisran_step_ar(const M &mesh, const D &integ_y, T x)
Definition: tline.h:1443
T t_value_straight_2point(T x1, T y1, T x2, T y2, T x, int s_ban_neg)
Definition: tline.h:1518
T t_integ_power_2point(T x1, T y1, T x2, T y2, T xl, T xr)
Definition: tline.h:1707
T t_value_straight_point_ar(const M &mesh, const D &y, T x, int s_ban_neg, int s_extrap_left, T left_bond, int s_extrap_right, T right_bond)
Definition: tline.h:1590
std::istream & operator>>(std::istream &file, EqualStepCoorMesh< T > &f)
Definition: tline.h:229
std::ostream & noindent(std::ostream &f)
Definition: prstream.cpp:17
int operator!=(manip_absvol_treeid &tid1, manip_absvol_treeid &tid2)
Definition: volume.h:61
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition: BGMesh.cpp:37
long t_find_entire_x_for_already_integ_step_ar(const M &mesh, const D &y, T integ, int *s_err)
Definition: tline.h:1322
DoubleAc pow(const DoubleAc &f, double p)
Definition: DoubleAc.cpp:337
T t_integ_straight_2point(T x1, T y1, T x2, T y2, T xl, T xr, int xpower, int s_ban_neg)
Definition: tline.h:1552
T t_integ_generic_point_ar(const M &mesh, const D &y, T(*fun)(T xp1, T yp1, T xp2, T yp2, T xmin, T xmax, T x1, T x2), T x1, T x2, int s_extrap_left, T left_bond, int s_extrap_right, T right_bond)
Definition: tline.h:1832
T t_find_x_for_already_integ_step_ar(const M &mesh, const D &y, T integ, int *s_err)
Definition: tline.h:1258
long t_entire_hisran_step_ar(const M &mesh, const D &integ_y, T rannum)
Definition: tline.h:1474
T t_hispre_step_ar(const M &mesh, const D &y, D &integ_y)
Definition: tline.h:1375
T t_mean_straight_point_ar(const M &mesh, const D &y, T x1, T x2, int s_extrap_left, T left_bond, int s_extrap_right, T right_bond, int &s_err)
Definition: tline.h:1808
DoubleAc exp(const DoubleAc &f)
Definition: DoubleAc.cpp:377
T t_value_power_2point(T x1, T y1, T x2, T y2, T x)
Definition: tline.h:1647
int operator==(const circumf &f1, const circumf &f2)
Definition: circumf.cpp:34
long set_position(const std::string &word, std::istream &istrm, int s_rewind, int s_req_sep)
Definition: definp.cpp:23
long t_find_interval(double x, long q, const D &coor)
Definition: tline.h:277
T t_hisran_step_ar(const M &mesh, const D &integ_y, T rannum)
Definition: tline.h:1412
T t_mean_step_ar(const M &mesh, const D &y, T x1, T x2, int &s_err)
Definition: tline.h:1504
T t_integ_step_ar(const M &mesh, const D &y, T x1, T x2, int xpower)
Definition: tline.h:905
T t_integ_straight_point_ar(const M &mesh, const D &y, T x1, T x2, int xpower, int s_ban_neg, int s_extrap_left, T left_bond, int s_extrap_right, T right_bond)
Definition: tline.h:1724
int apeq_mant(const T &x1, const T &x2, T prec)
Definition: minmax.h:55
indentation indn
Definition: prstream.cpp:15
T t_integ_generic_step_ar(const M &mesh, const D &y, T(*fun)(long np, T xp1, T xp2, T yp, T xmin, T xmax, T x1, T x2), T x1, T x2)
Definition: tline.h:997
T t_value_exp_2point(T x1, T y1, T x2, T y2, T x)
Definition: tline.h:1689
T t_value_generic_point_ar(const M &mesh, const D &y, T(*funval)(T xp1, T yp1, T xp2, T yp2, T xmin, T xmax, T x), T x, int s_extrap_left, T left_bond, int s_extrap_right, T right_bond)
Definition: tline.h:1615
std::ostream & yesindent(std::ostream &f)
Definition: prstream.cpp:21
long t_find_interval_end(double x, long q, const D &coor, long n_start)
Definition: tline.h:321
#define mcout
Definition: prstream.h:126
#define Iprint3n(file, name1, name2, name3)
Definition: prstream.h:232
#define Ifile
Definition: prstream.h:195
#define mcerr
Definition: prstream.h:128
#define Iprintn(file, name)
Definition: prstream.h:204
#define Iprint2n(file, name1, name2)
Definition: prstream.h:219
#define Iprint4n(file, name1, name2, name3, name4)
Definition: prstream.h:243