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