Garfield++ v1r0
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
17
18//#define TLINE_REDUCE_TO_RAW_ARR // useful for acceleration of PointCoorMesh
19// (and also for CopiedPointCoorMesh)
20// if the type D keeps elements in consequtive array
21// whose address can be obtained as address of the first element.
22// In PointCoorMesh this all is switched by the following way:
23//#ifndef TLINE_REDUCE_TO_RAW_ARR
24// D* amesh;
25//#else
26// T* amesh;
27//#endif
28// In constructors the assignment is switched by the following way:
29//#ifndef TLINE_REDUCE_TO_RAW_ARR
30// amesh = famesh;
31// xmin = (*amesh)[0];
32// xmax = (*amesh)[q-1];
33//#else
34// amesh = &((*famesh)[0]);
35// xmin = amesh[0];
36// xmax = amesh[q-1];
37//#endif
38// Note that in both cases only the address is kept in this class and the
39// corresponding object is not copied.
40// If Copying is necessary, one can use CopiedPointCoorMesh.
41// Note that class CopiedPointCoorMesh, based on DynLinArr,
42// also provides acceleration based on the use of raw array
43// address and switched on by TLINE_REDUCE_TO_RAW_ARR.
44// Note that this class does not use .acu() functions of DynLinArr,
45// allowing for the use of unchecked fast access
46// (since these functions were written after tline was done).
47
48//#define CHECK_POINT_MESH //verifies that the points are in increasing order.
49// It is indeed long and may be inacceptable for some applications.
50
51// ---------------------------------------------------------------------
52// The simplest mesh which has equal steps, and
53// determined by the number of "bins", minimum and maximum.
54// The object of this class keeps all ingredients in it.
55// It can be therefore copied and deleted freely.
56// T is the type of returned value.
57// T cannot be const.
58// At construction q has meaning of number of intervals.
59
60template <class T> class EqualStepCoorMesh {
61 public:
62 inline long get_qi(void) const {
63 return q;
64 } // get number of intervals
65 inline T get_xmin(void) const { return xmin; }
66 inline T get_xmax(void) const { return xmax; }
67
68 // get single coordinate
69 // of the point in the mesh. It can be last point of the last interval:
70 inline void get_scoor(long n, T& b) const { b = xmin + n * step; }
71
72 inline int get_interval(long n, T& b1, T& b2) const {
73 if (n < 0 || n >= q) return 0;
74 b1 = xmin + n * step;
75 b2 = b1 + step;
76 return 1;
77 }
78 // return 1 if interval is found
79
80 virtual int get_interval(T x, // is coordinate
81 long& n1) const; // is the bin number
82
83 // The same as above, but returns more information:
84 virtual int get_interval(T x, long& n1,
85 T& b1, // the bin number and left border
86 long& n2, T& b2) // the next bin number and its left
87 const;
88
89 virtual int get_interval_extrap(T x, long& n1, T& b1, long& n2, T& b2) const;
90 // returns 1 if x inside xmin and xmax and therefore b1 and b2,
91 // returns 0 if x < xmin
92 // In this case n1 = 0, n2 = 1, b1 and b2 are corresponding.
93 // returns 2 if x > xmax
94 // In this case n1 = q-1, n2 = q, b1 and b2 are corresponding.
95
96 inline int get_step(long n, T& fstep) const {
97 if (n < 0 || n >= q) return 0;
98 fstep = step;
99 return 1;
100 }
101
102 EqualStepCoorMesh<T>(void) : q(0), xmin(0), xmax(0), step(0) { ; }
103 EqualStepCoorMesh<T>(long fq, T fxmin, T fxmax);
104 void print(std::ostream& file) const;
105
106 private:
107 long q; // the number of steps or intervals;
108 // Attention: if you count the number of points with the
109 // last point of the last step there will be q+1 points.
110 T xmin;
111 T xmax;
112 T step;
113};
114
115template <class T>
117 : q(fq), xmin(fxmin), xmax(fxmax) {
118 mfunname("template<class T> EqualStepCoorMesh<T>::EqualStepCoorMesh<T>(long "
119 "fq, T fxmin, T fxmax)");
120 check_econd11(q, < 0, mcerr);
121 check_econd24(q, ==, 0, &&, xmin, <, xmax, mcerr);
122 check_econd12(xmin, >, xmax, mcerr);
123 /*
124 if(q < 0)
125 {
126 mcerr<<"ERROR in EqualStepCoorMesh<T>::get_interval_extrap:\n"
127 <<"q < 0\n";
128 Iprintn(mcerr, q);
129 spexit(mcerr);
130 }
131 if(q <= 1 && xmin < xmax)
132 {
133 mcerr<<"ERROR in EqualStepCoorMesh<T>::get_interval_extrap:\n"
134 <<"q <= 1 && xmin < xmax\n";
135 Iprintn(mcerr, q);
136 spexit(mcerr);
137 }
138 if(xmin > xmax)
139 {
140 mcerr<<"ERROR in EqualStepCoorMesh<T>::get_interval_extrap:\n"
141 <<"xmin > xmax\n";
142 Iprint2n(mcout, xmin, xmax);
143 spexit(mcerr);
144 }
145 */
146 step = (fxmax - fxmin) / q;
147 check_econd11(step, == 0, mcerr);
148}
149
150template <class T> int EqualStepCoorMesh<T>::get_interval(T x, long& n1) const {
151 if (x < xmin || x >= xmax) {
152 n1 = 0;
153 return 0;
154 }
155 n1 = long((x - xmin) / step);
156 if (n1 < 0) {
157 mcerr << "ERROR in EqualStepCoorMesh<T>::get_interval:\n"
158 << "n1 < 0 \n";
159 //if(n1 < 0 || n1 >= q || n2 < 0 || n2 > q ||
160 // b1 < xmin || b1 > xmax || b2 < xmin || b2 > xmax )
161 //{
162 //mcerr<<"ERROR in EqualStepCoorMesh<T>::get_interval:\n"
163 // <<"n1 < 0 || n1 >= q || n2 < 0 || n2 > q || b1 < xmin || b1 >
164 // xmax || b2 < xmin || b2 > xmax\n";
165 print(mcerr);
166 Iprintn(mcerr, x);
167 Iprintn(mcerr, n1);
168 spexit(mcerr);
169 }
170 return 1;
171}
172
173template <class T>
174int EqualStepCoorMesh<T>::get_interval(T x, long& n1, T& b1, long& n2,
175 T& b2) const {
176 if (x < xmin || x >= xmax) {
177 n1 = 0;
178 n2 = 0;
179 b1 = 0;
180 b2 = 0;
181 return 0;
182 }
183 n1 = long((x - xmin) / step);
184 n2 = n1 + 1;
185 b1 = xmin + step * n1;
186 b2 = b1 + step;
187 if (n1 < 0 || n2 > q || b2 > xmax) {
188 mcerr << "ERROR in EqualStepCoorMesh<T>::get_interval:\n"
189 << "n1 < 0 || n2 > q || b2 > xmax\n";
190 //if(n1 < 0 || n1 >= q || n2 < 0 || n2 > q ||
191 // b1 < xmin || b1 > xmax || b2 < xmin || b2 > xmax )
192 //{
193 //mcerr<<"ERROR in EqualStepCoorMesh<T>::get_interval:\n"
194 // <<"n1 < 0 || n1 >= q || n2 < 0 || n2 > q || b1 < xmin || b1 >
195 // xmax || b2 < xmin || b2 > xmax\n";
196 print(mcerr);
197 Iprintn(mcerr, x);
198 Iprint4n(mcerr, n1, n2, b1, b2);
199 spexit(mcerr);
200 }
201 return 1;
202}
203
204template <class T>
205int EqualStepCoorMesh<T>::get_interval_extrap(T x, long& n1, T& b1, long& n2,
206 T& b2) const {
207 int i_ret = 1;
208
209 if (x < xmin) {
210 i_ret = 0;
211 n1 = 0;
212 n2 = 1;
213 b1 = xmin;
214 b2 = xmin + step;
215 } else if (x >= xmax) {
216 i_ret = 2;
217 n1 = q - 1;
218 n2 = q;
219 b1 = xmax - step;
220 b2 = xmax;
221 } else {
222 n1 = long((x - xmin) / step);
223 n2 = n1 + 1;
224 if (n2 == q) {
225 b2 = xmax;
226 b1 = b2 - step;
227 } else {
228 b1 = xmin + step * n1;
229 b2 = b1 + step;
230 if (n1 < 0 || n2 > q || b2 > xmax) {
231 mcerr << "ERROR in EqualStepCoorMesh<T>::get_interval_extrap:\n"
232 << "n1 < 0 || n2 > q || b2 > xmax\n";
233 //if(n1 < 0 || n1 >= q || n2 < 0 || n2 > q ||
234 // b1 < xmin || b1 > xmax || b2 < xmin || b2 > xmax )
235 //{
236 // mcerr<<"ERROR in EqualStepCoorMesh<T>::get_interval_extrap:\n"
237 // <<"n1 < 0 || n1 >= q || n2 < 0 || n2 > q || b1 < xmin || b1
238 // > xmax || b2 < xmin || b2 > xmax\n";
239 print(mcerr);
240 Iprint4n(mcerr, n1, n2, b1, b2);
241 spexit(mcerr);
242 }
243 }
244 }
245 return i_ret;
246}
247
248template <class T> void EqualStepCoorMesh<T>::print(std::ostream& file) const {
249 Ifile << "EqualStepCoorMesh<T>:\n";
250 indn.n += 2;
251 Ifile << "Type of T is (in internal notations) " << typeid(T).name() << '\n';
252 Iprint4n(file, q, xmin, xmax, step);
253 indn.n -= 2;
254}
255
256template <class T>
257 std::ostream& operator<<(std::ostream& file,
258 const EqualStepCoorMesh<T>& f) {
259 f.print(file);
260 return file;
261}
262
263template <class T>
264 std::istream& operator>>(std::istream& file, EqualStepCoorMesh<T>& f) {
265 mfunname("istream& operator>>(istream& file, EqualStepCoorMesh<T>& f)");
266 definp_endpar dep(&file, 0, 1, 0);
267 set_position("Type of T is (in internal notations)", *dep.istrm, dep.s_rewind,
268 dep.s_req_sep);
269 long q;
270 T xmin;
271 T xmax;
272 DEFINPAP(q);
273 DEFINPAP(xmin);
274 DEFINPAP(xmax);
275 f = EqualStepCoorMesh<T>(q, xmin, xmax);
276 return file;
277}
278
279template <class T>
281 const EqualStepCoorMesh<T>& f2) {
282 if (f1.get_qi() != f2.get_qi() || f1.get_xmin() != f2.get_xmin() ||
283 f1.get_xmax() != f2.get_xmax())
284 return 0;
285 else
286 return 1;
287}
288
289template <class T>
291 T prec) {
292 if (f1.get_qi() != f2.get_qi() ||
293 !apeq_mant(f1.get_xmin(), f2.get_xmin(), prec) ||
294 !apeq_mant(f1.get_xmax(), f2.get_xmax(), prec)) {
295 Iprintn(mcout, !apeq_mant(f1.get_xmin(), f2.get_xmin(), prec));
296 Iprintn(mcout, !apeq_mant(f1.get_xmax(), f2.get_xmax(), prec));
297 return 0;
298 } else
299 return 1;
300}
301
302template <class T>
304 const EqualStepCoorMesh<T>& f2) {
305 if (f1.get_qi() != f2.get_qi() || f1.get_xmin() != f2.get_xmin() ||
306 f1.get_xmax() != f2.get_xmax())
307 return 1;
308 else
309 return 0;
310}
311
312template <class T, class D>
313// D is anything allowing indexing
314 long t_find_interval(double x, long q, const D& coor) {
315 long n1, n2, n3;
316#ifndef TLINE_REDUCE_TO_RAW_ARR
317 if (q <= 1) return -1;
318 if (x < coor[0] || x > coor[q - 1]) return -1;
319 if (x < coor[1]) return 0;
320 if (x >= coor[q - 2]) return q - 2;
321 n1 = 0;
322 n2 = q - 1;
323 while (n2 - n1 > 1) {
324 n3 = n1 + (n2 - n1) / 2;
325 if (x < coor[n3])
326 n2 = n3;
327 else
328 n1 = n3;
329 }
330 return n1;
331#else
332 T* arr = &(coor[0]); // take the address of the first element
333 if (q <= 1) return -1;
334 if (x < arr[0] || x > arr[q - 1]) return -1;
335 if (x < arr[1]) return 0;
336 if (x >= arr[q - 2]) return q - 2;
337 n1 = 0;
338 n2 = q - 1;
339 while (n2 - n1 > 1) {
340 n3 = n1 + (n2 - n1) / 2;
341 if (x < arr[n3])
342 n2 = n3;
343 else
344 n1 = n3;
345 }
346 return n1;
347
348#endif
349}
350
351// Use (scan) only end of the array starting from index n_start
352// as if it is 0
353// The return index:
354// -1 if less than corr[n_start] or more than coor[q-1]
355// Index if inside
356
357template <class T, class D>
358long t_find_interval_end(double x, long q, const D& coor, long n_start) {
359 long n1, n2, n3;
360 if (n_start < 0 || n_start > q - 1) {
361 mcerr << " ERROR in t_find_interval_end(...):\n";
362 mcerr << "n_start < 0 || n_start > q-1\n";
363 Iprint2n(mcout, n_start, q);
364 spexit(mcerr);
365 }
366#ifndef TLINE_REDUCE_TO_RAW_ARR
367 //if(q <= 1) return -1;
368 if (q - n_start <= 1) return -1;
369 if (x < coor[n_start] || x > coor[q - 1]) return -1;
370 if (x < coor[n_start + 1]) return n_start;
371 if (x >= coor[q - 2]) return q - 2;
372 n1 = n_start;
373 n2 = q - 1;
374 while (n2 - n1 > 1) {
375 n3 = n1 + (n2 - n1) / 2;
376 if (x < coor[n3])
377 n2 = n3;
378 else
379 n1 = n3;
380 }
381 return n1;
382#else
383 T* arr = &(coor[0]); // take the address of the first element
384 //if(q <= 1) return -1;
385 if (q - n_start <= 1) return -1;
386 if (x < arr[n_start] || x > arr[q - 1]) return -1;
387 if (x < arr[n_start + 1]) return n_start;
388 if (x >= arr[q - 2]) return q - 2;
389 n1 = n_start;
390 n2 = q - 1;
391 while (n2 - n1 > 1) {
392 n3 = n1 + (n2 - n1) / 2;
393 if (x < arr[n3])
394 n2 = n3;
395 else
396 n1 = n3;
397 }
398 return n1;
399
400#endif
401}
402
403// ---------------------------------------------------------------------
404// The generic mesh which has arbitrary steps.
405// The array determining the step edges is located somewhere outside.
406// In object of this class only the raw pointer is contained with consequences:
407
408/*
409Attention, here there is a raw pointer to mesh.
410It is not possible to use the passive pointer since
411if D is plain array, the reference cannot be registered.
412This is deviation from methodology, but it is not clear what can
413be done here. The mesh cannot be copyed or deleted after the PointCoorMesh
414is initialized. Obviously, the latter should be initialized immidiately
415before the use and not keept permanentely.
416Obviously again, that sooner or later the user can forget about this
417(the author also once almost forgot and was at the edge of error)
418and try to initialize it permanantely and then copy together with the mesh.
419This would be an error, which again confirms the correctness of the
420object management methodology, which forbids to place the raw pointers
421in classes. This class (below) may be understood as a temporary exclusion,
422which should be treated with great care.
423At construction q has meaning of number of points.
424 */
425
426template <class T, class D> class PointCoorMesh {
427 public:
428 inline long get_qi(void) const { return q - 1; }
429 inline T get_xmin(void) const { return xmin; }
430 inline T get_xmax(void) const { return xmax; }
431 inline void get_scoor(long n, T& b) const
432#ifndef TLINE_REDUCE_TO_RAW_ARR
433 {
434 b = (*amesh)[n];
435 }
436#else
437 { b = amesh[n]; }
438#endif
439 virtual int get_interval(long n, T& b1, T& b2) const {
440 if (n < 0 || n >= q - 1) return 0;
441#ifndef TLINE_REDUCE_TO_RAW_ARR
442 b1 = (*amesh)[n];
443 b2 = (*amesh)[n + 1];
444#else
445 b1 = amesh[n];
446 b2 = amesh[n + 1];
447#endif
448 return 1;
449 }
450
451 int get_interval(T x, long& n1) const;
452
453 int get_interval(T x, long& n1, T& b1, long& n2, T& b2) const;
454
455 int get_interval_extrap(T x, long& n1, T& b1, long& n2, T& b2) const;
456
457 inline int get_step(long n, T& fstep) const {
458 if (n < 0 || n >= q - 1) return 0;
459 T b1, b2;
460 get_interval(n, b1, b2);
461 fstep = b2 - b1;
462 return 1;
463 }
464
466 : q(0), xmin(0), xmax(0), x_old(0), n_old(-1), amesh(NULL) {
467 ;
468 }
469 PointCoorMesh<T, D>(long fq, // number of points, number of intervals
470 // is fq - 1.
471 D* famesh); // dimension is fq and the last index is fq-1
472 // This is the end point of the last interval
473 virtual ~PointCoorMesh<T, D>() {}
474 void check(void); // check that the points are sequencial.
475 // This is also done in constructor above provided that
476 // macro CHECK_POINT_MESH is initialized.
477
478 virtual void print(std::ostream& file) const;
479
480 private:
481 long q; // the number of points
482 // The number of intervals is q-1.
483 // Therefore q has to be 2 or more
484#ifndef TLINE_REDUCE_TO_RAW_ARR
485 //PassivePtr< D > amesh;
486 D* amesh;
487#else
488 T* amesh;
489#endif
490 T xmin;
491 T xmax;
492 // auxiliary thing to accelerate finding intervals
493 mutable T x_old; // previous x for finding interval
494 mutable long n_old; // -1 if there is nothing
495};
496
497template <class T, class D>
499 : q(fq), x_old(0), n_old(-1) {
500 if (q <= 1) {
501 mcerr << "ERROR in PointCoorMesh<T,D>::PointCoorMesh<T,D>:\n"
502 << "q <= 1\n";
503 Iprintn(mcerr, q);
504 spexit(mcerr);
505 }
506#ifndef TLINE_REDUCE_TO_RAW_ARR
507 //amesh.put( famesh );
508 amesh = famesh;
509 xmin = (*amesh)[0];
510 xmax = (*amesh)[q - 1];
511#else
512 amesh = &((*famesh)[0]);
513 xmin = amesh[0];
514 xmax = amesh[q - 1];
515#endif
516 // check consistence
517 if (xmin > xmax) {
518 mcerr << "ERROR in PointCoorMesh<T,D>::PointCoorMesh<T,D>:\n"
519 << "xmin > xmax\n";
520 Iprint2n(mcerr, xmin, xmax);
521 spexit(mcerr);
522 }
523#ifdef CHECK_POINT_MESH
524 long n;
525 for (n = 0; n < q - 1; n++) {
526#ifndef TLINE_REDUCE_TO_RAW_ARR
527 if ((*amesh)[n] >= (*amesh)[n + 1])
528#else
529 if (amesh[n] >= amesh[n + 1])
530#endif
531 {
532 mcerr << "ERROR in PointCoorMesh<T,D>::PointCoorMesh<T,D>:\n"
533 << "amesh[n] >= amesh[n+1]\n";
534#ifndef TLINE_REDUCE_TO_RAW_ARR
535 Iprint3n(mcerr, n, (*amesh)[n], (*amesh)[n + 1]);
536#else
537 Iprint3n(mcerr, n, amesh[n], amesh[n + 1]);
538#endif
539 spexit(mcerr);
540 }
541 }
542#endif
543
544}
545
546template <class T, class D> void PointCoorMesh<T, D>::check(void) {
547 long n;
548 for (n = 0; n < q - 1; n++) {
549#ifndef TLINE_REDUCE_TO_RAW_ARR
550 if ((*amesh)[n] >= (*amesh)[n + 1])
551#else
552 if (amesh[n] >= amesh[n + 1])
553#endif
554 {
555 mcerr << "ERROR in PointCoorMesh<T,D>::check(void):\n"
556 << "amesh[n] >= amesh[n+1]\n";
557#ifndef TLINE_REDUCE_TO_RAW_ARR
558 Iprint3n(mcerr, n, (*amesh)[n], (*amesh)[n + 1]);
559#else
560 Iprint3n(mcerr, n, amesh[n], amesh[n + 1]);
561#endif
562 spexit(mcerr);
563 }
564 }
565
566}
567
568template <class T, class D>
569int PointCoorMesh<T, D>::get_interval(T x, long& n1) const {
570 if (x < xmin || x >= xmax) {
571 n1 = 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
590 if (n1 < 0) {
591 mcerr << "ERROR in PointCoorMesh<T,D>::get_interval:\n"
592 << "n1 < 0\n";
593 print(mcerr);
594 Iprintn(mcerr, n1);
595 spexit(mcerr);
596 }
597 n_old = n1;
598 x_old = x;
599 return 1;
600}
601
602template <class T, class D>
603int PointCoorMesh<T, D>::get_interval(T x, long& n1, T& b1, long& n2,
604 T& b2) const {
605 if (x < xmin || x >= xmax) {
606 n1 = 0;
607 n2 = 0;
608 b1 = 0;
609 b2 = 0;
610 return 0;
611 }
612#ifndef TLINE_REDUCE_TO_RAW_ARR
613 if (n_old >= 0 && x_old <= x) {
614 n1 = t_find_interval_end<T, D>(x, q, *amesh, n_old);
615 } else {
616 n1 = t_find_interval<T, D>(x, q, *amesh);
617 }
618//n1 = t_find_interval< T , D >(x, q, amesh);
619#else
620 if (n_old >= 0 && x_old <= x) {
621 n1 = t_find_interval_end<T, T*>(x, q, amesh, n_old);
622 } else {
623 n1 = t_find_interval<T, T*>(x, q, amesh);
624 }
625//n1 = t_find_interval< T , T* >(x, q, &amesh);
626#endif
627 n2 = n1 + 1;
628#ifndef TLINE_REDUCE_TO_RAW_ARR
629 b1 = (*amesh)[n1];
630 b2 = (*amesh)[n2];
631#else
632 b1 = amesh[n1];
633 b2 = amesh[n2];
634#endif
635 if (n1 < 0 || n1 >= q || n2 < 0 || n2 >= q || b1 < xmin || b1 > xmax ||
636 b2 < xmin || b2 > xmax) {
637 mcerr << "ERROR in PointCoorMesh<T,D>::get_interval:\n"
638 << "n1 < 0 || n1 >= q || n2 < 0 || n2 >= q || b1 < xmin || b1 > xmax "
639 "|| b2 < xmin || b2 > xmax\n";
640 print(mcerr);
641 Iprint4n(mcerr, n1, n2, b1, b2);
642 spexit(mcerr);
643 }
644 n_old = n1;
645 x_old = x;
646 return 1;
647}
648
649template <class T, class D>
650int PointCoorMesh<T, D>::get_interval_extrap(T x, long& n1, T& b1, long& n2,
651 T& b2) const {
652 int i_ret = 1;
653
654 if (x < xmin) {
655 i_ret = 0;
656 n1 = 0;
657 n2 = 1;
658 b1 = xmin;
659#ifndef TLINE_REDUCE_TO_RAW_ARR
660 b2 = (*amesh)[1];
661#else
662 b2 = amesh[1];
663#endif
664 } else if (x >= xmax) {
665 i_ret = 2;
666 n1 = q - 2;
667 n2 = q - 1;
668#ifndef TLINE_REDUCE_TO_RAW_ARR
669 b1 = (*amesh)[q - 2];
670#else
671 b1 = amesh[q - 2];
672#endif
673 b2 = xmax;
674 } else {
675#ifndef TLINE_REDUCE_TO_RAW_ARR
676 if (n_old >= 0 && x_old <= x) {
677 n1 = t_find_interval_end<T, D>(x, q, *amesh, n_old);
678 } else {
679 n1 = t_find_interval<T, D>(x, q, *amesh);
680 }
681//n1 = t_find_interval< T , D >(x, q, amesh);
682#else
683 if (n_old >= 0 && x_old <= x) {
684 n1 = t_find_interval_end<T, T*>(x, q, amesh, n_old);
685 } else {
686 n1 = t_find_interval<T, T*>(x, q, amesh);
687 }
688//n1 = t_find_interval< T , T* >(x, q, &amesh);
689#endif
690 n2 = n1 + 1;
691#ifndef TLINE_REDUCE_TO_RAW_ARR
692 b1 = (*amesh)[n1];
693 b2 = (*amesh)[n2];
694#else
695 b1 = amesh[n1];
696 b2 = amesh[n2];
697#endif
698 if (n1 < 0 || n1 >= q || n2 < 0 || n2 >= q || b1 < xmin || b1 > xmax ||
699 b2 < xmin || b2 > xmax) {
700 mcerr << "ERROR in PointCoorMesh<T,D>::get_interval:\n"
701 << "n1 < 0 || n1 >= q || n2 < 0 || n2 >= q || b1 < xmin || b1 > "
702 "xmax || b2 < xmin || b2 > xmax\n";
703 print(mcerr);
704 Iprint4n(mcerr, n1, n2, b1, b2);
705 spexit(mcerr);
706 }
707 n_old = n1;
708 x_old = x;
709 }
710 return i_ret;
711
712}
713
714template <class T, class D>
715void PointCoorMesh<T, D>::print(std::ostream& file) const {
716 Ifile << "PointCoorMesh<T,D>:\n";
717 indn.n += 2;
718 Ifile << "Type of T is (in internal notations) " << typeid(T).name() << '\n';
719 Ifile << "Type of D is (in internal notations) " << typeid(D).name() << '\n';
720 Iprint3n(file, q, xmin, xmax);
721 Iprint2n(file, n_old, x_old);
722#ifndef TLINE_REDUCE_TO_RAW_ARR
723 Ifile << "(*amesh)=" << (*amesh) << '\n';
724#else
725 Ifile << "amesh:" << '\n';
726 long n;
727 indn.n += 2;
728 for (n = 0; n < q; n++) {
729 Ifile << "n=" << n << " amesh[n]=" << noindent << amesh[n] << yesindent
730 << '\n';
731 }
732 file << yesindent;
733 indn.n -= 2;
734#endif
735 indn.n -= 2;
736}
737
738template <class T, class D>
739 std::ostream& operator<<(std::ostream& file, const PointCoorMesh<T, D>& f) {
740 f.print(file);
741 return file;
742}
743
744// ---------------------------------------------------------------------
745// The generic mesh which has arbitrary steps.
746// The array determining the step edges is located right in this object.
747// Note that it is difficult to make this class derived from previous one
748// due to possibility of it without ifndef TLINE_REDUCE_TO_RAW_ARR.
749// Then the previous class keeps address of D, not necessary
750// raw array or DynLinArr.
751// Note also that TLINE_REDUCE_TO_RAW_ARR works here too.
752
753//#define TLINE_COPIED_USE_ADDRESS // doublfull option.
754// If TLINE_REDUCE_TO_RAW_ARR is defined, it allows to access to content
755// of DynLinArr as to raw array.
756// If TLINE_COPIED_USE_ADDRESS is not defined, access goes through object,
757// and with doundary checks if they are activated for DynLinArr.
758// Perhaps the latter might be slower.
759
760template <class T> class CopiedPointCoorMesh {
761 public:
762
763 inline long get_qi(void) const { return q - 1; }
764 inline T get_xmin(void) const { return xmin; }
765 inline T get_xmax(void) const { return xmax; }
766 inline const DynLinArr<T>& get_mesh(void) const { return mesh; }
767 inline void get_scoor(long n, T& b) const
768#ifdef TLINE_REDUCE_TO_RAW_ARR
769 {
770 b = (*amesh)[n];
771 }
772#else
773 { b = mesh[n]; }
774#endif
775 int get_interval(long n, T& b1, T& b2) const {
776 if (n < 0 || n >= q - 1) return 0;
777#ifdef TLINE_REDUCE_TO_RAW_ARR
778 b1 = (*amesh)[n];
779 b2 = (*amesh)[n + 1];
780#else
781 {
782 b1 = mesh[n];
783 b2 = mesh[n + 1];
784 }
785#endif
786 return 1;
787 }
788
789 int get_interval(T x, long& n1) const;
790
791 int get_interval(T x, long& n1, T& b1, long& n2, T& b2) const;
792
793 int get_interval_extrap(T x, long& n1, T& b1, long& n2, T& b2) const;
794
795 inline int get_step(long n, T& fstep) const {
796 if (n < 0 || n >= q - 1) return 0;
797 T b1, b2;
798 get_interval(n, b1, b2);
799 fstep = b2 - b1;
800 return 1;
801 }
802
803 CopiedPointCoorMesh<T>(void) : q(0), xmin(0), xmax(0), x_old(0), n_old(-1) {
804 ;
805 }
807 long fq, // number of points, number of intervals
808 // is fq - 1.
809 T* famesh); // dimension is fq and the last index is fq-1
810 // This is the end point of the last interval
811
813 DynLinArr<T>& famesh); // dimension is fq and the last index is fq-1
814 // This is the end point of the last interval
816 : q(f.q),
817 mesh(f.mesh),
818 xmin(f.xmin),
819 xmax(f.xmax),
820 x_old(f.x_old),
821 n_old(f.n_old)
822#ifdef TLINE_REDUCE_TO_RAW_ARR
823 amesh(&mesh)
824#endif
825 {
826 }
828 if (this != &f) {
829 q = f.q;
830 mesh = f.mesh;
831 xmin = f.xmin;
832 xmax = f.xmax;
833 x_old = f.x_old;
834 n_old = f.n_old;
835#ifdef TLINE_REDUCE_TO_RAW_ARR
836 amesh = &mesh;
837#endif
838 }
839 return *this;
840 }
841 void print(std::ostream& file) const;
842
843 private:
844 long q; // the number of points
845 // The number of intervals is q-1.
846 // Therefore q has to be 2 or more
847 DynLinArr<T> mesh;
848#ifdef TLINE_REDUCE_TO_RAW_ARR
849 //PassivePtr< D > amesh;
850 T* amesh;
851#endif
852 T xmin;
853 T xmax;
854 // auxiliary thing to accelerate finding intervals
855 mutable T x_old; // previous x for finding interval
856 mutable long n_old; // -1 if there is nothing
857
858};
859
860template <class T>
862 : q(fq), mesh(fq), x_old(0), n_old(-1) {
863 if (q <= 1) {
864 mcerr << "ERROR in CopiedPointCoorMesh<T>::CopiedPointCoorMesh<T>:\n"
865 << "q <= 1\n";
866 Iprintn(mcerr, q);
867 spexit(mcerr);
868 }
869 long n;
870 for (n = 0; n < q; n++) {
871 mesh[n] = famesh[n];
872 }
873 xmin = mesh[0];
874 xmax = mesh[q - 1];
875#ifdef TLINE_REDUCE_TO_RAW_ARR
876 amesh = &mesh;
877#endif
878 // check consistence
879 if (xmin > xmax) {
880 mcerr << "ERROR in CopiedPointCoorMesh<T>::PointCoorMesh<T>:\n"
881 << "xmin > xmax\n";
882 Iprint2n(mcerr, xmin, xmax);
883 spexit(mcerr);
884 }
885#ifdef CHECK_POINT_MESH
886 long n;
887 for (n = 0; n < q - 1; n++) {
888#ifdef TLINE_REDUCE_TO_RAW_ARR
889 if ((*amesh)[n] >= (*amesh)[n + 1])
890#else
891 if (mesh[n] >= mesh[n + 1])
892#endif
893 {
894 mcerr << "ERROR in CopiedPointCoorMesh<T>::PointCoorMesh<T>:\n"
895 << "mesh[n] >= mesh[n+1]\n";
896 Iprint3n(mcerr, n, mesh[n], mesh[n + 1]);
897 spexit(mcerr);
898 }
899 }
900#endif
901
902}
903
904template <class T>
906 : q(fmesh.get_qel()), mesh(fmesh), x_old(0), n_old(-1) {
907 if (q <= 1) {
908 mcerr << "ERROR in CopiedPointCoorMesh<T>::CopiedPointCoorMesh<T>:\n"
909 << "q <= 1\n";
910 Iprintn(mcerr, q);
911 spexit(mcerr);
912 }
913 //long n;
914 //for(n=0; n<q; n++)
915 //{
916 // mesh[n] = famesh[n];
917 //}
918 xmin = mesh[0];
919 xmax = mesh[q - 1];
920#ifdef TLINE_REDUCE_TO_RAW_ARR
921 amesh = &mesh;
922#endif
923 // check consistence
924 if (xmin > xmax) {
925 mcerr << "ERROR in CopiedPointCoorMesh<T>::PointCoorMesh<T>:\n"
926 << "xmin > xmax\n";
927 Iprint2n(mcerr, xmin, xmax);
928 spexit(mcerr);
929 }
930#ifdef CHECK_POINT_MESH
931 long n;
932 for (n = 0; n < q - 1; n++) {
933#ifdef TLINE_REDUCE_TO_RAW_ARR
934 if ((*amesh)[n] >= (*amesh)[n + 1])
935#else
936 if (mesh[n] >= mesh[n + 1])
937#endif
938 {
939 mcerr << "ERROR in CopiedPointCoorMesh<T>::PointCoorMesh<T>:\n"
940 << "mesh[n] >= mesh[n+1]\n";
941 Iprint3n(mcerr, n, mesh[n], mesh[n + 1]);
942 spexit(mcerr);
943 }
944 }
945#endif
946
947}
948
949template <class T>
950int CopiedPointCoorMesh<T>::get_interval(T x, long& n1) const {
951 if (x < xmin || x >= xmax) {
952 n1 = 0;
953 return 0;
954 }
955#ifdef TLINE_REDUCE_TO_RAW_ARR
956 if (n_old >= 0 && x_old <= x) {
957 n1 = t_find_interval_end<T, T*>(x, q, amesh, n_old);
958 } else {
959 n1 = t_find_interval<T, T*>(x, q, amesh);
960 }
961//n1 = t_find_interval< T , D >(x, q, amesh);
962#else
963 if (n_old >= 0 && x_old <= x) {
964 n1 = t_find_interval_end<T, DynLinArr<T> >(x, q, mesh, n_old);
965 } else {
966 n1 = t_find_interval<T, DynLinArr<T> >(x, q, mesh);
967 }
968//n1 = t_find_interval< T , T* >(x, q, &amesh);
969#endif
970
971 if (n1 < 0) {
972 mcerr << "ERROR in CopiedPointCoorMesh<T>::get_interval:\n"
973 << "n1 < 0\n";
974 print(mcerr);
975 Iprintn(mcerr, n1);
976 spexit(mcerr);
977 }
978 n_old = n1;
979 x_old = x;
980 return 1;
981}
982
983template <class T>
984int CopiedPointCoorMesh<T>::get_interval(T x, long& n1, T& b1, long& n2,
985 T& b2) const {
986 if (x < xmin || x >= xmax) {
987 n1 = 0;
988 n2 = 0;
989 b1 = 0;
990 b2 = 0;
991 return 0;
992 }
993#ifdef TLINE_REDUCE_TO_RAW_ARR
994 if (n_old >= 0 && x_old <= x) {
995 n1 = t_find_interval_end<T, T*>(x, q, amesh, n_old);
996 } else {
997 n1 = t_find_interval<T, T*>(x, q, amesh);
998 }
999//n1 = t_find_interval< T , D >(x, q, amesh);
1000#else
1001 if (n_old >= 0 && x_old <= x) {
1002 n1 = t_find_interval_end<T, DynLinArr<T> >(x, q, mesh, n_old);
1003 } else {
1004 n1 = t_find_interval<T, DynLinArr<T> >(x, q, mesh);
1005 }
1006//n1 = t_find_interval< T , T* >(x, q, &amesh);
1007#endif
1008 n2 = n1 + 1;
1009#ifdef TLINE_REDUCE_TO_RAW_ARR
1010 b1 = amesh[n1];
1011 b2 = amesh[n2];
1012#else
1013 b1 = mesh[n1];
1014 b2 = mesh[n2];
1015#endif
1016 if (n1 < 0 || n1 >= q || n2 < 0 || n2 >= q || b1 < xmin || b1 > xmax ||
1017 b2 < xmin || b2 > xmax) {
1018 mcerr << "ERROR in CopiedPointCoorMesh<T>::get_interval:\n"
1019 << "n1 < 0 || n1 >= q || n2 < 0 || n2 >= q || b1 < xmin || b1 > xmax "
1020 "|| b2 < xmin || b2 > xmax\n";
1021 print(mcerr);
1022 Iprint4n(mcerr, n1, n2, b1, b2);
1023 spexit(mcerr);
1024 }
1025 n_old = n1;
1026 x_old = x;
1027 return 1;
1028}
1029
1030template <class T>
1031int CopiedPointCoorMesh<T>::get_interval_extrap(T x, long& n1, T& b1, long& n2,
1032 T& b2) const {
1033 int i_ret = 1;
1034
1035 if (x < xmin) {
1036 i_ret = 0;
1037 n1 = 0;
1038 n2 = 1;
1039 b1 = xmin;
1040#ifdef TLINE_REDUCE_TO_RAW_ARR
1041 b2 = (*amesh)[1];
1042#else
1043 b2 = mesh[1];
1044#endif
1045 } else if (x >= xmax) {
1046 i_ret = 2;
1047 n1 = q - 2;
1048 n2 = q - 1;
1049#ifdef TLINE_REDUCE_TO_RAW_ARR
1050 b1 = (*amesh)[q - 2];
1051#else
1052 b1 = mesh[q - 2];
1053#endif
1054 b2 = xmax;
1055 } else {
1056#ifndef TLINE_REDUCE_TO_RAW_ARR
1057 if (n_old >= 0 && x_old <= x) {
1058 n1 = t_find_interval_end<T, DynLinArr<T> >(x, q, mesh, n_old);
1059 } else {
1060 n1 = t_find_interval<T, DynLinArr<T> >(x, q, mesh);
1061 }
1062//n1 = t_find_interval< T , D >(x, q, amesh);
1063#else
1064 if (n_old >= 0 && x_old <= x) {
1065 n1 = t_find_interval_end<T, T*>(x, q, amesh, n_old);
1066 } else {
1067 n1 = t_find_interval<T, T*>(x, q, amesh);
1068 }
1069//n1 = t_find_interval< T , T* >(x, q, &amesh);
1070#endif
1071 n2 = n1 + 1;
1072#ifndef TLINE_REDUCE_TO_RAW_ARR
1073 b1 = mesh[n1];
1074 b2 = mesh[n2];
1075#else
1076 b1 = amesh[n1];
1077 b2 = amesh[n2];
1078#endif
1079 if (n1 < 0 || n1 >= q || n2 < 0 || n2 >= q || b1 < xmin || b1 > xmax ||
1080 b2 < xmin || b2 > xmax) {
1081 mcerr << "ERROR in CopiedPointCoorMesh<T>::get_interval:\n"
1082 << "n1 < 0 || n1 >= q || n2 < 0 || n2 >= q || b1 < xmin || b1 > "
1083 "xmax || b2 < xmin || b2 > xmax\n";
1084 print(mcerr);
1085 Iprint4n(mcerr, n1, n2, b1, b2);
1086 spexit(mcerr);
1087 }
1088 n_old = n1;
1089 x_old = x;
1090 }
1091 return i_ret;
1092
1093}
1094
1095template <class T>
1096void CopiedPointCoorMesh<T>::print(std::ostream& file) const {
1097 Ifile << "CopiedPointCoorMesh<T>:\n";
1098 indn.n += 2;
1099 Ifile << "Type of T is (in internal notations) " << typeid(T).name() << '\n';
1100 //Ifile<<"Type of D is (in internal notations) "<<typeid(D).name()<<'\n';
1101 Iprint3n(file, q, xmin, xmax);
1102 Iprint2n(file, n_old, x_old);
1103
1104 Ifile << "mesh= " << mesh << '\n';
1105
1106 //#else
1107 //Ifile<<"amesh:"<<'\n';
1108 //long n;
1109 //indn.n+=2;
1110 //for( n=0; n<q; n++)
1111 //{
1112 //Ifile<<"n="<<n<<" amesh[n]="<<noindent<<amesh[n]<<yesindent<<'\n';
1113 //}
1114 //file<<yesindent;
1115 //indn.n-=2;
1116 //#endif
1117 indn.n -= 2;
1118}
1119
1120template <class T>
1121 std::ostream& operator<<(std::ostream& file, CopiedPointCoorMesh<T>& f) {
1122 f.print(file);
1123 return file;
1124}
1125
1126template <class T>
1127 std::istream& operator>>(std::istream& file, CopiedPointCoorMesh<T>& f) {
1128 mfunname("istream& operator>>(istream& file, CopiedPointCoorMesh<T>& f)");
1129 definp_endpar dep(&file, 0, 1, 0);
1130 set_position("Type of T is (in internal notations)", *dep.istrm, dep.s_rewind,
1131 dep.s_req_sep);
1132 DynLinArr<T> mesh;
1133 f = CopiedPointCoorMesh<T>(mesh);
1134 return file;
1135}
1136
1137template <class T>
1139 const CopiedPointCoorMesh<T>& f2) {
1140 if (f1.get_qi() != f2.get_qi() || f1.get_xmin() != f2.get_xmin() ||
1141 f1.get_xmax() != f2.get_xmax())
1142 return 0;
1143 if (f1.get_mesh() != f2.get_mesh())
1144 return 0;
1145 else
1146 return 1;
1147}
1148
1149template <class T>
1151 const CopiedPointCoorMesh<T>& f2, T prec) {
1152 if (f1.get_qi() != f2.get_qi() ||
1153 !apeq_mant(f1.get_xmin(), f2.get_xmin(), prec) ||
1154 !apeq_mant(f1.get_xmax(), f2.get_xmax(), prec))
1155 return 0;
1156 if (!apeq_mant(f1.get_mesh(), f2.get_mesh(), prec))
1157 return 0;
1158 else
1159 return 1;
1160}
1161
1162template <class T>
1164 const CopiedPointCoorMesh<T>& f2) {
1165 if (f1.get_qi() != f2.get_qi() || f1.get_xmin() != f2.get_xmin() ||
1166 f1.get_xmax() != f2.get_xmax())
1167 return 1;
1168 if (f1.get_mesh() != f2.get_mesh())
1169 return 1;
1170 else
1171 return 0;
1172}
1173
1174//-------------------------------------------------------------
1175// Auxiliary class which proides easy writting of polimorphic operator==
1176// See check_equat.c for details.
1177
1178template <class T, class B>
1179int verify_types(const T* ths, const B* b2, const T** tb2) {
1180 mfunnamep("template<class T> verify_types(const T* ths, const B* b2, const "
1181 "T* tb2)");
1182 //mcout<<"verify_types is working\n";
1183 //Iprintn(mcerr, typeid(T).name());
1184 //Iprintn(mcerr, typeid(B).name());
1185 if (typeid(*b2) != typeid(*ths)) return 0;
1186 if (typeid(*ths) != typeid(T)) {
1187 funnw.ehdr(cerr);
1188 mcerr << "Operator == for class T is called for first object of different "
1189 "class\n";
1190 mcerr << "This may mean that this operator is missed in one of derived "
1191 "classes\n";
1192 Iprintn(mcerr, typeid(*ths).name());
1193 spexit(mcerr);
1194 }
1195 *tb2 = dynamic_cast<const T*>(b2);
1196 check_econd11(*tb2, == NULL, mcerr);
1197 return 1;
1198}
1199
1200//----------------------------------------------------------
1201// Polimorphic meshes (which are sometimes also necessary)
1202
1203template <class T> class AbsCoorMesh : public RegPassivePtr {
1204 public:
1205 virtual long get_qi(void) const = 0;
1206 virtual T get_xmin(void) const = 0;
1207 virtual T get_xmax(void) const = 0;
1208
1209 // get single coordinate
1210 // of the point in the mesh. It can be last point of the last interval:
1211 virtual void get_scoor(long n, T& b) const = 0;
1212
1213 virtual int get_interval(long n, T& b1, T& b2) const = 0;
1214
1215 virtual int get_interval(T x, // is coordinate
1216 long& n1) const = 0; // is the bin number
1217
1218 // The same as above, but returns more information:
1219 virtual int get_interval(T x, long& n1,
1220 T& b1, // the bin number and left border
1221 long& n2, T& b2) // the next bin number and its left
1222 const = 0;
1223
1224 virtual int get_interval_extrap(T x, long& n1, T& b1, long& n2,
1225 T& b2) const = 0;
1226 // returns 1 if x inside xmin and xmax and therefore b1 and b2,
1227 // 0 if x < xmin
1228 // 2 if x > xmax
1229
1230 virtual int get_step(long n, T& fstep) const = 0;
1231
1232 virtual void print(std::ostream& file) const {
1233 Ifile << "AbsCoorMesh: no content.\n";
1234 } // 24 characters
1235
1237 virtual ~AbsCoorMesh() {}
1238 ;
1239
1240 virtual int operator==(const AbsCoorMesh<T>&) {
1241 mfunnamep("virtual int operator==(const AbsCoorMesh<T>&)");
1242 funnw.ehdr(cerr);
1243 mcerr << "AbsCoorMesh::operator == cannot be called since this is abstract "
1244 "class\n";
1245 spexit(mcerr);
1246#ifdef INS_CRETURN
1247 return 0; // to calm compiler
1248#endif
1249 }
1250 virtual int operator!=(const AbsCoorMesh<T>&) {
1251 mfunnamep("virtual int operator!=(const AbsCoorMesh<T>&)");
1252 funnw.ehdr(cerr);
1253 mcerr << "AbsCoorMesh::operator != cannot be called since this is abstract "
1254 "class\n";
1255 spexit(mcerr);
1256#ifdef INS_CRETURN
1257 return 0; // to calm compiler
1258#endif
1259 }
1260 virtual int apeq_mant(const AbsCoorMesh<T>&, T /*prec*/) {
1261 mfunnamep("virtual int apeq_mant(const AbsCoorMesh<T>& m2, T prec)");
1262 funnw.ehdr(cerr);
1263 mcerr << "AbsCoorMesh::apeq_mant != cannot be called since this is "
1264 "abstract class\n";
1265 spexit(mcerr);
1266#ifdef INS_CRETURN
1267 return 0; // to calm compiler
1268#endif
1269 }
1270};
1271
1272template <class T>
1273 std::ostream& operator<<(std::ostream& file, AbsCoorMesh<T>& f) {
1274 f.print(file);
1275 return file;
1276}
1277
1278template <class T>
1280 public EqualStepCoorMesh<T> {
1281 public:
1282 virtual long get_qi(void) const { return EqualStepCoorMesh<T>::get_qi(); }
1283 virtual T get_xmin(void) const { return EqualStepCoorMesh<T>::get_xmin(); }
1284 virtual T get_xmax(void) const { return EqualStepCoorMesh<T>::get_xmax(); }
1285
1286 // get single coordinate
1287 // of the point in the mesh. It can be last point of the last interval:
1288 virtual void get_scoor(long n, T& b) const {
1290 }
1291
1292 virtual int get_interval(long n, T& b1, T& b2) const {
1293 return EqualStepCoorMesh<T>::get_interval(n, b1, b2);
1294 }
1295
1296 virtual int get_interval(T x, // is coordinate
1297 long& n1) const // is the bin number
1298 {
1300 }
1301
1302 // The same as above, but returns more information:
1303 virtual int get_interval(T x, long& n1,
1304 T& b1, // the bin number and left border
1305 long& n2, T& b2) // the next bin number and its left
1306 const {
1307 return EqualStepCoorMesh<T>::get_interval(x, n1, b1, n2, b2);
1308 }
1309
1310 virtual int get_interval_extrap(T x, long& n1, T& b1, long& n2, T& b2) const {
1311 return EqualStepCoorMesh<T>::get_interval_extrap(x, n1, b1, n2, b2);
1312 }
1313
1314 // returns 1 if x inside xmin and xmax and therefore b1 and b2,
1315 // 0 if x < xmin
1316 // 2 if x > xmax
1317
1318 virtual int get_step(long n, T& fstep) const {
1319 return EqualStepCoorMesh<T>::get_step(n, fstep);
1320 }
1321
1323 VirtEqualStepCoorMesh<T>(long fq, T fxmin, T fxmax)
1324 : EqualStepCoorMesh<T>(fq, fxmin, fxmax) {}
1325
1326 virtual void print(std::ostream& file) const {
1327 Ifile << "VirtEqualStepCoorMesh<T>: \n";
1328 indn.n += 2;
1329 // two blanks there above are necessary for correct reading
1331 indn.n -= 2;
1332 }
1333
1335 virtual ~VirtEqualStepCoorMesh<T>() {}
1336 virtual int operator==(const AbsCoorMesh<T>& m2) {
1337 mfunname("virtual int VirtEqualStepCoorMesh<T>::operator==(const "
1338 "AbsCoorMesh<T>& m2)");
1339 const VirtEqualStepCoorMesh<T>* tm2;
1340 if (!verify_types(this, &m2, &tm2)) return 0;
1341 // The previous condition makes type of m2 equal to that of this.
1342 if (this == &m2) return 1; // addresses coincide, what means that it is
1343 // the same object. Put here but not in the first line in order
1344 // to detect missing operators== for derived casses as soon as possible.
1345 return ::operator==(static_cast<const EqualStepCoorMesh<T> >(*this),
1346 static_cast<const EqualStepCoorMesh<T> >(*tm2));
1347 }
1348 virtual int operator!=(const AbsCoorMesh<T>& m2) {
1349 if (operator==(m2) == 1)
1350 return 0;
1351 else
1352 return 1;
1353 }
1354 virtual int apeq_mant(const AbsCoorMesh<T>& m2, T prec) {
1355 mfunname("virtual int apeq_mant(const AbsCoorMesh<T>& m2, T prec)");
1356 const VirtEqualStepCoorMesh<T>* tm2;
1357 if (!verify_types(this, &m2, &tm2)) return 0;
1358 // The previous condition makes type of m2 equal to that of this.
1359 if (this == &m2) return 1; // addresses coincide, what means that it is
1360 // the same object. Put here but not in the first line in order
1361 // to detect missing operators== for derived casses as soon as possible.
1362 return ::apeq_mant(static_cast<const EqualStepCoorMesh<T> >(*this),
1363 static_cast<const EqualStepCoorMesh<T> >(*tm2), prec);
1364 }
1365};
1366
1367template <class T>
1368 std::ostream& operator<<(std::ostream& file, VirtEqualStepCoorMesh<T>& f) {
1369 f.print(file);
1370 return file;
1371}
1372
1373template <class T>
1374 std::istream& operator>>(std::istream& file, VirtEqualStepCoorMesh<T>& f) {
1375 mfunname("istream& operator>>(istream& file, VirtEqualStepCoorMesh<T>& f)");
1376 definp_endpar dep(&file, 0, 1, 0);
1377 set_position("EqualStepCoorMesh<T>:", *dep.istrm, dep.s_rewind,
1378 dep.s_req_sep);
1379 //file>>f;
1380 //file>>(static_cast< EqualStepCoorMesh<T> >(f));
1381 EqualStepCoorMesh<T>& ft = f;
1382 file >> ft;
1383
1384 return file;
1385}
1386/*
1387template<class T>
1388int operator==(const VirtEqualStepCoorMesh<T>& f1,
1389 const VirtEqualStepCoorMesh<T>& f2)
1390{
1391 return operator==(static_cast< const EqualStepCoorMesh<T>& >(f1),
1392 static_cast< const EqualStepCoorMesh<T>& >(f2));
1393}
1394template<class T>
1395int apeq_mant(const VirtEqualStepCoorMesh<T>& f1,
1396 const VirtEqualStepCoorMesh<T>& f2, T prec)
1397{
1398 return apeq_mant(static_cast< const EqualStepCoorMesh<T>& >(f1),
1399 static_cast< const EqualStepCoorMesh<T>& >(f2), prec);
1400}
1401template<class T>
1402int operator!=(const VirtEqualStepCoorMesh<T>& f1,
1403 const VirtEqualStepCoorMesh<T>& f2)
1404{
1405 return operator!=(static_cast< const EqualStepCoorMesh<T>& >(f1),
1406 static_cast< const EqualStepCoorMesh<T>& >(f2));
1407}
1408*/
1409
1410template <class T>
1412 public CopiedPointCoorMesh<T> {
1413 public:
1414 virtual long get_qi(void) const { return CopiedPointCoorMesh<T>::get_qi(); }
1415 virtual T get_xmin(void) const { return CopiedPointCoorMesh<T>::get_xmin(); }
1416 virtual T get_xmax(void) const { return CopiedPointCoorMesh<T>::get_xmax(); }
1417
1418 // get single coordinate
1419 // of the point in the mesh. It can be last point of the last interval:
1420 virtual void get_scoor(long n, T& b) const {
1422 }
1423
1424 virtual int get_interval(long n, T& b1, T& b2) const {
1425 return CopiedPointCoorMesh<T>::get_interval(n, b1, b2);
1426 }
1427
1428 virtual int get_interval(T x, // is coordinate
1429 long& n1) const // is the bin number
1430 {
1432 }
1433
1434 // The same as above, but returns more information:
1435 virtual int get_interval(T x, long& n1,
1436 T& b1, // the bin number and left border
1437 long& n2, T& b2) // the next bin number and its left
1438 const {
1439 return CopiedPointCoorMesh<T>::get_interval(x, n1, b1, n2, b2);
1440 }
1441
1442 virtual int get_interval_extrap(T x, long& n1, T& b1, long& n2, T& b2) const {
1443 return CopiedPointCoorMesh<T>::get_interval_extrap(x, n1, b1, n2, b2);
1444 }
1445
1446 // returns 1 if x inside xmin and xmax and therefore b1 and b2,
1447 // 0 if x < xmin
1448 // 2 if x > xmax
1449
1450 virtual int get_step(long n, T& fstep) const {
1451 return CopiedPointCoorMesh<T>::get_step(n, fstep);
1452 }
1453
1454 VirtCopiedPointCoorMesh<T>(void) { ; }
1456 : // dimension is fq and the last index is fq-1
1457 // This is the end point of the last interval
1458 CopiedPointCoorMesh<T>(famesh) {}
1459
1460 virtual void print(std::ostream& file) const {
1461 Ifile << "VirtCopiedPointCoorMesh<T>:\n";
1462 indn.n += 2;
1464 indn.n -= 2;
1465 }
1466
1468 virtual ~VirtCopiedPointCoorMesh<T>() {}
1469 ;
1470 virtual int operator==(const AbsCoorMesh<T>& m2) {
1471 mfunname("virtual int operator==(const AbsCoorMesh<T>& m2)");
1472 const VirtCopiedPointCoorMesh<T>* tm2;
1473 if (!verify_types(this, &m2, &tm2)) return 0;
1474 // The previous condition makes type of m2 equal to that of this.
1475 if (this == &m2) return 1; // addresses coincide, what means that it is
1476 // the same object. Put here but not in the first line in order
1477 // to detect missing operators== for derived casses as soon as possible.
1478 return ::operator==(static_cast<const CopiedPointCoorMesh<T> >(*this),
1479 static_cast<const CopiedPointCoorMesh<T> >(*tm2));
1480 }
1481 virtual int operator!=(const AbsCoorMesh<T>& m2) {
1482 if (operator==(m2) == 1)
1483 return 0;
1484 else
1485 return 1;
1486 }
1487 virtual int apeq_mant(const AbsCoorMesh<T>& m2, T prec) {
1488 mfunname("virtual int apeq_mant(const AbsCoorMesh<T>& m2, T prec)");
1489 const VirtCopiedPointCoorMesh<T>* tm2;
1490 if (!verify_types(this, &m2, &tm2)) return 0;
1491 // The previous condition makes type of m2 equal to that of this.
1492 if (this == &m2) return 1; // addresses coincide, what means that it is
1493 // the same object. Put here but not in the first line in order
1494 // to detect missing operators== for derived casses as soon as possible.
1495 return ::apeq_mant(static_cast<const CopiedPointCoorMesh<T> >(*this),
1496 static_cast<const CopiedPointCoorMesh<T> >(*tm2), prec);
1497 }
1498};
1499
1500template <class T>
1501 std::ostream& operator<<(std::ostream& file,
1503 f.print(file);
1504 return file;
1505}
1506
1507template <class T>
1508 std::istream& operator>>(std::istream& file,
1510 mfunname("istream& operator>>(istream& file, VirtCopiedPointCoorMesh<T>& f)");
1511 definp_endpar dep(&file, 0, 1, 0);
1512 set_position("CopiedPointCoorMesh<T>:", *dep.istrm, dep.s_rewind,
1513 dep.s_req_sep);
1514 // file>>f; // this would lead to loop
1515 //file>>(static_cast< CopiedPointCoorMesh<T> >(f));
1516 CopiedPointCoorMesh<T>& ft = f;
1517 file >> ft;
1518 return file;
1519}
1520/*
1521template<class T>
1522int operator==(const VirtCopiedPointCoorMesh<T>& f1,
1523 const VirtCopiedPointCoorMesh<T>& f2)
1524{
1525 return operator==(static_cast< const CopiedPointCoorMesh<T> >(f1) ,
1526 static_cast< const CopiedPointCoorMesh<T>& >(f2));
1527}
1528template<class T>
1529int apeq_mant(const VirtCopiedPointCoorMesh<T>& f1,
1530 const VirtCopiedPointCoorMesh<T>& f2, T prec)
1531{
1532 return apeq_mant(static_cast< const CopiedPointCoorMesh<T> >(f1) ,
1533 static_cast< const CopiedPointCoorMesh<T>& >(f2), prec);
1534}
1535
1536template<class T>
1537int operator!=(const VirtCopiedPointCoorMesh<T>& f1,
1538 const VirtCopiedPointCoorMesh<T>& f2)
1539{
1540 return operator!=(static_cast< const CopiedPointCoorMesh<T> >(f1) ,
1541 static_cast< const CopiedPointCoorMesh<T>& >(f2));
1542}
1543*/
1544
1545/* attension: this assumes only two derivatives, that is really bad design.
1546Is it possible to make it allowing any derivatives? (to think in future).
1547*/
1548/*
1549template<class T>
1550int operator==(const AbsCoorMesh<T>& f1,
1551 const AbsCoorMesh<T>& f2)
1552{
1553 const VirtEqualStepCoorMesh<T>* af1 =
1554 dynamic_cast< const VirtEqualStepCoorMesh<T>* >(&f1);
1555 const VirtEqualStepCoorMesh<T>* af2 =
1556 dynamic_cast< const VirtEqualStepCoorMesh<T>* >(&f2);
1557 if(af1 != NULL && af2 != NULL)
1558 {
1559 if((*af1) == (*af2)) return 1;
1560 }
1561 const VirtCopiedPointCoorMesh<T>* af3 =
1562 dynamic_cast< const VirtCopiedPointCoorMesh<T>* >(&f1);
1563 const VirtCopiedPointCoorMesh<T>* af4 =
1564 dynamic_cast< const VirtCopiedPointCoorMesh<T>* >(&f2);
1565 if(af3 != NULL && af4 != NULL)
1566 {
1567 if((*af3) == (*af4)) return 1;
1568 }
1569 return 0;
1570}
1571
1572template<class T>
1573int apeq_mant(const AbsCoorMesh<T>& f1,
1574 const AbsCoorMesh<T>& f2, T prec)
1575{
1576 const VirtEqualStepCoorMesh<T>* af1 =
1577 dynamic_cast< const VirtEqualStepCoorMesh<T>* >(&f1);
1578 const VirtEqualStepCoorMesh<T>* af2 =
1579 dynamic_cast< const VirtEqualStepCoorMesh<T>* >(&f2);
1580 if(af1 != NULL && af2 != NULL)
1581 {
1582 if(apeq_mant((*af1) , (*af2) , prec) == 1) return 1;
1583 }
1584 const VirtCopiedPointCoorMesh<T>* af3 =
1585 dynamic_cast< const VirtCopiedPointCoorMesh<T>* >(&f1);
1586 const VirtCopiedPointCoorMesh<T>* af4 =
1587 dynamic_cast< const VirtCopiedPointCoorMesh<T>* >(&f2);
1588 if(af3 != NULL && af4 != NULL)
1589 {
1590 if(apeq_mant((*af3) , (*af4) , prec) == 1) return 1;
1591 }
1592 return 0;
1593}
1594
1595template<class T>
1596int operator!=(const AbsCoorMesh<T>& f1,
1597 const AbsCoorMesh<T>& f2)
1598{
1599 if(f1 == f2) return 0;
1600 return 1;
1601}
1602*/
1603template <class T>
1604ActivePtr<AbsCoorMesh<T> > read_AbsCoorMesh(std::istream& file) {
1605 mfunnamep("ActivePtr< AbsCoorMesh<T> > read_AbsCoorMesh(istream& file)");
1606 const long q = 28;
1607 long n;
1608 char keyline[q];
1609 for (n = 0; n < q - 1; n++) {
1610 //file.get(keyline[n]);
1611 keyline[n] = file.get();
1612 }
1613 keyline[n] = '\0';
1614 if (!strcmp(&(keyline[0]), "AbsCoorMesh: no content.")) {
1615 funnw.ehdr(mcerr);
1616 mcout << "attempt to read AbsCoorMesh\n";
1617 spexit(mcerr);
1618 }
1619 if (!strcmp(&(keyline[0]), "VirtEqualStepCoorMesh<T>: ")) {
1621 file >> (*amesh);
1622 return ActivePtr<AbsCoorMesh<T> >(amesh, dont_clone);
1623 }
1624 if (!strcmp(&(keyline[0]), "VirtCopiedPointCoorMesh<T>:")) {
1626 file >> (*amesh);
1627 return ActivePtr<AbsCoorMesh<T> >(amesh, dont_clone);
1628 }
1629 funnw.ehdr(mcerr);
1630 mcout << "cannot identifiy the type of derived AbsCoorMesh\n";
1631 Iprintn(mcout, keyline);
1632 spexit(mcerr);
1633#ifdef INS_CRETURN
1634 return ActivePtr<AbsCoorMesh<T> >();
1635#endif
1636}
1637
1638// end of definitions of meshes
1639//-----------------------------------------------------------------------
1640
1641// Step array is like a histogram.
1642// Each value of y represents constant height in each interval
1643// If mesh is defined by points,
1644// its size should be longer by unity than the number of y-points,
1645// the last x-point being represent the end of the last bin.
1646
1647// Extract value defined by this array for abscissa x
1648template <class T, class D, class M>
1649T t_value_step_ar(const M& mesh, const D& y, // array of function values
1650 T x, int s_include_last_point = 0)
1651 // 0 - not include, 1 - include
1652 {
1653 mfunname("double t_value_step_ar(...)");
1654 double xmin = mesh.get_xmin();
1655 double xmax = mesh.get_xmax();
1656 //Iprint3n(mcout, x, xmin, xmax);
1657 if (x < xmin) return 0;
1658 if (s_include_last_point == 0) {
1659 if (x >= xmax) return 0;
1660 } else {
1661 if (x > xmax) return 0;
1662 }
1663 long n1, n2;
1664 T b1, b2;
1665 int i_ret = 0;
1666 i_ret = mesh.get_interval(x, n1, b1, n2, b2);
1667 check_econd11(i_ret, != 1, mcerr);
1668 return y[n1];
1669}
1670
1671// The same for two-dimensional array D
1672template <class T, class D, class M1, class M2>
1673T t_value_step_ar(const M1& mesh1, const M2& mesh2,
1674 const D& y, // array of function values
1675 T x1, T x2, int s_include_last_point = 0)
1676 // 0 - not include, 1 - include
1677 {
1678 mfunname("double t_value_step_ar(...)");
1679 double x1min = mesh1.get_xmin();
1680 double x1max = mesh1.get_xmax();
1681 //Iprint3n(mcout, x, xmin, xmax);
1682 if (x1 < x1min) return 0;
1683 if (s_include_last_point == 0) {
1684 if (x1 >= x1max) return 0;
1685 } else {
1686 if (x1 > x1max) return 0;
1687 }
1688 double x2min = mesh2.get_xmin();
1689 double x2max = mesh2.get_xmax();
1690 //Iprint3n(mcout, x, xmin, xmax);
1691 if (x2 < x2min) return 0;
1692 if (s_include_last_point == 0) {
1693 if (x2 >= x2max) return 0;
1694 } else {
1695 if (x2 > x2max) return 0;
1696 }
1697 long n11, n12;
1698 long n21, n22;
1699 T b1, b2;
1700 int i_ret = 0;
1701
1702 i_ret = mesh1.get_interval(x1, n11, b1, n12, b2);
1703 check_econd11(i_ret, != 1, mcerr);
1704
1705 i_ret = mesh2.get_interval(x2, n21, b1, n22, b2);
1706
1707 check_econd11(i_ret, != 1, mcerr);
1708 return y[n11][n21];
1709}
1710
1711// Fill the array y like a histogram adding value val (or 1) for bin
1712// corresponding to abscissa x
1713template <class T, class D, class M>
1714void t_hfill_step_ar(const M& mesh, const D& y, // array of function values
1715 T x, T val = 1, int s_include_last_point = 0)
1716 // 0 - not include, 1 - include
1717 {
1718 mfunname("double t_hfill_step_ar(...)");
1719 double xmin = mesh.get_xmin();
1720 double xmax = mesh.get_xmax();
1721 //Iprint3n(mcout, x, xmin, xmax);
1722 if (x < xmin) return;
1723 if (s_include_last_point == 0) {
1724 if (x >= xmax) return;
1725 } else {
1726 if (x > xmax) return;
1727 }
1728 long n1;
1729 int i_ret = 0;
1730 i_ret = mesh.get_interval(x, n1);
1731 check_econd11(i_ret, != 1, mcerr);
1732 y[n1] += val;
1733 return;
1734}
1735
1736// The same as above, but with "ac" access instead of "[]".
1737// Useful if D is DynArr.
1738
1739template <class T, class D, class M>
1740void t_hfill_step_ar_ac(const M& mesh, const D& y, // array of function values
1741 T x, T val = 1, int s_include_last_point = 0)
1742 // 0 - not include, 1 - include
1743 {
1744 mfunname("double t_hfill_step_ar(...)");
1745 double xmin = mesh.get_xmin();
1746 double xmax = mesh.get_xmax();
1747 //Iprint3n(mcout, x, xmin, xmax);
1748 if (x < xmin) return;
1749 if (s_include_last_point == 0) {
1750 if (x >= xmax) return;
1751 } else {
1752 if (x > xmax) return;
1753 }
1754 long n1;
1755 int i_ret = 0;
1756 i_ret = mesh.get_interval(x, n1);
1757 check_econd11(i_ret, != 1, mcerr);
1758 y.ac(n1) += val;
1759 return;
1760}
1761
1762// The same but for two-dimensional array:
1763template <class T, class D, class M1, class M2>
1764void t_hfill_step_ar_ac(const M1& mesh1, const M2& mesh2,
1765 const D& y, // array of function values
1766 T x1, T x2, T val = 1, int s_include_last_point = 0)
1767 // 0 - not include, 1 - include
1768 {
1769 mfunname("double t_hfill_step_ar(...)");
1770 double x1min = mesh1.get_xmin();
1771 double x1max = mesh1.get_xmax();
1772 double x2min = mesh2.get_xmin();
1773 double x2max = mesh2.get_xmax();
1774 //Iprint3n(mcout, x, xmin, xmax);
1775 if (x1 < x1min) return;
1776 if (s_include_last_point == 0) {
1777 if (x1 >= x1max) return;
1778 } else {
1779 if (x1 > x1max) return;
1780 }
1781 if (x2 < x2min) return;
1782 if (s_include_last_point == 0) {
1783 if (x2 >= x2max) return;
1784 } else {
1785 if (x2 > x2max) return;
1786 }
1787 long n1;
1788 int i_ret1 = 0;
1789 i_ret1 = mesh1.get_interval(x1, n1);
1790 check_econd11(i_ret1, != 1, mcerr);
1791 long n2;
1792 int i_ret2 = 0;
1793 i_ret2 = mesh2.get_interval(x2, n2);
1794 check_econd11(i_ret2, != 1, mcerr);
1795 y.ac(n1, n2) += val;
1796 return;
1797}
1798
1799/*
1800Integrate the function represented by array y (interpreted as
1801rectangular bins with height determined by the values y[n])
1802from x1 to x2, taking either pure integral by x (for xpower = 0,
1803that is it will be sum of function values multiplied by
1804bin width)
1805or int(f * x * dx) (for xpower = 1,
1806the integration of product of function by x).
1807*/
1808
1809template <class T, class D, class M>
1810T t_integ_step_ar(const M& mesh, const D& y, // array of function values
1811 T x1, T x2, int xpower) // currently 0 or 1
1812 {
1813 mfunname("double t_integ_step_ar(...)");
1814
1815 // mcout<<"start t_step_integ_ar\n";
1816 check_econd21(xpower, != 0 &&, != 1, mcerr);
1817 check_econd12(x1, >, x2, mcerr);
1818 long qi = mesh.get_qi();
1819 check_econd12(qi, <, 1, mcerr);
1820 //if(x1 > x2) return 0;
1821 double xmin = mesh.get_xmin();
1822 double xmax = mesh.get_xmax();
1823 if (x2 <= xmin) return 0;
1824 if (x1 >= xmax) return 0;
1825 if (x1 == x2) return 0;
1826 long istart, iafterend; // indexes to sum total intervals
1827 T s(0);
1828 if (x1 <= xmin) {
1829 x1 = xmin;
1830 istart = 0;
1831 } else {
1832 long n1, n2;
1833 T b1, b2;
1834 int i_ret = 0;
1835 i_ret = mesh.get_interval(x1, n1, b1, n2, b2);
1836 //Iprint2n(mcout, x1, i_ret);
1837 //Iprint4n(mcout, n1, b1, n2, b2);
1838 check_econd11(i_ret, != 1, mcerr);
1839 if (b2 - x1 > 0) { // otherwise it could be only equal to 0
1840 if (x2 <= b2) { // if x2 in the same interval
1841 if (xpower == 0) {
1842 s = (x2 - x1) * y[n1];
1843 } else {
1844 s = 0.5 * (x2 * x2 - x1 * x1) * y[n1];
1845 }
1846 return s;
1847 }
1848 if (xpower == 0) {
1849 s += (b2 - x1) * y[n1];
1850 } else {
1851 s += 0.5 * (b2 * b2 - x1 * x1) * y[n1];
1852 }
1853 }
1854 istart = n2;
1855 }
1856 if (x2 >= xmax) {
1857 x2 = xmax;
1858 iafterend = qi;
1859 } else {
1860 long n1, n2;
1861 T b1, b2;
1862 int i_ret = 0;
1863 i_ret = mesh.get_interval(x2, n1, b1, n2, b2);
1864 //Iprint2n(mcout, x2, i_ret);
1865 //Iprint4n(mcout, n1, b1, n2, b2);
1866 check_econd11(i_ret, != 1, mcerr);
1867 if (x2 - b1 > 0) {
1868 if (xpower == 0) {
1869 s += (x2 - b1) * y[n1];
1870 } else {
1871 s += 0.5 * (x2 * x2 - b1 * b1) * y[n1];
1872 }
1873 }
1874 iafterend = n1;
1875 }
1876 //Iprint2n(mcout, istart, iafterend);
1877 long i;
1878 double b;
1879 mesh.get_scoor(istart, b);
1880 if (xpower == 0) {
1881 for (i = istart; i < iafterend; i++) {
1882 double a = b;
1883 mesh.get_scoor(i + 1, b);
1884 s += (b - a) * y[i];
1885 }
1886 } else {
1887 for (i = istart; i < iafterend; i++) {
1888 double a = b;
1889 mesh.get_scoor(i + 1, b);
1890 s += 0.5 * (b * b - a * a) * y[i];
1891 }
1892 }
1893 //Iprintn(mcout, s);
1894
1895 //T t;
1896 return s;
1897
1898}
1899
1900/*
1901Generic integration.
1902fun can be modulating function - very convenient sometimes.
1903np is number of interval.
1904It can be used to obtain weight in a global array.
1905*/
1906template <class T, class D, class M>
1908 const D& y, // array of function values
1909 T (*fun)(long np, T xp1, T xp2, T yp, T xmin, T xmax,
1910 T x1, T x2),
1911 // This function should produce integral
1912 // form x1 to x2.
1913 T x1, T x2) {
1914 mfunname("double t_integ_step_ar(...)");
1915
1916 //mcout<<"start t_step_integ_ar\n";
1917 check_econd12(x1, >, x2, mcerr);
1918 long qi = mesh.get_qi();
1919 check_econd12(qi, <, 1, mcerr);
1920 //if(x1 > x2) return 0;
1921 double xmin = mesh.get_xmin();
1922 double xmax = mesh.get_xmax();
1923 if (x2 <= xmin) return 0;
1924 if (x1 >= xmax) return 0;
1925 if (x1 == x2) return 0;
1926 long istart, iafterend; // indexes to sum total intervals
1927 T s(0);
1928 if (x1 <= xmin) {
1929 x1 = xmin;
1930 istart = 0;
1931 } else {
1932 long n1, n2;
1933 T b1, b2;
1934 int i_ret = 0;
1935 i_ret = mesh.get_interval(x1, n1, b1, n2, b2);
1936 //Iprint2n(mcout, x1, i_ret);
1937 //Iprint4n(mcout, n1, b1, n2, b2);
1938 check_econd11(i_ret, != 1, mcerr);
1939 if (b2 - x1 > 0) // otherwise it could be only equal to 0
1940 {
1941 if (x2 <= b2) // if x2 in the same interval
1942 {
1943 s = fun(n1, b1, b2, y[n1], xmin, xmax, x1, x2);
1944 return s;
1945 }
1946 s = fun(n1, b1, b2, y[n1], xmin, xmax, x1, x2);
1947 }
1948 istart = n2;
1949 }
1950 if (x2 >= xmax) {
1951 x2 = xmax;
1952 iafterend = qi;
1953 } else {
1954 long n1, n2;
1955 T b1, b2;
1956 int i_ret = 0;
1957 i_ret = mesh.get_interval(x2, n1, b1, n2, b2);
1958 //Iprint2n(mcout, x2, i_ret);
1959 //Iprint4n(mcout, n1, b1, n2, b2);
1960 check_econd11(i_ret, != 1, mcerr);
1961 if (x2 - b1 > 0) {
1962 s += fun(n1, b1, b2, y[n1], xmin, xmax, b1, x2);
1963 }
1964 iafterend = n1;
1965 }
1966 //Iprint2n(mcout, istart, iafterend);
1967 long i;
1968 double b;
1969 mesh.get_scoor(istart, b);
1970 for (i = istart; i < iafterend; i++) {
1971 double a = b;
1972 mesh.get_scoor(i + 1, b);
1973 s += fun(i, a, b, y[i], xmin, xmax, a, b);
1974 }
1975 //Iprintn(mcout, s);
1976
1977 //T t;
1978 return s;
1979
1980}
1981
1982// simplified version for total integration along all the mesh
1983// It is without "power" as function above.
1984// So it is sum of functions multiplied by bin widths.
1985
1986template <class T, class D, class M>
1987T t_total_integ_step_ar(const M& mesh, const D& y // array of function values
1988 ) {
1989 mfunname("double t_total_integ_step_ar(...)");
1990
1991 //mcout<<"start t_step_integ_ar\n";
1992 long qi = mesh.get_qi();
1993 check_econd12(qi, <, 1, mcerr);
1994 //if(x1 > x2) return 0;
1995 long istart, iafterend; // indexes to sum total intervals
1996 T s(0);
1997 istart = 0;
1998 iafterend = qi;
1999 //Iprint2n(mcout, istart, iafterend);
2000 long i;
2001 double b;
2002 mesh.get_scoor(istart, b);
2003 for (i = istart; i < iafterend; i++) {
2004 double a = b;
2005 mesh.get_scoor(i + 1, b);
2006 s += (b - a) * y[i];
2007 }
2008
2009 //T t;
2010 return s;
2011
2012}
2013
2014// total integration of two dimensional array in both dimensions
2015
2016template <class T, class D, class M1, class M2>
2017T t_total_integ_step_ar(const M1& mesh1, const M2& mesh2,
2018 const D& y // array of function values
2019 ) {
2020 mfunname("double t_total_integ_step_ar(...)");
2021
2022 //mcout<<"start t_step_integ_ar\n";
2023 long qi1 = mesh1.get_qi();
2024 check_econd12(qi1, <, 1, mcerr);
2025 long qi2 = mesh2.get_qi();
2026 check_econd12(qi2, <, 1, mcerr);
2027 //if(x1 > x2) return 0;
2028 long istart1, iafterend1; // indexes to sum total intervals
2029 T s1(0);
2030 istart1 = 0;
2031 iafterend1 = qi1;
2032 //Iprint2n(mcout, istart, iafterend);
2033 long i1;
2034 double b1;
2035 mesh1.get_scoor(istart1, b1);
2036 for (i1 = istart1; i1 < iafterend1; i1++) {
2037 double a1 = b1;
2038 mesh1.get_scoor(i1 + 1, b1);
2039 // time to obtain integral by the second dimension
2040 //if(x1 > x2) return 0;
2041 long istart2, iafterend2; // indexes to sum total intervals
2042 T s2(0);
2043 istart2 = 0;
2044 iafterend2 = qi2;
2045 //Iprint2n(mcout, istart, iafterend);
2046 long i2;
2047 double b2;
2048 mesh2.get_scoor(istart2, b2);
2049 for (i2 = istart2; i2 < iafterend2; i2++) {
2050 double a2 = b2;
2051 mesh2.get_scoor(i2 + 1, b2);
2052 s2 += (b2 - a2) * y[i1][i2];
2053 }
2054 // OK, integral = s2
2055 s1 += (b1 - a1) * s2;
2056 }
2057
2058 //T t;
2059 return s1;
2060
2061}
2062
2063// Faster version adapted for DynArr
2064
2065template <class T, class M1, class M2>
2066T t_total_integ_step_ar(const M1& mesh1, const M2& mesh2,
2067 const DynArr<T>& y // array of function values
2068 ) {
2069 mfunname("double t_total_integ_step_ar(...)");
2070
2071 //mcout<<"start t_step_integ_ar\n";
2072 long qi1 = mesh1.get_qi();
2073 check_econd12(qi1, <, 1, mcerr);
2074 check_econd12(qi1, !=, y.get_qel()[0], mcerr);
2075 long qi2 = mesh2.get_qi();
2076 check_econd12(qi2, <, 1, mcerr);
2077 check_econd12(qi2, !=, y.get_qel()[1], mcerr);
2078 //if(x1 > x2) return 0;
2079 long istart1, iafterend1; // indexes to sum total intervals
2080 T s1(0);
2081 istart1 = 0;
2082 iafterend1 = qi1;
2083 //Iprint2n(mcout, istart, iafterend);
2084 long i1;
2085 double b1;
2086 mesh1.get_scoor(istart1, b1);
2087 for (i1 = istart1; i1 < iafterend1; i1++) {
2088 double a1 = b1;
2089 mesh1.get_scoor(i1 + 1, b1);
2090
2091 // time to obtain integral by the second dimension
2092
2093 //if(x1 > x2) return 0.0;
2094 long istart2, iafterend2; // indexes to sum total intervals
2095 T s2(0.0);
2096 istart2 = 0;
2097 iafterend2 = qi2;
2098 //Iprint2n(mcout, istart, iafterend);
2099 long i2;
2100 double b2;
2101 mesh2.get_scoor(istart2, b2);
2102 for (i2 = istart2; i2 < iafterend2; i2++) {
2103 double a2 = b2;
2104 mesh2.get_scoor(i2 + 1, b2);
2105 s2 += (b2 - a2) * y.acu(i1, i2);
2106 }
2107
2108 // OK, integral = s2
2109
2110 s1 += (b1 - a1) * s2;
2111 }
2112
2113 //T t;
2114 return s1;
2115
2116}
2117
2118/* Finds value x, such that the integral of y (rectangular bins)
2119is equal to integ.
2120*/
2121// This program is not fast enough for
2122// serial random number generation.
2123// For the last purpose it is more smart to integrate the array
2124// once. This program integrates it each time.
2125
2126template <class T, class D, class M>
2128 const D& y, // array of function values
2129 T integ, int* s_err) // for power = 0 only
2130 {
2131 mfunname("double t_integ_step_ar(...)");
2132
2133 *s_err = 0;
2134 //mcout<<"start t_step_integ_ar\n";
2135 //check_econd11(xpower , != 0 , mcerr);
2136 check_econd11(integ, < 0.0, mcerr);
2137 long qi = mesh.get_qi();
2138 check_econd12(qi, <, 1, mcerr);
2139 //if(x1 > x2) return 0.0;
2140 double xmin = mesh.get_xmin();
2141 double xmax = mesh.get_xmax();
2142 if (integ == 0.0) return xmin;
2143 T s(0.0);
2144 long n = 0;
2145 T xp1(0.0);
2146 T xp2(0.0);
2147 mesh.get_scoor(n, xp2);
2148 for (n = 0; n < qi; n++) {
2149 xp1 = xp2;
2150 mesh.get_scoor(n + 1, xp2);
2151 T step = xp2 - xp1;
2152 T s1 = s + y[n] * step;
2153 //Iprint3n(mcout, n, s1, integ);
2154 if (s1 > integ) break;
2155 if (s1 == integ) return xp2;
2156 s = s1;
2157 }
2158
2159 if (n == qi) {
2160 *s_err = 1;
2161 return xmax;
2162 }
2163 double x = xp1;
2164 //Iprint3n(mcout, n, s, x);
2165 x += (integ - s) / y[n];
2166 //Iprintn(mcout, x);
2167 return x;
2168}
2169
2170// The following program the same as previous, but
2171// considers the array already integrated.
2172// The algorithm is then much faster, since it uses binary search.
2173// It is used, in particular, for random numbers generation.
2174
2175template <class T, class D, class M>
2177 const D& y, // array of function values
2178 T integ, int* s_err) // for power = 0 only
2179 {
2180 mfunname("double t_find_x_for_already_integ_step_ar(...)");
2181
2182 *s_err = 0;
2183 //mcout<<"start t_step_integ_ar\n";
2184 //check_econd11(xpower , != 0 , mcerr);
2185 check_econd11(integ, < 0.0, mcerr);
2186 long qi = mesh.get_qi();
2187 check_econd12(qi, <, 1, mcerr);
2188 //if(x1 > x2) return 0.0;
2189 double xmin = mesh.get_xmin();
2190 double xmax = mesh.get_xmax();
2191 if (integ == 0.0) return xmin;
2192 if (integ > y[qi - 1]) {
2193 *s_err = 1;
2194 return xmax;
2195 }
2196 if (integ == y[qi - 1]) return xmax;
2197 if (integ < y[0]) { // answer in the first bin
2198 T xp1(0.0);
2199 T xp2(0.0);
2200 mesh.get_scoor(0, xp1);
2201 mesh.get_scoor(1, xp2);
2202 return xp1 + (xp2 - xp1) * integ / y[0];
2203 }
2204 // binary search
2205 long nl = 0;
2206 long nr = qi - 1;
2207 long nc;
2208 while (nr - nl > 1) {
2209 nc = (nr + nl) / 2;
2210 if (integ < y[nc])
2211 nr = nc;
2212 else
2213 nl = nc;
2214 }
2215 //Iprint2n(mcout, nl, nr);
2216 T xl(0.0);
2217 T xr(0.0);
2218 mesh.get_scoor(nl + 1, xl);
2219 mesh.get_scoor(nr + 1, xr);
2220 // Note "+1" in the previous two expressions.
2221 // This arises from the fact that the nl'th element of
2222 // y-array contains integral of nl'th bin plus all previous bins.
2223 // So y[nl] is related to x of nl+1.
2224 T a = (xr - xl) / (y[nr] - y[nl]);
2225 T ret = xl + a * (integ - y[nl]);
2226
2227 return ret;
2228}
2229
2230// The same as previous, but return entire number, faster.
2231// Mesh should be entire too.
2232// In the contrary to the previous function
2233// y is interpreted here as y[i] is sum from 0 to y[i].
2234// Not to y[i+1], as for smooth case.
2235// But "+1" is persisting anyway.
2236// For example, if gamma is between the first (n=0) and second (n=1)
2237// bins by prob.density, then the solution is the second bin (n=1),
2238// not the first as one could think naively!
2239
2240template <class T, class D, class M>
2242 const M& mesh, const D& y, // array of function values
2243 T integ, int* s_err) // for power = 0 only
2244 {
2245 mfunname("double t_find_entire_x_for_already_integ_step_ar(...)");
2246 //Iprintn(mcout, mesh);
2247 //Iprintn(mcout, integ);
2248 *s_err = 0;
2249 //mcout<<"start t_step_integ_ar\n";
2250 //check_econd11(xpower , != 0 , mcerr);
2251 check_econd11(integ, < 0.0, mcerr);
2252 long qi = mesh.get_qi();
2253 check_econd12(qi, <, 1, mcerr);
2254 //if(x1 > x2) return 0.0;
2255 long xmin = mesh.get_xmin();
2256 long xmax = mesh.get_xmax();
2257 if (integ == 0) return xmin;
2258 if (integ > y[qi - 1]) {
2259 *s_err = 1;
2260 return xmax;
2261 }
2262 if (integ == y[qi - 1]) return xmax;
2263 if (integ < y[0]) { // answer in the first bin
2264 long xp1(0);
2265 mesh.get_scoor(0, xp1);
2266 return xp1;
2267 }
2268 // binary search
2269 long nl = 0;
2270 long nr = qi - 1;
2271 long nc;
2272 while (nr - nl > 1) {
2273 nc = (nr + nl) / 2;
2274 if (integ < y[nc])
2275 nr = nc;
2276 else
2277 nl = nc;
2278 }
2279 //Iprint2n(mcout, nl, nr);
2280 //Iprint2n(mcout, y[nl], y[nr]);
2281 //Iprint2n(mcout, nl, nr);
2282 long x(0);
2283 mesh.get_scoor(nr, x);
2284 //Iprintn(mcout, x);
2285
2286 return x;
2287}
2288
2289// prepare histogram for generation of the random numbers
2290// return integral
2291// initialize probability density function
2292// y and integ_y can point to the same array
2293
2294template <class T, class D, class M>
2295T t_hispre_step_ar(const M& mesh, const D& y, // array of function values
2296 D& integ_y // return integrated array
2297 ) {
2298 mfunname("double t_hispre_step_ar(...)");
2299
2300 //mcout<<"start t_step_integ_ar\n";
2301 //check_econd11(xpower , != 0 , mcerr);
2302 long qi = mesh.get_qi();
2303 check_econd12(qi, <, 1, mcerr);
2304
2305 T s(0.0);
2306 long n = 0;
2307 T xp1(0.0);
2308 T xp2(0.0);
2309 mesh.get_scoor(n, xp2);
2310 for (n = 0; n < qi; n++) {
2311 xp1 = xp2;
2312 mesh.get_scoor(n + 1, xp2);
2313 T step = xp2 - xp1;
2314 check_econd11a(y[n], < 0.0,
2315 "n=" << n << " xp1=" << xp1 << " xp2=" << xp2 << '\n',
2316 mcerr);
2317 s = s + y[n] * step;
2318 integ_y[n] = s;
2319 //Iprint3n(mcout, n, s1, integ);
2320 }
2321 check_econd11a(s, <= 0.0, "y=" << y << " integ_y=" << integ_y << '\n', mcerr);
2322 for (n = 0; n < qi; n++) {
2323 integ_y[n] /= s;
2324 }
2325 return s;
2326}
2327
2328// generate random number
2329
2330template <class T, class D, class M>
2331T t_hisran_step_ar(const M& mesh, const D& integ_y, T rannum) {
2332 mfunname("double t_hisran_step_ar(...)");
2333 //mcout<<"start t_step_integ_ar\n";
2334 //check_econd11(xpower , != 0 , mcerr);
2335 long qi = mesh.get_qi();
2336 long s_same = apeq_mant(integ_y[qi - 1], 1.0, 1.0e-12);
2337 check_econd11a(s_same, != 1.0, "integ_y[qi-1]=" << integ_y[qi - 1] << '\n',
2338 mcerr);
2339
2340 //Iprintn(mcout, rannum);
2341 //check_econd11(integ_y[qi-1] , != 1.0 , mcerr);
2342 int s_err;
2343
2344 T ret = t_find_x_for_already_integ_step_ar(mesh, // dimension q
2345 integ_y, // dimension q-1
2346 rannum, &s_err);
2347 check_econd11a(s_err, != 0, "mesh=" << mesh << " integ_y=" << integ_y
2348 << " rannum=" << rannum << '\n',
2349 mcerr);
2350 return ret;
2351 //return t_find_x_for_already_integ_step_ar
2352 // (mesh, // dimension q
2353 // integ_y, // dimension q-1
2354 // rannum,
2355 // &s_err);
2356}
2357
2358// opposite to generate random number: find integral probability
2359// for a certain absciss
2360
2361template <class T, class D, class M>
2362T t_opposite_hisran_step_ar(const M& mesh, const D& integ_y, T x) {
2363 mfunname("double t_opposite_hisran_step_ar(...)");
2364
2365 //mcout<<"start t_step_integ_ar\n";
2366 //check_econd11(xpower , != 0 , mcerr);
2367 long qi = mesh.get_qi();
2368 long s_same = apeq_mant(integ_y[qi - 1], 1.0, 1.0e-12);
2369 check_econd11a(s_same, != 1.0, "integ_y[qi-1]=" << integ_y[qi - 1] << '\n',
2370 mcerr);
2371
2372 long n1;
2373 T b1;
2374 long n2;
2375 T b2;
2376
2377 mesh.get_interval_extrap(x, n1, b1, n2, b2);
2378 T y1;
2379 T y2;
2380 if (n1 == 0) {
2381 y1 = 0.0;
2382 y2 = integ_y[0];
2383 } else {
2384 y1 = integ_y[n1 - 1];
2385 y2 = integ_y[n2 - 1];
2386 }
2387 T res = y1 + ((y2 - y1) / (b2 - b1)) * (x - b1);
2388 return res;
2389}
2390
2391// generate entire random number
2392
2393template <class T, class D, class M>
2394long t_entire_hisran_step_ar(const M& mesh, const D& integ_y, T rannum) {
2395 mfunname("double t_entire_hisran_step_ar(...)");
2396
2397 //mcout<<"start t_step_integ_ar\n";
2398 //check_econd11(xpower , != 0 , mcerr);
2399 long qi = mesh.get_qi();
2400 long s_same = apeq_mant(integ_y[qi - 1], 1.0, 1.0e-12);
2401 check_econd11a(s_same, != 1.0, "integ_y[qi-1]=" << integ_y[qi - 1] << '\n',
2402 mcerr);
2403 //check_econd11(integ_y[qi-1] , != 1.0 , mcerr);
2404 int s_err;
2405
2406 long ret =
2408 integ_y, // dimension q-1
2409 rannum, &s_err);
2410 check_econd11a(s_err, != 0, "mesh=" << mesh << " integ_y=" << integ_y
2411 << " rannum=" << rannum << '\n',
2412 mcerr);
2413 return ret;
2414 //return t_find_entire_x_for_already_integ_step_ar
2415 // (mesh, // dimension q
2416 // integ_y, // dimension q-1
2417 // rannum,
2418 // &s_err);
2419}
2420
2421/*
2422This is mean of "step array".
2423*/
2424template <class T, class D, class M>
2425T t_mean_step_ar(const M& mesh, const D& y, // array of function values
2426 T x1, T x2, int& s_err) {
2427 mfunname("double t_mean_step_ar(...)");
2428 s_err = 0;
2429 T integ = t_integ_step_ar(mesh, y, x1, x2, 0);
2430 if (integ == 0) {
2431 s_err = 1;
2432 return 0.0;
2433 }
2434 T xinteg = t_integ_step_ar(mesh, y, x1, x2, 1);
2435 return xinteg / integ;
2436}
2437
2438template <class T>
2439T t_value_straight_2point(T x1, T y1, T x2, T y2, T x, int s_ban_neg) {
2440 mfunname("double t_value_straight_2point(...)");
2441 check_econd12(x1, ==, x2, mcerr);
2442
2443 T a = (y2 - y1) / (x2 - x1);
2444 // Less numerical precision
2445 //T b = y[n1];
2446 //T res = a * ( x - x1) + b;
2447 // More numerical precision (although it is not proved),
2448 // starting from what is closer to x
2449 T res;
2450 T dx1 = x - x1;
2451 T adx1 = (dx1 > 0) ? dx1 : -dx1; // absolute value
2452 //if(dx1 > 0)
2453 // adx1 = dx1;
2454 //else
2455 // adx1 = -dx1;
2456 T dx2 = x - x2;
2457 T adx2 = (dx2 > 0) ? dx2 : -dx2; // absolute value
2458 //if(dx2 > 0)
2459 // adx2 = dx2;
2460 //else
2461 // adx2 = -dx2;
2462 if (adx1 < adx2) // x is closer to x1
2463 {
2464 res = a * dx1 + y1;
2465 } else {
2466 res = a * dx2 + y2;
2467 }
2468 if (s_ban_neg == 1 && res < 0.0) res = 0.0;
2469 return res;
2470}
2471
2472template <class T>
2473T t_integ_straight_2point(T x1, T y1, T x2, T y2, T xl, T xr,
2474 int xpower, // currently 0 or 1
2475 int s_ban_neg)
2476 // 0 - not include, 1 - include
2477 {
2478 mfunname("double t_integ_straight_2point(...)");
2479 check_econd12(x1, ==, x2, mcerr);
2480
2481 T a = (y2 - y1) / (x2 - x1);
2482 T b = y1;
2483 T yl = a * (xl - x1) + b;
2484 T yr = a * (xr - x1) + b;
2485 if (s_ban_neg == 1) {
2486 if (yl <= 0.0 && yr <= 0.0) return 0.0;
2487 if (yl < 0.0 || yr < 0.0) {
2488 T xz = x1 - b / a;
2489 if (yl < 0.0) {
2490 xl = xz;
2491 yl = 0.0;
2492 } else {
2493 xr = xz;
2494 yr = 0.0;
2495 }
2496 }
2497 }
2498 T res;
2499 if (xpower == 0)
2500 res = 0.5 * a * (xr * xr - xl * xl) + (b - a * x1) * (xr - xl);
2501 else
2502 res = a * (xr * xr * xr - xl * xl * xl) / 3.0 +
2503 0.5 * (b - a * x1) * (xr * xr - xl * xl);
2504
2505 return res;
2506}
2507
2508// Extract value defined by this array for abscissa x
2509// y have dimension q or qi+1.
2510template <class T, class D, class M>
2512 const D& y, // array of function values
2513 T x, int s_ban_neg, int s_extrap_left, T left_bond,
2514 int s_extrap_right, T right_bond) {
2515 // 0 - not include, 1 - include
2516 mfunname("double t_value_straight_point_ar(...)");
2517 double xmin = mesh.get_xmin();
2518 double xmax = mesh.get_xmax();
2519 //Iprint3n(mcout, x, xmin, xmax);
2520 if (x < left_bond) return 0.0;
2521 if (x > right_bond) return 0.0;
2522 if (x < xmin && s_extrap_left == 0) return 0.0;
2523 if (x > xmax && s_extrap_right == 0) return 0.0;
2524 long n1, n2;
2525 T b1, b2;
2526 mesh.get_interval_extrap(x, n1, b1, n2, b2);
2527 T x1;
2528 mesh.get_scoor(n1, x1);
2529 T x2;
2530 mesh.get_scoor(n2, x2);
2531 return t_value_straight_2point(x1, y[n1], x2, y[n2], x, s_ban_neg);
2532 /*
2533 T a = (y[n2] - y[n1])/(x2 - x1);
2534 // Less numerical precision
2535 //T b = y[n1];
2536 //T res = a * ( x - x1) + b;
2537 // More numerical precision (although it is not proved),
2538 // starting from what is closer to x
2539 T res;
2540 T dx1 = x - x1;
2541 T adx1 = (dx1 > 0) ? dx1 : -dx1; // absolute value
2542 //if(dx1 > 0)
2543 // adx1 = dx1;
2544 //else
2545 // adx1 = -dx1;
2546 T dx2 = x - x2;
2547 T adx2 = (dx2 > 0) ? dx2 : -dx2; // absolute value
2548 //if(dx2 > 0)
2549 // adx2 = dx2;
2550 //else
2551 // adx2 = -dx2;
2552 if(adx1 < adx2) // x is closer to x1
2553 {
2554 res = a * dx1 + y[n1];
2555 }
2556 else
2557 {
2558 res = a * dx2 + y[n2];
2559 }
2560 //T res = a * ( x - x1) + b;
2561 if(s_ban_neg == 1 && res < 0.0) res = 0.0;
2562 //Iprint2n(mcout, x, res);
2563 //Iprint2n(mcout, x1, x2);
2564 //Iprint2n(mcout, y[n1], y[n2]);
2565 //Iprintn(mcout, a);
2566 return res;
2567 */
2568}
2569
2570// Extract value defined by this array for abscissa x
2571template <class T, class D, class M>
2573 const M& mesh, const D& y, // array of function values
2574 T (*funval)(T xp1, T yp1, T xp2, T yp2, T xmin,
2575 T xmax, // may be necessary for shape determination
2576 T x),
2577 T x, int s_extrap_left, T left_bond, int s_extrap_right, T right_bond) {
2578 // 0 - not include, 1 - include
2579 mfunname("double t_value_generic_point_ar(...)");
2580 double xmin = mesh.get_xmin();
2581 double xmax = mesh.get_xmax();
2582 //Iprint3n(mcout, x, xmin, xmax);
2583 if (x < left_bond) return 0.0;
2584 if (x > right_bond) return 0.0;
2585 if (x < xmin && s_extrap_left == 0) return 0.0;
2586 if (x > xmax && s_extrap_right == 0) return 0.0;
2587 long n1, n2;
2588 T b1, b2;
2589 mesh.get_interval_extrap(x, n1, b1, n2, b2);
2590 T x1;
2591 mesh.get_scoor(n1, x1);
2592 T x2;
2593 mesh.get_scoor(n2, x2);
2594 return funval(x1, y[n1], x2, y[n2], left_bond, right_bond, x);
2595}
2596
2597// power function x^pw
2598
2599// not debugged
2600// No, perhaps already checked in some application.
2601// If power function cannot be drawn, it exits.
2602
2603template <class T> T t_value_power_2point(T x1, T y1, T x2, T y2, T x) {
2604 mfunname("double t_value_power_2point(...)");
2605
2606 check_econd11(y1, <= 0.0, mcerr);
2607 check_econd11(y2, <= 0.0, mcerr);
2608 check_econd12(y1, ==, y2, mcerr);
2609 check_econd12(x1, ==, x2, mcerr);
2610 T res = y1;
2611 if (x1 <= 0.0 && x2 >= 0.0) {
2612 mcerr << "T t_value_power_2point(...): \n";
2613 mcerr << "x's are of different sign, power cannot be drawn\n";
2614 spexit(mcerr);
2615 } else {
2616 T pw = log(y1 / y2) / log(x1 / x2);
2617 //check_econd11(pw , == -1.0 , mcerr);
2618 res = y1 * pow(x, pw) / pow(x1, pw);
2619 }
2620 return res;
2621}
2622
2623// in the case of zero of different signs of x it uses linear interpolation
2624template <class T>
2625T t_value_power_extended_2point(T x1, T y1, T x2, T y2, T x) {
2626 mfunname("double t_value_power_2point(...)");
2627
2628 check_econd11(y1, <= 0.0, mcerr);
2629 check_econd11(y2, <= 0.0, mcerr);
2630 check_econd12(y1, ==, y2, mcerr);
2631 check_econd12(x1, ==, x2, mcerr);
2632 T res;
2633 if (x1 <= 0.0 && x2 >= 0.0) {
2634 res = y1 + (x - x1) * (y2 - y1) / (x2 - x1);
2635 } else {
2636 T pw = log(y1 / y2) / log(x1 / x2);
2637 //check_econd11(pw , == -1.0 , mcerr);
2638 res = y1 * pow(x, pw) / pow(x1, pw);
2639 }
2640 return res;
2641}
2642
2643template <class T> T t_value_exp_2point(T x1, T y1, T x2, T y2, T x) {
2644 mfunname("double t_value_exp_2point(...)");
2645
2646 check_econd11(y1, <= 0.0, mcerr);
2647 check_econd11(y2, <= 0.0, mcerr);
2648 check_econd12(y1, ==, y2, mcerr);
2649 check_econd12(x1, ==, x2, mcerr);
2650 T res;
2651
2652 T a = log(y1 / y2) / (x1 - x2);
2653 T c = y1 / exp(a * x1);
2654 //check_econd11(pw , == -1.0 , mcerr);
2655 res = c * exp(a * x);
2656 ;
2657 return res;
2658}
2659
2660template <class T>
2661T t_integ_power_2point(T x1, T y1, T x2, T y2, T xl, T xr)
2662 // 0 - not include, 1 - include
2663 {
2664 mfunname("double t_integ_power_2point(...)");
2665
2666 check_econd11(y1, <= 0.0, mcerr);
2667 check_econd11(y2, <= 0.0, mcerr);
2668 check_econd12(y1, ==, y2, mcerr);
2669 check_econd12(x1, ==, x2, mcerr);
2670 T pw = log(y1 / y2) / log(x1 / x2);
2671 check_econd11(pw, == -1.0, mcerr);
2672 T k = y1 * pow(x1, -pw);
2673 T t = k / (1 + pw) * (pow(xr, (pw + 1)) - pow(xl, (pw + 1)));
2674 return t;
2675}
2676
2677template <class T, class D, class M>
2679 const D& y, // array of function values
2680 T x1, T x2, // intervals of integration
2681 int xpower, // currently 0 or 1
2682 int s_ban_neg, int s_extrap_left, T left_bond,
2683 int s_extrap_right, T right_bond) {
2684 mfunname("double t_integ_straight_point_ar(...)");
2685
2686 //mcout<<"Strart t_integ_straight_point_ar\n";
2687 check_econd21(xpower, != 0 &&, != 1, mcerr);
2688 check_econd12(x1, >, x2, mcerr);
2689 long qi = mesh.get_qi();
2690 check_econd12(qi, <, 1, mcerr);
2691 //if(x1 > x2) return 0.0;
2692 double xmin = mesh.get_xmin();
2693 double xmax = mesh.get_xmax();
2694 if (x2 <= xmin && s_extrap_left == 0) return 0.0;
2695 if (x1 >= xmax && s_extrap_right == 0) return 0.0;
2696 if (x2 <= left_bond) return 0.0;
2697 if (x1 >= right_bond) return 0.0;
2698 T s(0.0);
2699 if (x1 < left_bond) x1 = left_bond;
2700 if (x2 > right_bond) x2 = right_bond;
2701 if (x1 <= xmin && s_extrap_left == 0) x1 = xmin;
2702 if (x2 > xmax && s_extrap_left == 0) x2 = xmax;
2703 long np1, np2;
2704 T bp1, bp2;
2705 int i_ret = 0;
2706 // restore the interval in which x1 reside
2707 i_ret = mesh.get_interval_extrap(x1, np1, bp1, np2, bp2);
2708 // restore the x-coordinates of given points
2709 T xp1;
2710 mesh.get_scoor(np1, xp1);
2711 T xp2;
2712 mesh.get_scoor(np2, xp2);
2713 T res;
2714 T yp1 = y[np1];
2715 T yp2 = y[np2];
2716 if (i_ret == 2 || x2 <= xp2) // then all in one interval
2717 {
2718 res = t_integ_straight_2point<T>(xp1, yp1, xp2, yp2, x1, x2, xpower,
2719 s_ban_neg);
2720 } else {
2721 // integrate only till end of the current interval
2722 T x1i = x1;
2723 T x2i = xp2;
2724 res = t_integ_straight_2point<T>(xp1, yp1, xp2, yp2, x1i, x2i, xpower,
2725 s_ban_neg);
2726 //x2i = x1; // prepere for loop
2727 int s_stop = 0;
2728 do {
2729 np1 = np2;
2730 np2++;
2731 xp1 = xp2;
2732 mesh.get_scoor(np2, xp2);
2733 x1i = x2i;
2734 if (xp2 >= x2) {
2735 x2i = x2; // till end of integral
2736 s_stop = 1;
2737 } else {
2738 if (np2 == qi) // end of the mesh, but x2 is farther
2739 {
2740 x2i = x2; // till end of integral
2741 s_stop = 1;
2742 } else {
2743 x2i = xp2; // till end of current interval
2744 s_stop = 0;
2745 }
2746 }
2747 yp1 = yp2;
2748 yp2 = y[np2];
2749 res += t_integ_straight_2point<T>(xp1, yp1, xp2, yp2, x1i, x2i, xpower,
2750 s_ban_neg);
2751 //Iprint2n(mcout, xp1, xp2);
2752 //Iprint2n(mcout, x1i, x2i);
2753 //Iprint2n(mcout, yp1, yp2);
2754 //Iprint2n(mcout, res, s_stop);
2755
2756 } while (s_stop == 0);
2757 }
2758 return res;
2759}
2760
2761template <class T, class D, class M>
2763 const D& y, // array of function values
2764 T x1, T x2, int s_extrap_left, T left_bond,
2765 int s_extrap_right, T right_bond, int& s_err) {
2766 mfunname("double t_mean_straight_point_ar(...)");
2767 s_err = 0;
2768 T integ = t_integ_straight_point_ar(mesh, y, x1, x2, 0, 1, s_extrap_left,
2769 left_bond, s_extrap_right, right_bond);
2770 if (integ == 0) {
2771 s_err = 1;
2772 return 0.0;
2773 }
2774 T xinteg = t_integ_straight_point_ar(mesh, y, x1, x2, 1, 1, s_extrap_left,
2775 left_bond, s_extrap_right, right_bond);
2776 return xinteg / integ;
2777}
2778
2779//template<class T>
2780//typedef T(*GENERICFUN)(T xp1, T yp1, T xp2, T yp2,
2781// T xmin, T xmax, T x1, T x2);
2782//typedef T(*GENERICFUN)(T, T, T, T,
2783// T, T, T, T);
2784
2785template <class T, class D, class M>
2787 const M& mesh, const D& y, // array of function values
2788 //GENERICFUN fun,
2789 T (*fun)(T xp1, T yp1, T xp2, T yp2, T xmin, T xmax, T x1, T x2), T x1,
2790 T x2, int s_extrap_left, T left_bond, int s_extrap_right, T right_bond) {
2791 mfunname("double t_integ_generic_point_ar(...)");
2792
2793 //mcout<<"Strart t_integ_straight_point_ar\n";
2794 //check_econd21(xpower , != 0 && , != 1 , mcerr);
2795 check_econd12(x1, >, x2, mcerr);
2796 long qi = mesh.get_qi();
2797 check_econd12(qi, <, 1, mcerr);
2798 //if(x1 > x2) return 0.0;
2799 double xmin = mesh.get_xmin();
2800 double xmax = mesh.get_xmax();
2801 if (x2 <= xmin && s_extrap_left == 0) return 0.0;
2802 if (x1 >= xmax && s_extrap_right == 0) return 0.0;
2803 if (x2 <= left_bond) return 0.0;
2804 if (x1 >= right_bond) return 0.0;
2805 // long istart, iafterend; // indexes to sum total intervals
2806 if (x1 < left_bond) x1 = left_bond;
2807 if (x2 > right_bond) x2 = right_bond;
2808 if (x1 <= xmin && s_extrap_left == 0) x1 = xmin;
2809 if (x2 > xmax && s_extrap_left == 0) x2 = xmax;
2810 long np1, np2;
2811 T bp1, bp2;
2812 int i_ret = 0;
2813 // restore the interval in which x1 reside
2814 i_ret = mesh.get_interval_extrap(x1, np1, bp1, np2, bp2);
2815 // restore the x-coordinates of given points
2816 T xp1;
2817 mesh.get_scoor(np1, xp1);
2818 T xp2;
2819 mesh.get_scoor(np2, xp2);
2820 T res;
2821 T yp1 = y[np1];
2822 T yp2 = y[np2];
2823 if (i_ret == 2 || x2 <= xp2) // then all in one interval
2824 {
2825 res = fun(xp1, yp1, xp2, yp2, xmin, xmax, x1, x2);
2826 } else {
2827 // integrate only till end of the current interval
2828 T x1i = x1;
2829 T x2i = xp2;
2830 res = fun(xp1, yp1, xp2, yp2, xmin, xmax, x1i, x2i);
2831 //x2i = x1; // prepere for loop
2832 int s_stop = 0;
2833 do {
2834 np1 = np2;
2835 np2++;
2836 xp1 = xp2;
2837 mesh.get_scoor(np2, xp2);
2838 x1i = x2i;
2839 if (xp2 >= x2) {
2840 x2i = x2; // till end of integral
2841 s_stop = 1;
2842 } else {
2843 if (np2 == qi) // end of the mesh, but x2 is farther
2844 {
2845 x2i = x2; // till end of integral
2846 s_stop = 1;
2847 } else {
2848 x2i = xp2; // till end of current interval
2849 s_stop = 0;
2850 }
2851 }
2852 yp1 = yp2;
2853 yp2 = y[np2];
2854 res += fun(xp1, yp1, xp2, yp2, xmin, xmax, x1i, x2i);
2855 //Iprint2n(mcout, xp1, xp2);
2856 //Iprint2n(mcout, x1i, x2i);
2857 //Iprint2n(mcout, yp1, yp2);
2858 //Iprint2n(mcout, res, s_stop);
2859
2860 } while (s_stop == 0);
2861 }
2862 return res;
2863}
2864
2865// find width at half-height of a histogram
2866// doing straight line interpolation between centers of the bins
2867//(like straight_point_ar).
2868// But the mesh is understood as a range of the left points.
2869// if there are several maximal bin with the same height
2870// it will decline from the first one, which might be
2871// not accurate, although the result is anyway reasonable.
2872
2873template <class T, class D, class M>
2874T t_width_at_hheight_step_ar(const M& mesh, const D& y) {
2875 // 0 - not include, 1 - include
2876 mfunname("double t_width_at_hheight_step_ar(...)");
2877 //mcout<<"t_width_at_hheight_step_ar is started\n";
2878 long qi = mesh.get_qi();
2879 long n;
2880 T ymax = 0;
2881 long nmax;
2882 for (n = 0; n < qi; ++n) {
2883 if (y[n] > ymax) {
2884 check_econd11(y[n], < 0.0, mcerr);
2885 ymax = y[n];
2886 nmax = n;
2887 }
2888 }
2889 //Iprint2n(mcout, ymax, nmax);
2890 if (ymax == 0) return 0;
2891 T ylev = ymax / 2.0;
2892 T s2 = 0;
2893 long q = 0;
2894 for (n = nmax; n < qi; n++) {
2895
2896 if (y[n] > ylev && y[n + 1] <= ylev) {
2897 T x1, x2;
2898 mesh.get_interval(n, x1, x2);
2899 T step1, step2;
2900 mesh.get_step(n, step1);
2901 mesh.get_step(n + 1, step2);
2902 step1 = step1 / 2.0;
2903 step2 = step2 / 2.0;
2904 s2 += t_value_straight_2point(y[n], x1 + step1, y[n + 1], x2 + step2,
2905 ylev, 0);
2906 //Iprint2n(mcout, x1, x2);
2907 //Iprint2n(mcout, x1+step1, x2+step2);
2908 //Iprint2n(mcout, y[n], y[n+1]);
2909 //Iprint2n(mcout, n, t_value_straight_2point(y[n], x1+step1, y[n+1],
2910 //x2+step2, ylev, 0));
2911 q++;
2912 }
2913 }
2914 check_econd11(q, <= 0, mcerr);
2915 s2 = s2 / q;
2916 T s1 = 0;
2917 q = 0;
2918 for (n = nmax; n >= 0; n--) {
2919 if (y[n] > ylev && y[n - 1] <= ylev) {
2920 T x1, x2;
2921 mesh.get_interval(n - 1, x1, x2);
2922 T step1, step2;
2923 mesh.get_step(n - 1, step1);
2924 mesh.get_step(n, step2);
2925 step1 = step1 / 2.0;
2926 step2 = step2 / 2.0;
2927 s1 += t_value_straight_2point(y[n - 1], x1 + step1, y[n], x2 + step2,
2928 ylev, 0);
2929 //Iprint2n(mcout, x1, x2);
2930 //Iprint2n(mcout, x1+step1, x2+step2);
2931 //Iprint2n(mcout, y[n-1], y[n]);
2932 //Iprint2n(mcout, n, t_value_straight_2point(y[n-1], x1+step1, y[n],
2933 //x2+step2, ylev, 0));
2934 q++;
2935 }
2936 }
2937 check_econd11(q, <= 0, mcerr);
2938 s1 = s1 / q;
2939 //Iprint3n(mcout, s1, s2, s2 - s1);
2940 return s2 - s1;
2941}
2942
2943#endif
void(* fun)(T &f))
Definition: AbsArr.h:591
@ dont_clone
Definition: AbsPtr.h:519
DoubleAc pow(const DoubleAc &f, double p)
Definition: DoubleAc.cpp:336
DoubleAc exp(const DoubleAc &f)
Definition: DoubleAc.cpp:376
#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream)
Definition: FunNameStack.h:428
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:366
#define check_econd11a(a, signb, add, stream)
Definition: FunNameStack.h:395
#define check_econd24(a1, sign1, b1, sign0, a2, sign2, b2, stream)
Definition: FunNameStack.h:462
#define mfunnamep(string)
Definition: FunNameStack.h:77
#define spexit(stream)
Definition: FunNameStack.h:536
#define check_econd12(a, sign, b, stream)
Definition: FunNameStack.h:380
#define mfunname(string)
Definition: FunNameStack.h:67
macro_copy_total_zero(AbsCoorMesh< T >)
virtual int get_interval(T x, long &n1) const =0
virtual T get_xmax(void) const =0
virtual int get_interval_extrap(T x, long &n1, T &b1, long &n2, T &b2) const =0
virtual int operator==(const AbsCoorMesh< T > &)
Definition: tline.h:1240
virtual int get_interval(T x, long &n1, T &b1, long &n2, T &b2) const =0
virtual int get_interval(long n, T &b1, T &b2) const =0
virtual void print(std::ostream &file) const
Definition: tline.h:1232
virtual long get_qi(void) const =0
virtual int apeq_mant(const AbsCoorMesh< T > &, T)
Definition: tline.h:1260
virtual T get_xmin(void) const =0
virtual ~AbsCoorMesh()
Definition: tline.h:1237
virtual void get_scoor(long n, T &b) const =0
virtual int operator!=(const AbsCoorMesh< T > &)
Definition: tline.h:1250
virtual int get_step(long n, T &fstep) const =0
void get_scoor(long n, T &b) const
Definition: tline.h:767
int get_step(long n, T &fstep) const
Definition: tline.h:795
const DynLinArr< T > & get_mesh(void) const
Definition: tline.h:766
int get_interval(long n, T &b1, T &b2) const
Definition: tline.h:775
long get_qi(void) const
Definition: tline.h:763
int get_interval_extrap(T x, long &n1, T &b1, long &n2, T &b2) const
Definition: tline.h:1031
void print(std::ostream &file) const
Definition: tline.h:1096
T get_xmax(void) const
Definition: tline.h:765
CopiedPointCoorMesh(void)
Definition: tline.h:803
T get_xmin(void) const
Definition: tline.h:764
CopiedPointCoorMesh< T > & operator=(const CopiedPointCoorMesh< T > &f)
Definition: tline.h:827
T & acu(long i1)
Definition: AbsArr.h:2098
const DynLinArr< long > & get_qel(void) const
Definition: AbsArr.h:2548
void print(std::ostream &file) const
Definition: tline.h:248
virtual int get_interval_extrap(T x, long &n1, T &b1, long &n2, T &b2) const
Definition: tline.h:205
int get_step(long n, T &fstep) const
Definition: tline.h:96
void get_scoor(long n, T &b) const
Definition: tline.h:70
long get_qi(void) const
Definition: tline.h:62
T get_xmin(void) const
Definition: tline.h:65
EqualStepCoorMesh(void)
Definition: tline.h:102
int get_interval(long n, T &b1, T &b2) const
Definition: tline.h:72
T get_xmax(void) const
Definition: tline.h:66
int get_interval_extrap(T x, long &n1, T &b1, long &n2, T &b2) const
Definition: tline.h:650
void get_scoor(long n, T &b) const
Definition: tline.h:431
virtual void print(std::ostream &file) const
Definition: tline.h:715
virtual int get_interval(long n, T &b1, T &b2) const
Definition: tline.h:439
int get_step(long n, T &fstep) const
Definition: tline.h:457
void check(void)
Definition: tline.h:546
long get_qi(void) const
Definition: tline.h:428
T get_xmax(void) const
Definition: tline.h:430
PointCoorMesh(void)
Definition: tline.h:465
T get_xmin(void) const
Definition: tline.h:429
virtual int operator==(const AbsCoorMesh< T > &m2)
Definition: tline.h:1470
virtual int get_interval(T x, long &n1) const
Definition: tline.h:1428
macro_copy_total(VirtCopiedPointCoorMesh< T >)
virtual int get_interval_extrap(T x, long &n1, T &b1, long &n2, T &b2) const
Definition: tline.h:1442
virtual long get_qi(void) const
Definition: tline.h:1414
virtual void print(std::ostream &file) const
Definition: tline.h:1460
virtual int get_interval(long n, T &b1, T &b2) const
Definition: tline.h:1424
virtual T get_xmin(void) const
Definition: tline.h:1415
virtual int apeq_mant(const AbsCoorMesh< T > &m2, T prec)
Definition: tline.h:1487
virtual void get_scoor(long n, T &b) const
Definition: tline.h:1420
virtual int get_interval(T x, long &n1, T &b1, long &n2, T &b2) const
Definition: tline.h:1435
virtual int get_step(long n, T &fstep) const
Definition: tline.h:1450
virtual int operator!=(const AbsCoorMesh< T > &m2)
Definition: tline.h:1481
virtual T get_xmax(void) const
Definition: tline.h:1416
virtual int get_interval(long n, T &b1, T &b2) const
Definition: tline.h:1292
virtual void get_scoor(long n, T &b) const
Definition: tline.h:1288
virtual int apeq_mant(const AbsCoorMesh< T > &m2, T prec)
Definition: tline.h:1354
virtual int get_interval(T x, long &n1, T &b1, long &n2, T &b2) const
Definition: tline.h:1303
virtual T get_xmax(void) const
Definition: tline.h:1284
virtual void print(std::ostream &file) const
Definition: tline.h:1326
virtual long get_qi(void) const
Definition: tline.h:1282
virtual int operator!=(const AbsCoorMesh< T > &m2)
Definition: tline.h:1348
virtual T get_xmin(void) const
Definition: tline.h:1283
macro_copy_total(VirtEqualStepCoorMesh< T >)
virtual int get_interval_extrap(T x, long &n1, T &b1, long &n2, T &b2) const
Definition: tline.h:1310
virtual int operator==(const AbsCoorMesh< T > &m2)
Definition: tline.h:1336
virtual int get_step(long n, T &fstep) const
Definition: tline.h:1318
virtual int get_interval(T x, long &n1) const
Definition: tline.h:1296
int s_rewind
Definition: definp.h:42
std::istream * istrm
Definition: definp.h:38
int s_req_sep
Definition: definp.h:43
long set_position(const String &word, std::istream &istrm, int s_rewind, int s_req_sep)
Definition: definp.cpp:71
#define DEFINPAP(name)
Definition: definp.h:91
indentation indn
Definition: prstream.cpp:13
std::ostream & yesindent(std::ostream &f)
Definition: prstream.cpp:19
std::ostream & noindent(std::ostream &f)
Definition: prstream.cpp:15
#define mcout
Definition: prstream.h:133
#define Iprint3n(file, name1, name2, name3)
Definition: prstream.h:249
#define Ifile
Definition: prstream.h:207
#define mcerr
Definition: prstream.h:135
#define Iprintn(file, name)
Definition: prstream.h:216
#define Iprint2n(file, name1, name2)
Definition: prstream.h:236
#define Iprint4n(file, name1, name2, name3, name4)
Definition: prstream.h:260
T t_find_x_for_integ_step_ar(const M &mesh, const D &y, T integ, int *s_err)
Definition: tline.h:2127
long t_entire_hisran_step_ar(const M &mesh, const D &integ_y, T rannum)
Definition: tline.h:2394
void t_hfill_step_ar_ac(const M &mesh, const D &y, T x, T val=1, int s_include_last_point=0)
Definition: tline.h:1740
T t_value_power_extended_2point(T x1, T y1, T x2, T y2, T x)
Definition: tline.h:2625
T t_value_step_ar(const M &mesh, const D &y, T x, int s_include_last_point=0)
Definition: tline.h:1649
long t_find_entire_x_for_already_integ_step_ar(const M &mesh, const D &y, T integ, int *s_err)
Definition: tline.h:2241
std::istream & operator>>(std::istream &file, EqualStepCoorMesh< T > &f)
Definition: tline.h:264
int verify_types(const T *ths, const B *b2, const T **tb2)
Definition: tline.h:1179
T t_value_straight_2point(T x1, T y1, T x2, T y2, T x, int s_ban_neg)
Definition: tline.h:2439
T t_hisran_step_ar(const M &mesh, const D &integ_y, T rannum)
Definition: tline.h:2331
long t_find_interval_end(double x, long q, const D &coor, long n_start)
Definition: tline.h:358
T t_find_x_for_already_integ_step_ar(const M &mesh, const D &y, T integ, int *s_err)
Definition: tline.h:2176
T t_width_at_hheight_step_ar(const M &mesh, const D &y)
Definition: tline.h:2874
T t_integ_power_2point(T x1, T y1, T x2, T y2, T xl, T xr)
Definition: tline.h:2661
T t_value_power_2point(T x1, T y1, T x2, T y2, T x)
Definition: tline.h:2603
void t_hfill_step_ar(const M &mesh, const D &y, T x, T val=1, int s_include_last_point=0)
Definition: tline.h:1714
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:2473
T t_mean_step_ar(const M &mesh, const D &y, T x1, T x2, int &s_err)
Definition: tline.h:2425
ActivePtr< AbsCoorMesh< T > > read_AbsCoorMesh(std::istream &file)
Definition: tline.h:1604
int operator!=(const EqualStepCoorMesh< T > &f1, const EqualStepCoorMesh< T > &f2)
Definition: tline.h:303
T t_opposite_hisran_step_ar(const M &mesh, const D &integ_y, T x)
Definition: tline.h:2362
int apeq_mant(const EqualStepCoorMesh< T > &f1, const EqualStepCoorMesh< T > &f2, T prec)
Definition: tline.h:290
T t_value_exp_2point(T x1, T y1, T x2, T y2, T x)
Definition: tline.h:2643
T t_integ_step_ar(const M &mesh, const D &y, T x1, T x2, int xpower)
Definition: tline.h:1810
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:2762
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:2786
T t_total_integ_step_ar(const M &mesh, const D &y)
Definition: tline.h:1987
T t_hispre_step_ar(const M &mesh, const D &y, D &integ_y)
Definition: tline.h:2295
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:2511
int operator==(const EqualStepCoorMesh< T > &f1, const EqualStepCoorMesh< T > &f2)
Definition: tline.h:280
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:2678
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:2572
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:1907
long t_find_interval(double x, long q, const D &coor)
Definition: tline.h:314
std::ostream & operator<<(std::ostream &file, const EqualStepCoorMesh< T > &f)
Definition: tline.h:257