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