Garfield++ 5.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
AbsArr.h
Go to the documentation of this file.
1#ifndef ABSARR_H
2#define ABSARR_H
3/*
4Simple arrays with variable length.
5DynLinArr - "Dynamic Linear Array" - it is what it is.
6The name is choosen to distinguish this template class from every known
7other libraries.
8The information is kept in one block of memory and accessible with
9indexes. The array is characterized by the only parameter - its physical
10size. If you need a logicl size different from physical, keep the
11logical size in a separated place.
12Increasing of the array size leads to allocation of
13another block of memory and copying all elements to it by
14operator= (which can be correctly defined in the class definitions).
15This is difference with STL, in which vector have logical size
16which can be smaller than the volume of allocated memory.
17Currently the array boundaries are checked at each access, this is
18also difference with STL.
19These checks can be switched out by undefining macro ALR_CHECK_BOUND.
20The copying of array leads to copying all elements, destruction - to
21destruction of elements.
22The array DynLinArr can keep other array DynLinArr as elements
23and constitute multy-dimensional array of not "parallelogram" shape,
24that is for each first index, the dimension corresponding to
25the second index can be different from that of the other first indexes.
26This is very powerful feature, but it is not always desirable.
27If you need box-like array or "parallelogram" shape, use DynArr -
28"Dynamic Array".
29
30In DynArr the number of dimensions is arbitrary, but size of this
31array along each dimension is fixed and independent on
32the indexes of other dimensions. So this is rectangular array.
33The access is performed by indexes,
34but not through operators []. Since it is not trivial to provide
35such access for this array, I preferred the simplest solutions
36and arranged this access through little functions "ac":
37 T& DynArr::ac(long i) // for 1-dimensional array
38 T& DynArr::ac(long i1, long i2) // for 2-dimensional array
39 T& DynArr::ac(const DynLinArr<long>& ind)
40 // for arbitrary number of dimensions
41 // but the number of them in array should be equal to size of ind.
42 // ind is array of indexes. Its first element if the first index,
43 // second is second, etc.
44class DynArr is constructed with the help of DynLinArr.
45DynArr can keep as elements another DynArr's or DynLinArr's.
46DynLinArr can also keep DynArr as elements.
47
48There are many various auxiliary utilites assosiated with these arrays.
49Some of them look little bit antiquated, since they was created in
50stone age and were not revised after innovation of electricity.:)
51This happened because the author needed to port his programs on
52very various computers, not all of them had very advanced C++-related
53software. Today the situation with C++ is being changed rapidly
54and some of these pearls may be arranged by more modern way.
55But the main components of this file are actual and very convenient.
56
57Copyright (c) 1999-2005 I. B. Smirnov
58
59The file can be used, copied, modified, and distributed
60according to the terms of GNU Lesser General Public License version 2.1
61as published by the Free Software Foundation,
62and provided that the above copyright notice, this permission notice,
63and notices about any modifications of the original text
64appear in all copies and in supporting documentation.
65The file is provided "as is" without express or implied warranty.
66*/
67#include <iostream>
68#include <iomanip>
69#include <sstream>
72#include "wcpplib/util/String.h"
74
75// Here there is a good place to switch on the bound check in all programs
76#ifndef ALR_CHECK_BOUND
77#define ALR_CHECK_BOUND
78#endif
79#ifndef ALR_CHECK_EACH_BOUND
80#define ALR_CHECK_EACH_BOUND
81#endif
82
83//#define DEBUG_DYNLINARR // make some print
84//#define DEBUG_DYNARR // make some print and in addition
85// functions from DynArr make some formally unnecessary checks, which are
86// however useful for debug.
87
88namespace Heed {
89extern long max_qel_DynLinArr; // increase it if need
90// Helps to detect access to not inited DynLinArr,
91// what may happen at initializetion of class members
92// and use of not inited member for initialization of the other.
93
94template <class T>
95class DynArr;
96
98class ArgInterp_SingleAdr {}; // for put_qel()
100
101template <class T>
102class DynLinArr : public RegPassivePtr {
103 public:
104 // Constructors
105 DynLinArr(void) : qel(0), el(NULL) { ; }
106 explicit DynLinArr(long fqel) : qel(fqel), el(NULL) {
107 if (qel > max_qel_DynLinArr) {
108 mcerr << "ERROR in DynLinArr(long fqel):\n";
109 mcerr << "qel > max_qel_DynLinArr:\n";
111 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
112 << '\n';
113 spexit(mcerr);
114 }
115 if (qel < 0) {
116 mcerr << "ERROR in DynLinArr(long fqel):\n";
117 mcerr << "qel < 0:\n";
118 Iprintn(mcout, qel);
119 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
120 << '\n';
121 spexit(mcerr);
122 }
123 el = (fqel > 0) ? (new T[fqel]) : (T*)NULL;
124 }
125
126 DynLinArr(long fqel, const T& val) : qel(fqel), el(NULL) {
127 if (qel > max_qel_DynLinArr) {
128 mcerr << "ERROR in DynLinArr(long fqel, const T& val):\n";
129 mcerr << "qel > max_qel_DynLinArr:\n";
131 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
132 << '\n';
133 spexit(mcerr);
134 }
135 if (qel < 0) {
136 mcerr << "ERROR in DynLinArr(long fqel, const T& val):\n";
137 mcerr << "qel < 0:\n";
138 Iprintn(mcout, qel);
139 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
140 << '\n';
141 spexit(mcerr);
142 }
143 el = (fqel > 0) ? (new T[fqel]) : (T*)NULL;
144 assignAll(val);
145 }
146 DynLinArr(long fqel, const T* ar, ArgInterp_Arr /*t*/) : qel(fqel), el(NULL) {
147 if (qel > max_qel_DynLinArr) {
148 mcerr << "ERROR in DynLinArr(long fqel, const T* ar, ArgInterp_Arr):\n";
149 mcerr << "qel > max_qel_DynLinArr:\n";
151 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
152 << '\n';
153 spexit(mcerr);
154 }
155 if (qel < 0) {
156 mcerr << "ERROR in DynLinArr(long fqel, const T* ar, ArgInterp_Arr):\n";
157 mcerr << "qel < 0:\n";
158 Iprintn(mcout, qel);
159 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
160 << '\n';
161 spexit(mcerr);
162 }
163 el = (fqel > 0) ? (new T[fqel]) : (T*)NULL;
164 for (long n = 0; n < qel; n++) el[n] = ar[n];
165 }
166 // const T* ar is array here (of course).
167 // ArgInterp_Arr serves to distinguish this
168 // from previous constructor when second argument
169 // does not coincide with T but can be converted to it.
170 // Typical example is when T is double and second argument is 0.
171 // It is assumed that 0 should be converted to 0.0 and previous
172 // constructor should be called. But in practice (Red Hat Linux 6.0)
173 // the compiler says
174 // call of overloaded `DynLinArr(int &, int)' is ambiguous.
175 // I don't know whether this is error of particular compiler or
176 // general problem. But the third dummy argument is anyway convenient
177 // to distringuish these cases.
178
180 template <class D>
182
183 void pass(long fqel, T* fel) {
184 // Do not call directly! Is to be used only
185 // from assignment operator above
186 clear();
187 qel = fqel;
188 el = fel;
189 }
190
191 inline DynLinArr(const DynLinArr<T>& f);
192 DynLinArr(const DynLinArr<T>& f, Pilfer) : qel(f.qel), el(f.el) {
193#ifdef DEBUG_DYNLINARR
194 mcout << "DynLinArr( DynLinArr<T>& f, Pilfer) is working\n";
195#endif
196 f.qel = 0;
197 f.el = 0;
198 }
199 DynLinArr(const DynArr<T>& f); // works only if f has one dimension
200 // otherwise calls spexit.
201
202 DynLinArr(const DynArr<T>& f, int n_of_dim,
203 // 0 - first dim) 1 - second dim)
204 long roc_number);
205 // takes only mentioned raw or column.
206
207 DynLinArr& assignAll(const T& f) {
208 check();
209 for (long n = 0; n < qel; n++) el[n] = f;
210 return *this;
211 }
212 template <class X>
214 // assumes that element is object
215 // which also accepts assignAll, which is called for it.
216 check();
217 for (long n = 0; n < qel; n++) el[n].assignAll(f);
218 return *this;
219 }
220 // DynLinArr& operator=(const T& f) { int n; for( n=0; n<qel; n++) el[n]=f; }
221 inline T& operator[](long n) {
222#ifdef ALR_CHECK_BOUND
223 if (n >= 0 && n < qel) return el[n];
224 mcerr << "ERROR in const T& DynLinArr::operator[](long n) const: "
225 << "n is out of bounds, n=" << n << " qel=" << qel << '\n';
226 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
227 << '\n';
228 spexit(mcerr);
229 return el[0];
230#else
231 return el[n];
232#endif
233 }
234 inline const T& operator[](long n) const {
235#ifdef ALR_CHECK_BOUND
236 if (n >= 0 && n < qel) return el[n];
237 mcerr << "ERROR in const T& DynLinArr::operator[](long n) const: "
238 << "n is out of bounds, n=" << n << " qel=" << qel << '\n';
239 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
240 << '\n';
241 spexit(mcerr);
242 return el[0];
243#else
244 return el[n];
245#endif
246 }
247 inline T& acu(long n) {
248 // unchecked access
249 return el[n];
250 }
251 inline const T& acu(long n) const {
252 // unchecked access
253 return el[n];
254 }
255 inline T& last_el(void) {
256#ifdef ALR_CHECK_BOUND
257 if (qel > 0) return el[qel - 1];
258 mcerr << "ERROR in const T& DynLinArr::last_el(void) const: qel <=0:"
259 << " qel" << qel << '\n';
260 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
261 << '\n';
262 spexit(mcerr);
263 return el[0];
264#else
265 return el[qel];
266#endif
267 }
268
269 inline const T& last_el(void) const {
270#ifdef ALR_CHECK_BOUND
271 if (qel > 0) return el[qel - 1];
272 mcerr << "ERROR in const T& DynLinArr::last_el(void) const: qel <=0:"
273 << " qel" << qel << '\n';
274 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
275 << '\n';
276 spexit(mcerr);
277 return el[0];
278#else
279 return el[qel];
280#endif
281 }
282
283 long get_qel(void) const { return qel; }
284 void put_qel(long fqel);
285 void put_qel(long fqel, const T* val, ArgInterp_SingleAdr t);
286 // creates array with size fqel
287 // If old array existed, then
288 // If it was less than fqel, it all is copied to new array
289 // and the other elements either assigned *val or
290 // remains not inited.
291 // else its fqel part is copyed to new array.
292 // ArgInterp_SingleAdr serves to distinguish this
293 // from next function when second argument
294 // does not coincide with T but can be converted to it
295 // (for example NULL to int and it is not clear which function
296 // should be called.
297 // Attention!, val is an element, this is assimetry with contructor,
298 // in which ar is an array.
299
300 void put_qel(long fqel, const T& val) {
301 put_qel(fqel, &val, ArgInterp_SingleAdr());
302 }
303 void increment(const T* val = NULL) {
304 check();
305 long q = qel + 1;
306 put_qel(q, *val);
307 }
308 void increment(const T& val) {
309 check();
310 long q = qel + 1;
311 put_qel(q, val);
312 }
313 void clear(void) { put_qel(0); } // Not only clears the content,
314 // but makes zero dimension.
315 void pilfer(const DynLinArr<T>& f) {
316#ifdef DEBUG_DYNLINARR
317 mcout << "DynLinArr::pilfer is called\n";
318#endif
319 if (this != &f) {
320 if (qel != 0) {
321 if (f.qel != 0) {
322 mcerr << "ERROR in DynLinArr::pilfer(...):\n";
323 mcerr << "Both the destination and source arrays are not empty\n";
324 // For explanations why it is dengerous, see similar function
325 // of ActivePtr.
326 spexit(mcerr);
327 } else {
328 delete[] el;
329 qel = 0;
330 }
331 }
332 el = f.el;
333 qel = f.qel;
334 f.el = NULL;
335 f.qel = 0;
336 }
337 }
338
339 void check(void) const;
340
341 /*
342 void print(std::ostream& file, long qpr) const
343 {
344 Ifile<<"DynLinArr<T>: qel="<<get_qel()<<" qpr="<<qpr<<'\n';
345 long n;
346 indn.n+=2;
347 for( n=0; n<qpr; n++)
348 {
349 Ifile<<"n="<<n<<" el[n]="<<this->DynLinArr<T>::operator[](n)<<'\n';
350 }
351 indn.n-=2;
352 }
353 */
354 DynArr<T> top(void); // transpose the vector, rotate it
355 // from vertical colunm to horisontal line for the purpose
356 // of linear algebra calculations.
357
358 // friend void DLA_sort<T>(DynLinArr<T>& f);
359 // Apply any function of one argument (of type T) to each element.
360 template <class P>
361 friend void apply1(DynLinArr<P>& ar, void (*fun)(P& f));
362 // template<class P> friend void apply1m(DynLinArr<P>& ar,
363 // void (*P::fun)(void));
364 // Apply any function of two arguments
365 // (first of which is of type T and the second is of type of address
366 // of another function (possibly apply1) to each element.
367 template <class P, class X>
368 friend void apply2(DynLinArr<P>& ar, void (*fun1)(P& f, void (*fun21)(X& f)),
369 void (*fun2)(X& f));
370
371 // template<class P, class X> friend void apply2m(DynLinArr<P>& ar,
372 // void (*fun1)(P& f, void (*fun21)(X& f) ),
373 // void (*X::fun2)(void) );
374 // void apply(void (*fun)(T& f))
375 //{ long n; for(n=0; n<qel; n++) (*fun)(el[n]); }
376
377 // Attention: the both sorts below at large N are much less efficient
378 // then sort for standard vectors.
379 // At N of the order of 50000 thay take several seconds,
380 // whereas sort for vectors takes several tenths of second.
381
382 void sort(long q_to_sort = 0); // sorts first q_to_sort to increasing order.
383 // If q_to_sort = 0, it sorts all get_qel() elements.
384
385 void sort(DynLinArr<long>& sort_ind, long q_to_sort = 0) const;
386 // to increasing order
387 // Does not change array, but creates index array which gives access
388 // in sorted order. For example:
389 // DynLinArr< long > sort_ind;
390 // collection.sort(sort_ind);
391 // for(n=0; n<q; n++)
392 // {
393 // collection_ordered[n] = collection[sort_ind[n]];
394 // }
395 // Thus content of each n-th element of sort_ind gives
396 // position of n-th (by size) element of array.
397
398 // finds and sorts minimal q_to_sort elements from all.
400 long q_to_sort = 0) const;
402 long q_to_sort = 0) const;
403
404 virtual DynLinArr* copy() const;
405
406 virtual ~DynLinArr() {
407 check();
408 if (el) delete[] el;
409 }
410
411 private:
412 mutable long qel; // number of elements, mutable only for pilfer
413 mutable T* el; // array of qel elements, mutable only for pilfer
414 //(regarding mutable and pilfer see ActivePtr for more comments).
415};
416template <class T>
418 return new DynLinArr<T>(*this);
419}
420
421template <class T>
422void apply1(DynLinArr<T>& ar, void (*fun)(T& f)) {
423 for (long n = 0; n < ar.qel; n++) (*fun)(ar.el[n]);
424}
425
426template <class T, class X>
427void apply2(DynLinArr<T>& ar, void (*fun1)(T& f, void (*fun21)(X& f)),
428 void (*fun2)(X& f)) {
429 for (long n = 0; n < ar.qel; n++) (*fun1)(ar.el[n], fun2);
430}
431
432template <class T>
433void DynLinArr<T>::check(void) const {
434 if (qel < 0) {
435 mcerr << "ERROR in template<class T> void DynLinArr<T>::check(void):\n";
436 mcerr << "qel < 0, qel=" << qel << '\n';
437 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
438 << '\n';
439 spexit(mcerr);
440 }
441 if (qel == 0 && el != NULL) {
442 mcerr << "ERROR in template<class T> void DynLinArr<T>::check(void):\n";
443 mcerr << "qel == 0 && el != NULL: el=" << el << '\n';
444 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
445 << '\n';
446 spexit(mcerr);
447 }
448 if (qel > 0) {
449 if (el == NULL) {
450 mcerr << "ERROR in template<class T> void DynLinArr<T>::check(void):\n";
451 mcerr << "qel > 0 && el == NULL: qel=" << qel << '\n';
452 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
453 << '\n';
454 spexit(mcerr);
455 }
456 if (qel > max_qel_DynLinArr) {
457 mcerr << "ERROR in template<class T> void DynLinArr<T>::check(void):\n";
458 mcerr << "qel > max_qel_DynLinArr: \n";
460 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
461 << '\n';
462 spexit(mcerr);
463 }
464 }
465}
466
467template <class T>
469#ifdef DEBUG_DYNLINARR
470 mcout << "DynLinArr<T>& DynLinArr<T>::operator=(const DynLinArr<T>& f) is "
471 "working\n";
472#endif
473 if (this != &f) {
474 // mcout<<"DynLinArr<T>& operator=(const DynLinArr<T>& f): long(el)="
475 //<<long(el)<<'\n';
476 check();
477 f.check();
478 // First of all we allocate memory and copy to there
479 // all elements from f, because f can be part of this array,
480 // for example, one of its elements.
481 long q = f.get_qel();
482 T* temp_el = (T*)NULL;
483 if (q > 0) {
484 temp_el = new T[q];
485 for (long n = 0; n < q; n++) temp_el[n] = f.el[n];
486 }
487 pass(q, temp_el);
488 }
489 return *this;
490}
491
492template <class T>
493template <class D>
495#ifdef DEBUG_DYNLINARR
496 mcout << "DynLinArr<T>& DynLinArr<T>::operator=(const DynLinArr<D>& f) is "
497 "working\n";
498#endif
499 if (this == &f) return *this;
500 check();
501 f.check();
502 // First of all we allocate memory and copy to there
503 // all elements from f, because f can be part of this array,
504 // for example, one of its elements.
505 long q = f.get_qel();
506 T* temp_el = (T*)NULL;
507 if (q > 0) {
508 temp_el = new T[q];
509 for (long n = 0; n < q; n++) temp_el[n] = f[n];
510 }
511 pass(q, temp_el);
512 return *this;
513}
514
515template <class T>
517 : RegPassivePtr(),
518 qel(0),
519 el(NULL) {
520#ifdef DEBUG_DYNLINARR
521 mcout << "DynLinArr(const DynLinArr<T>& f) is working\n";
522#endif
523 *this = f;
524}
525
526template <class T>
527void DynLinArr<T>::put_qel(long fqel) {
528 //
529 // creates array with size fqel
530 // If old array existed, then
531 // If it was less than fqel, it all is copied to new array
532 // and the other elements either assigned *val or
533 // remains not inited.
534 // else its fqel part is copyed to new array.
535 // mcout<<"put_qel: *this="<<(*this);
536 if (fqel < 0) {
537 mcerr << "ERROR in template<class T> void DynLinArr<T>::put_qel(long "
538 "fqel):\n";
539 mcerr << "fqel < 0, fqel=" << fqel << '\n';
540 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
541 << '\n';
542 spexit(mcerr);
543 }
544 check();
545 if (el == NULL) {
546 qel = fqel;
547 if (qel > 0) el = new T[fqel];
548 } else {
549 if (qel != fqel) {
550 if (fqel <= 0) {
551 qel = 0;
552 delete[] el;
553 el = NULL;
554 } else {
555 T* elh;
556 elh = new T[fqel];
557 for (long n = 0; n < fqel; ++n) {
558 if (n < qel) elh[n] = el[n];
559 }
560 delete[] el;
561 el = elh;
562 qel = fqel;
563 }
564 }
565 }
566}
567
568template <class T>
569void DynLinArr<T>::put_qel(long fqel, const T* val, ArgInterp_SingleAdr t) {
570 // By default val == NULL
571 // creates array with size fqel
572 // If old array existed, then
573 // If it was less than fqel, it all is copied to new array
574 // and the other elements either assigned *val or
575 // remains not inited.
576 // else its fqel part is copyed to new array.
577 // mcout<<"put_qel: *this="<<(*this);
578 if (fqel < 0) {
579 mcerr << "ERROR in template<class T> void DynLinArr<T>::put_qel(long fqel, "
580 "const T* val, ArgInterp_SingleAdr):\n";
581 mcerr << "fqel < 0, fqel=" << fqel << '\n';
582 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
583 << '\n';
584 spexit(mcerr);
585 // Avoid compiler warning because of unused variable t (HS).
586 mcerr << sizeof(t) << "\n";
587 }
588 check();
589 if (el == NULL) {
590 qel = fqel;
591 if (qel > 0) el = new T[fqel];
592 if (val != NULL)
593 for (long n = 0; n < qel; ++n) el[n] = *val;
594 } else {
595 if (qel != fqel) {
596 if (fqel <= 0) {
597 qel = 0;
598 delete[] el;
599 el = NULL;
600 } else {
601 T* elh;
602 elh = new T[fqel];
603 for (long n = 0; n < fqel; ++n) {
604 if (n < qel)
605 elh[n] = el[n];
606 else if (val != NULL)
607 elh[n] = *val;
608 }
609 delete[] el;
610 el = elh;
611 qel = fqel;
612 }
613 }
614 }
615}
616
617// Simple sorting routine optimized for DynLiArr. )ptimized means
618// not doing checks at each indexing, but it is not the best for the large
619// number of N.
620// Note that it can be made better if at choosing n_possible_next
621// to arrange going backward. But this is much more complicated so currently
622// I am not going to do this.
623
624template <class T>
625void DynLinArr<T>::sort(long q_to_sort) {
626 mfunnamep("void DynLinArr<T>::sort(long q_to_sort = 0)");
627
628 check_econd12(q_to_sort, >, qel, mcerr);
629 if (q_to_sort <= 0) q_to_sort = qel;
630 if (q_to_sort <= 1) return;
631
632 long n_possible_next = 1;
633 for (long n = 0; n < q_to_sort - 1; n++) {
634 // Iprint2n(mcout, n, n_possible_next);
635 // first it finds the minimum along the rest and replaces if it is less
636 // long nmin = n+1;
637 long nmin = n_possible_next;
638 T el_min = el[nmin];
639 int s_change_possible_next = 0;
640
641 // for(m=n+2; m<q_to_sort; m++)
642 for (long m = n_possible_next + 1; m < q_to_sort; m++) {
643 // if(el[nmin] > el[m])
644 if (el_min > el[m]) {
645 n_possible_next = nmin;
646 s_change_possible_next = 1;
647 nmin = m;
648 el_min = el[nmin];
649 }
650 }
651 // Iprint4n(mcout, n_possible_next, s_change_possible_next, nmin, el_min);
652 if (s_change_possible_next == 0 || n_possible_next < n + 2) {
653 n_possible_next = n + 2;
654 }
655 // if(el[n] > el[nmin])
656 //{
657 // T t = el[nmin];
658 // el[nmin] = el[n];
659 // el[n] = t;
660 //}
661 // Iprintn(mcout, n_possible_next);
662 // Iprint2n(mcout, el[n], el_min);
663 if (el[n] > el_min) {
664 if (s_change_possible_next == 1) {
665 // if(n_possible_next < q_to_sort)
666 if (n_possible_next < q_to_sort && el[n] < el[n_possible_next]) {
667 n_possible_next = nmin;
668 }
669 }
670 // mcout<<"replacing el[n] and el_min\n";
671 T t = el_min;
672 el[nmin] = el[n];
673 el[n] = t;
674 }
675 // Iprintn(mcout, (*this));
676 }
677}
678
679// New variant, should be faster, the old is below.
680
681template <class T>
682void DynLinArr<T>::sort(DynLinArr<long>& sort_ind, long q_to_sort) const {
683 mfunnamep(
684 "void DynLinArr<T>::sort(DynLinArr< long >& sort_ind, long "
685 "q_to_sort = 0) const");
686
687 check_econd12(q_to_sort, >, qel, mcerr);
688 if (q_to_sort <= 0) q_to_sort = qel;
689 // if(q_to_sort <= 1) return;
690
691 sort_ind.clear();
692 sort_ind.pilfer(DynLinArr<long>(q_to_sort));
693 long n, m;
694 for (n = 0; n < q_to_sort; n++) {
695 sort_ind.acu(n) = n;
696 }
697 if (q_to_sort <= 1) return;
698
699 long n_possible_next = 1;
700
701 for (n = 0; n < q_to_sort - 1; n++) {
702 // first it finds the minimum along the rest and replaces if it is less
703 long nmin = n_possible_next;
704 long ind_nmin = sort_ind.acu(nmin);
705 int s_change_possible_next = 0;
706
707 // for(m=n+2; m<q_to_sort; m++)
708 for (m = n_possible_next + 1; m < q_to_sort; m++) {
709 if (el[ind_nmin] > el[sort_ind.acu(m)])
710 // if(el[sort_ind.acu(nmin)] > el[sort_ind.acu(m)])
711 {
712 n_possible_next = nmin;
713 s_change_possible_next = 1;
714 nmin = m;
715 ind_nmin = sort_ind.acu(nmin);
716 }
717 }
718 if (s_change_possible_next == 0 || n_possible_next < n + 2) {
719 n_possible_next = n + 2;
720 }
721 if (el[sort_ind.acu(n)] > el[ind_nmin])
722 // if(el[sort_ind.acu(n)] > el[sort_ind.acu(nmin)])
723 {
724 if (s_change_possible_next == 1) {
725 if (n_possible_next < q_to_sort &&
726 el[sort_ind.acu(n)] < el[sort_ind.acu(n_possible_next)]) {
727 n_possible_next = nmin;
728 }
729 }
730 // long t = sort_ind.acu(nmin);
731 sort_ind.acu(nmin) = sort_ind.acu(n);
732 sort_ind.acu(n) = ind_nmin;
733 }
734 }
735}
736
737template <class T>
739 long q_to_sort) const {
740 mfunnamep(
741 "void DynLinArr<T>::sort_select_increasing(DynLinArr< long >& "
742 "sort_ind, long q_to_sort = 0) const");
743
744 check_econd12(q_to_sort, >, qel, mcerr);
745 long s_last_noninc = 0;
746 if (q_to_sort <= 0) {
747 q_to_sort = qel;
748 s_last_noninc = 1;
749 } else if (q_to_sort == qel) {
750 s_last_noninc = 1;
751 }
752
753 // if(qel <= 1) return;
754 sort_ind.clear();
755 sort_ind.pilfer(DynLinArr<long>(qel));
756 long n, m;
757 for (n = 0; n < qel; n++) {
758 sort_ind[n] = n;
759 }
760 if (q_to_sort <= 1) return;
761
762 long n_possible_next = 1;
763
764 for (n = 0; n < q_to_sort - s_last_noninc; n++) {
765 // first it finds the minimum along the rest and replaces if it is less
766 long nmin = n_possible_next;
767 long ind_nmin = sort_ind[nmin];
768 int s_change_possible_next = 0;
769
770 // for(m=n+2; m<q_to_sort; m++)
771 for (m = n_possible_next + 1; m < qel; m++) {
772 if (el[ind_nmin] > el[sort_ind[m]])
773 // if(el[sort_ind.acu(nmin)] > el[sort_ind.acu(m)])
774 {
775 n_possible_next = nmin;
776 s_change_possible_next = 1;
777 nmin = m;
778 ind_nmin = sort_ind[nmin];
779 }
780 }
781 if (s_change_possible_next == 0 || n_possible_next < n + 2) {
782 n_possible_next = n + 2;
783 }
784 if (el[sort_ind[n]] > el[ind_nmin])
785 // if(el[sort_ind.acu(n)] > el[sort_ind.acu(nmin)])
786 {
787 if (s_change_possible_next == 1) {
788 if (n_possible_next < q_to_sort &&
789 el[sort_ind[n]] < el[sort_ind[n_possible_next]]) {
790 n_possible_next = nmin;
791 }
792 }
793 // long t = sort_ind.acu(nmin);
794 sort_ind[nmin] = sort_ind[n];
795 sort_ind[n] = ind_nmin;
796 }
797 }
798 sort_ind.put_qel(qel);
799}
800
801template <class T>
803 long q_to_sort) const {
804 mfunnamep(
805 "void DynLinArr<T>::sort_select_decreasing(DynLinArr< long >& "
806 "sort_ind, long q_to_sort = 0) const");
807
808 check_econd12(q_to_sort, >, qel, mcerr);
809 long s_last_noninc = 0;
810 if (q_to_sort <= 0) {
811 q_to_sort = qel;
812 s_last_noninc = 1;
813 } else if (q_to_sort == qel) {
814 s_last_noninc = 1;
815 }
816 // Iprintn(mcout, q_to_sort);
817
818 // if(qel <= 1) return;
819 sort_ind.clear();
820 sort_ind.pilfer(DynLinArr<long>(qel));
821 long n, m;
822 for (n = 0; n < qel; n++) {
823 sort_ind[n] = n;
824 }
825 if (q_to_sort <= 1) return;
826
827 long n_possible_next = 1;
828
829 for (n = 0; n < q_to_sort - s_last_noninc; n++) {
830 // Iprintn(mcout, n);
831 // first it finds the minimum along the rest and replaces if it is less
832 long nmax = n_possible_next;
833 // Iprintn(mcout, nmax);
834 long ind_nmax = sort_ind[nmax];
835 int s_change_possible_next = 0;
836
837 // for(m=n+2; m<q_to_sort; m++)
838 for (m = n_possible_next + 1; m < qel; m++) {
839 // Iprint3n(mcout, ind_nmax, m, sort_ind[m]);
840 if (el[ind_nmax] < el[sort_ind[m]]) {
841 n_possible_next = nmax;
842 s_change_possible_next = 1;
843 nmax = m;
844 // Iprintn(mcout, nmax);
845 ind_nmax = sort_ind[nmax];
846 }
847 }
848 if (s_change_possible_next == 0 || n_possible_next < n + 2) {
849 n_possible_next = n + 2;
850 }
851 // Iprint4n(mcout, n, sort_ind[n], ind_nmax, el[ind_nmax]);
852 if (el[sort_ind[n]] < el[ind_nmax]) {
853 if (s_change_possible_next == 1) {
854 if (n_possible_next < q_to_sort &&
855 el[sort_ind[n]] > el[sort_ind[n_possible_next]]) {
856 n_possible_next = nmax;
857 }
858 }
859 // long t = sort_ind.acu(nmin);
860 sort_ind[nmax] = sort_ind[n];
861 sort_ind[n] = ind_nmax;
862 }
863 }
864 sort_ind.put_qel(qel);
865}
866
867/*
868template<class T>
869void DynLinArr<T>::sort(DynLinArr< long >& sort_ind, long q_to_sort) const
870{
871 mfunnamep("void DynLinArr<T>::sort(DynLinArr< long >& sort_ind, long q_to_sort
872= 0) const");
873
874 check_econd12(q_to_sort , > , qel , mcerr);
875 if(q_to_sort <= 0) q_to_sort = qel;
876 if(q_to_sort <= 1) return;
877
878 //if(qel <= 1) return;
879 sort_ind.clear();
880 sort_ind.pilfer(DynLinArr< long >(q_to_sort));
881 long n,m;
882 for(n=0; n<q_to_sort; n++)
883 {
884 sort_ind.acu(n) = n;
885 }
886
887 for(n=0; n<q_to_sort-1; n++)
888 {
889 // first it finds the minimum along the rest and replaces if it is less
890 long nmin = n+1;
891 long ind_nmin = sort_ind.acu(nmin);
892 for(m=n+2; m<q_to_sort; m++)
893 {
894 if(el[ind_nmin] > el[sort_ind.acu(m)])
895 //if(el[sort_ind.acu(nmin)] > el[sort_ind.acu(m)])
896 {
897 nmin = m;
898 ind_nmin = sort_ind.acu(nmin);
899 }
900 }
901 if(el[sort_ind.acu(n)] > el[ind_nmin])
902 //if(el[sort_ind.acu(n)] > el[sort_ind.acu(nmin)])
903 {
904 //long t = sort_ind.acu(nmin);
905 sort_ind.acu(nmin) = sort_ind.acu(n);
906 sort_ind.acu(n) = ind_nmin;
907 }
908 }
909}
910*/
911
912/*
913template<T> void DLA_sort(DynLinArr<T>& f)
914{
915 mfunnamep("template<T> void DLA_sort(DynLinArr<T>& f)");
916
917 long q = f.get_qel();
918 if(q <= 1) return;
919 long n,m;
920 T* a = &(f[0]);
921 for(n=0; n<q-1; n++)
922 {
923 for(m=n+1; m<q; m++)
924 {
925 if(a[n] > a[m])
926 {
927 T t = a[m];
928 a[m] = a[n];
929 a[n] = t;
930 }
931 }
932 }
933}
934*/
935/*
936//Somewhy this doen not work prolerly if T is template class itself
937//AbsCont_ts.c:167: type unification failed for function template
938//`template <class T> long int append_TreeNode(TreeNode<...> &,
939//TreeNode<...> &, long int &, T * = 0, long int = 0)'
940*/
941/*
942This is not compiled in Solaris:
943Error: Function templates may not have default parameters.
944*/
945#ifndef BAN_DEFAULT_PAR_FUN_TEMPL
946template <class T>
947long append(const T& t, // value to assign
948 DynLinArr<T>& dla, // array to whose elements this value is to be
949 // assigned
950 long& qael, // input: index of element to which it will be assigned
951 // if qael == get_qel(), the qel will be increased
952 // to either new_qel or by 3 times.
953 // But if qael > get_qel(), it is considered as error.
954 // output: the next index
955 T* tempt = NULL, // data filled to extra elements
956 long new_qel = 0 // recommended new size
957 ) {
958 if (dla.get_qel() < qael) {
959 mcerr << "ERROR in long append(class DynLinArr& dla, ...): dla.get_qel() < "
960 "qael\n"
961 << "dla.get_qel()=" << dla.get_qel() << " qael=" << qael << '\n';
962 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
963 << '\n';
964 spexit(mcerr);
965 }
966 if (dla.get_qel() == qael) {
967 if (new_qel <= qael) new_qel = std::max(3 * qael, long(3));
968 dla.put_qel(new_qel, tempt, ArgInterp_SingleAdr());
969 }
970 dla[qael++] = t;
971 return qael;
972}
973
974#else
975
976#define append_to_DynLinArr(t, dla, qael, tempt, new_qel) \
977 { \
978 if (dla.get_qel() < qael) { \
979 mcerr << "append(class DynLinArr& dla, ...): dla.get_qel() < qael, " \
980 << "dla.get_qel()=" << dla.get_qel() << " qael=" << qael << '\n'; \
981 spexit(mcerr); \
982 } \
983 int nn = new_qel; \
984 if (dla.get_qel() == qael) { \
985 if (new_qel <= qael) nn = std::max(3 * qael, long(3)); \
986 dla.put_qel(nn, tempt); \
987 } \
988 dla[qael++] = t; \
989 }
990#define append_to_DynLinArr_short(t, dla, qael) \
991 { \
992 if (dla.get_qel() < qael) { \
993 mcerr << "append(class DynLinArr& dla, ...): dla.get_qel() < qael, " \
994 << "dla.get_qel()=" << dla.get_qel() << " qael=" << qael << '\n'; \
995 spexit(mcerr); \
996 } \
997 int nn = 0; \
998 if (dla.get_qel() == qael) { \
999 nn = std::max(3 * qael, long(3)); \
1000 dla.put_qel(nn, NULL); \
1001 } \
1002 dla[qael++] = t; \
1003 }
1004#endif
1005
1006template <class T>
1007std::ostream& operator<<(std::ostream& file, const DynLinArr<T>& f) {
1008 // mfunnamep("template<class T> std::ostream& operator<<(std::ostream& file,
1009 // const DynLinArr<T>& f)");
1010 // mcout<<"operator<<(std::ostream& file, const DynLinArr<T>& f) is
1011 // started\n";
1012 Ifile << "DynLinArr<T>: qel=" << f.get_qel() << '\n';
1013 f.check();
1014 long n;
1015 indn.n += 2;
1016 for (n = 0; n < f.get_qel(); n++) {
1017 // Ifile<<"n="<<n<<" el[n]="<<noindent<<f[n]<<yesindent<<'\n';
1018 if (s_short_output == 0) {
1019 Ifile << "n=" << n << " el[n]=";
1020 }
1021 std::ostringstream ost;
1022 ost << indn << noindent << f[n] << yesindent;
1023 put_one_n(ost);
1024 file << ost.str();
1025 }
1026 // file<<yesindent;
1027 indn.n -= 2;
1028 return file;
1029}
1030
1031
1032
1033template <class T>
1034std::istream& operator>>(std::istream& file, DynLinArr<T>& f) {
1035 mfunnamep(
1036 "template<class T> istream& operator>>(istream& file, DynLinArr<T>& f)");
1037 // mcout<<"operator<<(std::ostream& file, const DynLinArr<T>& f) is
1038 // started\n";
1039 definp_endpar dep(&file, 0, 1, 0, s_short_output);
1040 long qel = 0;
1041 dep.s_short = 0;
1042 DEFINPAP(qel);
1043 dep.s_short = s_short_output;
1044 check_econd11(qel, < 0, mcerr);
1045 f.clear();
1046 f.put_qel(qel);
1047 long fn;
1048 for (fn = 0; fn < qel; fn++) {
1049 if (s_short_output == 0) {
1050 long n = 0;
1051 DEFINPAP(n);
1052 check_econd12(fn, !=, n, mcerr);
1053 }
1054 // set_position("el[n]=", *dep.istrm, dep.s_rewind, dep.s_req_sep);
1055 // file >> f[n];
1056 definp_any_par(f[fn], "el[n]=", dep);
1057 }
1058 return file;
1059}
1060
1061// Commented out unused function (hschindl)
1062/*
1063template<class T>
1064void output_DynLinArr(std::ostream& file, const DynLinArr<T>& f, int l, long q)
1065{
1066 //mfunnamep("template<class T> void output_DynLinArr(std::ostream& file, const
1067DynLinArr<T>& f, int l, long q)");
1068 Ifile<<"DynLinArr<T>: qel="<<f.get_qel()<<" q to print is "<<q<<'\n';
1069 f.check();
1070 if(q>f.get_qel())
1071 {
1072 mcerr<<"output_DynLinArr(...): q>f.get_qel(), q="<<q
1073 <<" f.get_qel()="<<f.get_qel()<<'\n';
1074 mcerr<<"Type of T is (in internal notations) "<<typeid(T).name()<<'\n';
1075 spexit(mcerr);
1076 }
1077 long n;
1078 indn.n+=2;
1079 for( n=0; n<q; n++)
1080 {
1081 //Ifile<<"n="<<n<<" el[n]="<<noindent<<f[n]<<yesindent<<'\n';
1082 Ifile<<"n="<<n<<" el[n]="<<noindent;
1083 std::ostringstream ost;
1084 ost<<f[n]<<yesindent;
1085 put_one_n(ost);
1086 file<<ost.str();
1087 }
1088 //file<<yesindent;
1089 indn.n-=2;
1090}
1091*/
1092
1093template <class T>
1094void print_DynLinArr(std::ostream& file, const DynLinArr<T>& f, int l) {
1095 // mfunnamep("template<class T> void print_DynLinArr(std::ostream& file, const
1096 // DynLinArr<T>& f, int l)");
1097 Ifile << "DynLinArr<T>: qel=" << f.get_qel() << '\n';
1098 f.check();
1099 long n;
1100 indn.n += 2;
1101 for (n = 0; n < f.get_qel(); n++) {
1102 // Ifile<<"n="<<n<<" el[n]="<<noindent; f[n].print(file, l);
1103 // file<<yesindent;
1104 Ifile << "n=" << n << " el[n]=" << noindent;
1105 std::ostringstream ost;
1106 f[n].print(ost, l);
1107 ost << yesindent;
1108 put_one_n(ost);
1109 file << ost.str();
1110 }
1111 indn.n -= 2;
1112}
1113
1114template <class T>
1115void print_DynLinArr(std::ostream& file, const DynLinArr<T>& f, int l, long q) {
1116 // mfunnamep("template<class T> void print_DynLinArr(std::ostream& file, const
1117 // DynLinArr<T>& f, int l, long q)");
1118 Ifile << "DynLinArr<T>: qel=" << f.get_qel() << " q to print is " << q
1119 << '\n';
1120 f.check();
1121 if (q > f.get_qel()) {
1122 mcerr << "print_DynLinArr(...): q>f.get_qel(), q=" << q
1123 << " f.get_qel()=" << f.get_qel() << '\n';
1124 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1125 << '\n';
1126 spexit(mcerr);
1127 }
1128 long n;
1129 indn.n += 2;
1130 for (n = 0; n < q; n++) {
1131 // Ifile<<"n="<<n<<" el[n]="<<noindent; f[n].print(file, l);
1132 // file<<yesindent;
1133 Ifile << "n=" << n << " el[n]=" << noindent;
1134 std::ostringstream ost;
1135 f[n].print(ost, l);
1136 ost << yesindent;
1137 put_one_n(ost);
1138 file << ost.str();
1139 }
1140 indn.n -= 2;
1141}
1142
1143template <class T>
1144void print_adr_DynLinArr(std::ostream& file, const DynLinArr<T>& f, int l,
1145 long q) {
1146 // mfunnamep("template<class T> void print_adr_DynLinArr(std::ostream& file,
1147 // const DynLinArr<T>& f, int l, long q)");
1148 Ifile << "DynLinArr<T>: qel=" << f.get_qel() << " q to print is " << q
1149 << '\n';
1150 f.check();
1151 if (q > f.get_qel()) {
1152 mcerr << "print_adr_DynLinArr(...): q>f.get_qel(), q=" << q
1153 << " f.get_qel()=" << f.get_qel() << '\n';
1154 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1155 << '\n';
1156 spexit(mcerr);
1157 }
1158 long n;
1159 indn.n += 2;
1160 for (n = 0; n < q; n++) {
1161 // Ifile<<"n="<<n<<" el[n]="<<noindent; f[n]->print(file, l);
1162 // file<<yesindent;
1163 Ifile << "n=" << n << " el[n]=" << noindent;
1164 std::ostringstream ost;
1165 f[n]->print(ost, l);
1166 ost << yesindent;
1167 put_one_n(ost);
1168 file << ost.str();
1169 }
1170 indn.n -= 2;
1171}
1172
1174
1175void print_DynLinArr_int(std::ostream& file, const DynLinArr<int>& f);
1176void print_DynLinArr_long(std::ostream& file, const DynLinArr<long>& f);
1177void print_DynLinArr_float(std::ostream& file, const DynLinArr<float>& f);
1178void print_DynLinArr_double(std::ostream& file, const DynLinArr<double>& f);
1179// See AbsArrD for similar function with DoubleAc
1180
1181void print_DynLinArr_double2(std::ostream& file, const DynLinArr<double>& f1,
1182 const DynLinArr<double>& f2);
1183// Print two arrays in two colums side-by-side.
1184// Good for arrays of equal dimensions.
1185
1186void print_DynLinArr_int_double(std::ostream& file, const DynLinArr<int>& iar,
1187 const DynLinArr<double>& dar);
1188
1189void print_DynLinArr_int_double3(std::ostream& file, const DynLinArr<int>& iar,
1190 const DynLinArr<double>& dar1,
1191 const DynLinArr<double>& dar2,
1192 const DynLinArr<double>& dar3);
1193// Print 4 arrays in two colums side-by-side.
1194// Good for arrays of equal dimensions.
1195
1196#define Iprintdla_int(file, name) \
1197 file << indn << #name << "=" << noindent; \
1198 print_DynLinArr_int(file, name);
1199#define Iprintdla_long(file, name) \
1200 file << indn << #name << "=" << noindent; \
1201 print_DynLinArr_long(file, name);
1202#define Iprintdla_float(file, name) \
1203 file << indn << #name << "=" << noindent; \
1204 print_DynLinArr_float(file, name);
1205#define Iprintdla_double(file, name) \
1206 file << indn << #name << "=" << noindent; \
1207 print_DynLinArr_double(file, name);
1208// See AbsArrD for similar function with DoubleAc
1209
1210template <class T, class X>
1211void copy_DynLinArr(const T& s, X& d) {
1212 mfunnamep("template<class T, class X> void copy_DynLinArr(const T& s, X& d)");
1213 s.check();
1214 d.check();
1215 long q = s.get_qel();
1216 d.put_qel(q);
1217 long n;
1218 for (n = 0; n < q; n++) {
1219 d[n] = s[n];
1220 }
1221}
1222
1223// Covert to another compatible type
1224template <class T, class X>
1225void convert_DynLinArr(const T& s, X& d) {
1226 long q = s.get_qel();
1227 d.put_qel(q);
1228 long n;
1229 for (n = 0; n < q; n++) {
1230 d[n] = X(s[n]);
1231 }
1232}
1233
1234template <class T>
1235void put_qel_1(DynLinArr<T>& f, long fq) // change dimensions of arrays
1236 // which are elements of the main one
1237{
1238 long q = f.get_qel();
1239 long n;
1240 for (n = 0; n < q; n++) f[n].put_qel(fq);
1241}
1242
1243template <class T, class T1>
1244void assignAll_1(DynLinArr<T>& f, const T1& ft) // assign ft to all elements
1245 // of arrays which are elements of the main one
1246{
1247 long q = f.get_qel();
1248 long n;
1249 for (n = 0; n < q; n++) f[n].assignAll(ft);
1250}
1251
1252template <class T>
1254 public:
1255 IterDynLinArr(DynLinArr<T>* fdar) : dar(fdar), ncur(-1) { ; }
1256 T* more(void) {
1257 if (ncur < dar->get_qel() - 1)
1258 return &((*dar)[++ncur]);
1259 else
1260 ncur = dar->get_qel();
1261 return NULL;
1262 }
1263 T* current(void) {
1264 if (ncur >= 0 || ncur < dar->get_qel())
1265 return &((*dar)[ncur]);
1266 else
1267 return NULL;
1268 }
1269 T* less(void) // switch current to previous
1270 {
1271 if (ncur >= 1)
1272 return &((*dar)[--ncur]);
1273 else
1274 ncur = -1;
1275 return NULL;
1276 }
1277 long get_ncur(void) { return ncur; }
1278
1279 private:
1280 long ncur;
1281 DynLinArr<T>* dar;
1282};
1283
1284int gconfirm_ind(const DynLinArr<long>& qel, const DynLinArr<long>& ind);
1285int gconfirm_ind_ext(const DynLinArr<long>& qel, const DynLinArr<long>& ind);
1286
1287// The following function checks whether the arrays or their first qfirst
1288// elements are equal.
1289// In the first case this means that their dimensions and all elements
1290// should be equal to each other.
1291// In the second case if either of the dimensions is less than qfirst,
1292// the result is negative (0), so the arrays are considered different.
1293// If the dimensions are equal or more than qfirst,
1294// the function compares that number of first elements.
1295// If to put here just equal, the program may not be compiled since
1296// instead of this function the program will insert
1297// template <class InputIterator1, class InputIterator2>
1298// inline bool equal(InputIterator1 first1, InputIterator1 last1,
1299// InputIterator2 first2) {
1300// Therefore I substituted it to ifequal.
1301template <class T>
1302int ifequal(const DynLinArr<T>& fd1, const DynLinArr<T>& fd2,
1303 long qfirst = -1) {
1304 long n;
1305 if (qfirst == -1) {
1306 if ((qfirst = fd1.get_qel()) != fd2.get_qel()) return 0;
1307 // qfirst=fd1.get_qel();
1308 } else {
1309 if (qfirst > fd1.get_qel() || qfirst > fd2.get_qel()) return 0;
1310 }
1311 // Iprintn(mcout, qfirst);
1312 for (n = 0; n < qfirst; n++) {
1313 // Iprint3n(mcout, n, fd1[n], fd2[n]);
1314 if (!(fd1[n] == fd2[n])) return 0;
1315 }
1316 return 1;
1317}
1318
1319// The same as above, but compares DynLinArr with ordinary array.
1320template <class T>
1321int ifequal(const DynLinArr<T>& fd1, const T* fd2, long qfirst = -1) {
1322 long n;
1323 if (qfirst == -1) {
1324 qfirst = fd1.get_qel();
1325 } else {
1326 if (qfirst > fd1.get_qel()) return 0;
1327 }
1328 for (n = 0; n < qfirst; n++)
1329 if (!(fd1[n] == fd2[n])) return 0;
1330 return 1;
1331}
1332
1333template <class T>
1334int ifequal(T* fd1, T* fd2, long qfirst) {
1335 long n;
1336 for (n = 0; n < qfirst; n++)
1337 if (!(fd1[n] == fd2[n])) return 0;
1338 return 1;
1339}
1340
1341template <class T>
1342DynLinArr<T> merge(const DynLinArr<T>& fd1, long qfd1, const DynLinArr<T>& fd2,
1343 long qfd2) {
1344 long n;
1345 if (qfd1 < 0) {
1346 qfd1 = fd1.get_qel();
1347 }
1348 if (qfd2 < 0) {
1349 qfd2 = fd2.get_qel();
1350 }
1351 DynLinArr<T> ret(qfd1 + qfd2);
1352 if (qfd1 + qfd2 == 0) return ret;
1353 for (n = 0; n < qfd1; n++) {
1354 ret[n] = fd1[n];
1355 }
1356 for (n = 0; n < qfd2; n++) {
1357 ret[qfd1 + n] = fd2[n];
1358 }
1359 return ret;
1360}
1361
1362template <class T>
1363class DynArr : public RegPassivePtr {
1364 public:
1365 // Constructors
1366 DynArr(void) { ; }
1367 // For one-dimensional array:
1368 explicit DynArr(long fqel, T* val = NULL)
1369 : qel(DynLinArr<long>(1)),
1370 cum_qel(DynLinArr<long>(1)),
1371 el(DynLinArr<T>(fqel)) {
1372#ifdef DEBUG_DYNARR
1373 mcout << "explicit DynArr(long fqel, T* val=NULL) is called\n";
1374#endif
1375 qel[0] = fqel;
1376 cum_qel[0] = 1;
1377 if (val != NULL) assignAll(*val);
1378 }
1379 DynArr(long fqel, T val, ArgInterp_Val /*t*/)
1380 : qel(DynLinArr<long>(1)),
1381 cum_qel(DynLinArr<long>(1)),
1382 el(DynLinArr<T>(fqel)) {
1383#ifdef DEBUG_DYNARR
1384 mcout << "explicit DynArr(long fqel, T* val=NULL) is called\n";
1385#endif
1386 qel[0] = fqel;
1387 cum_qel[0] = 1;
1388 assignAll(val);
1389 }
1390 DynArr(long fqel, const T* ar, ArgInterp_Arr /*t*/)
1391 : qel(DynLinArr<long>(1)), cum_qel(DynLinArr<long>(1)), el(fqel) {
1392 qel[0] = fqel;
1393 cum_qel[0] = 1;
1394 long n;
1395 for (n = 0; n < fqel; n++) el.acu(n) = ar[n];
1396 }
1397 // Another variant for one-dimensional array
1398 // Attention: if the T is long, this might be mixed with array of dimensions.
1399 // To avoid this the latter should be accompanied by address, see below.
1401 : qel(DynLinArr<long>(1)), cum_qel(DynLinArr<long>(1)), el(f.get_qel()) {
1402 qel[0] = f.get_qel();
1403 cum_qel[0] = 1;
1404 for (long n = 0; n < qel[0]; n++) ac(n) = f[n];
1405 }
1406
1407 // For two-dimensional array:
1408 DynArr(long fqel1, long fqel2, T* val = NULL)
1409 : qel(DynLinArr<long>(2)),
1410 cum_qel(DynLinArr<long>(2)),
1411 el(fqel1 * fqel2) {
1412#ifdef DEBUG_DYNARR
1413 mcout << "DynArr(long fqel1, long fqel2, T* val=NULL) is called\n";
1414#endif
1415 qel[0] = fqel1;
1416 qel[1] = fqel2;
1417 cum_qel[0] = fqel2;
1418 cum_qel[1] = 1;
1419 if (val != NULL) assignAll(*val);
1420 }
1421
1422 DynArr(long fqel1, long fqel2, T val, ArgInterp_Val /*t*/)
1423 : qel(DynLinArr<long>(2)),
1424 cum_qel(DynLinArr<long>(2)),
1425 el(fqel1 * fqel2) {
1426#ifdef DEBUG_DYNARR
1427 mcout
1428 << "DynArr(long fqel1, long fqel2, T val, ArgInterp_Val t) is called\n";
1429#endif
1430 qel[0] = fqel1;
1431 qel[1] = fqel2;
1432 cum_qel[0] = fqel2;
1433 cum_qel[1] = 1;
1434 assignAll(val);
1435 }
1436
1437 // For three-dimensional array:
1438 DynArr(long fqel1, long fqel2, long fqel3, T* val = NULL)
1439 : qel(DynLinArr<long>(3)),
1440 cum_qel(DynLinArr<long>(3)),
1441 el(fqel1 * fqel2 * fqel3) {
1442 qel[0] = fqel1;
1443 qel[1] = fqel2;
1444 qel[2] = fqel3;
1445 cum_qel[0] = fqel2 * fqel3;
1446 cum_qel[1] = fqel3;
1447 cum_qel[2] = 1;
1448 if (val != NULL) assignAll(*val);
1449 }
1450
1451 // For four-dimensional array:
1452 DynArr(long fqel1, long fqel2, long fqel3, long fqel4, T* val = NULL)
1453 : qel(DynLinArr<long>(4)),
1454 cum_qel(DynLinArr<long>(4)),
1455 el(fqel1 * fqel2 * fqel3 * fqel4) {
1456 qel[0] = fqel1;
1457 qel[1] = fqel2;
1458 qel[2] = fqel3;
1459 qel[3] = fqel4;
1460 cum_qel[0] = fqel2 * fqel3 * fqel4;
1461 cum_qel[1] = fqel3 * fqel4;
1462 cum_qel[2] = fqel4;
1463 cum_qel[3] = 1;
1464 if (val != NULL) assignAll(*val);
1465 }
1466
1467 // Default value is removed in order to avoid confusions with copy
1468 // constructor from DynLinArr at T = long.
1469 // If initialization of values is not necessary, just put NULL as argument.
1470 // It creates array with structure determined by fqel.
1471
1472 DynArr(const DynLinArr<long>& fqel, T val, ArgInterp_Val /*t*/) : qel(fqel) {
1473 long qdim = qel.get_qel();
1474 if (qdim <= 0) return;
1475 cum_qel.put_qel(qdim);
1476 long ndim;
1477 long size = qel[0];
1478 for (ndim = 1; ndim < qdim; ndim++) size *= qel[ndim];
1479 el.put_qel(size);
1480 cum_qel[qdim - 1] = 1;
1481 for (ndim = qdim - 2; ndim >= 0; ndim--)
1482 cum_qel[ndim] = qel[ndim + 1] * cum_qel[ndim + 1];
1483 assignAll(val);
1484 }
1485
1486 explicit DynArr(const DynLinArr<long>& fqel, T* val) : qel(fqel) {
1487 // fqel: array of dimensions
1488 // val: address of value to fill, may be NULL
1489 long qdim = qel.get_qel();
1490 if (qdim <= 0) return;
1491 cum_qel.put_qel(qdim);
1492 long ndim;
1493 long size = qel[0];
1494 for (ndim = 1; ndim < qdim; ndim++) size *= qel[ndim];
1495 el.put_qel(size);
1496 cum_qel[qdim - 1] = 1;
1497 for (ndim = qdim - 2; ndim >= 0; ndim--)
1498 cum_qel[ndim] = qel[ndim + 1] * cum_qel[ndim + 1];
1499 if (val != NULL) assignAll(*val);
1500 }
1501
1503#ifdef DEBUG_DYNARR
1504 mcout << "DynArr(const DynArr<T>& f) is working\n";
1505#endif
1506 *this = f;
1507 }
1509 : qel(f.qel, steal), cum_qel(f.cum_qel, steal), el(f.el, steal) {
1510#ifdef DEBUG_DYNARR
1511 mcout << "DynArr( DynArr<T>& f, Pilfer) is working\n";
1512#endif
1513 }
1514
1515 void pilfer(const DynArr<T>& f) {
1516#ifdef DEBUG_DYNARR
1517 mcout << "DynArr::pilfer is called\n";
1518#endif
1519 if (this != &f) {
1520 if (qel.get_qel() != 0) {
1521 if (f.qel.get_qel() != 0) {
1522 mcerr << "ERROR in DynArr::pilfer(...):\n";
1523 mcerr << "Both the destination and source arrays are not empty\n";
1524 // For explanations why it is dangerous, see similar function
1525 // of ActivePtr.
1526 spexit(mcerr);
1527 } else {
1528 qel.clear();
1529 cum_qel.clear();
1530 el.clear();
1531 }
1532 }
1533 qel.pilfer(f.qel);
1534 cum_qel.pilfer(f.cum_qel);
1535 el.pilfer(f.el);
1536 f.qel.clear();
1537 f.cum_qel.clear();
1538 f.el.clear();
1539 }
1540 }
1541
1543 template <class D>
1545
1546 void pass(long q, DynLinArr<long> fqel, DynLinArr<long> fcum_qel, T* fel)
1547 // Do not call directly! Is to be used only
1548 // from assignment operator above
1549 {
1550 clear();
1551 qel = fqel;
1552 cum_qel = fcum_qel;
1553 el.pass(q, fel);
1554 }
1555
1556 // Auxiliary class that provides indexing through ordinary way
1557 // It is perhaps quite slow.
1558 template <class D>
1560 public:
1562 mutable long q_deref_ind;
1563 mutable long current_pos;
1564 IndexingProvider(DynArr<D>& farr, long fq_deref_ind, long fcurrent_pos)
1565 : arr(farr), q_deref_ind(fq_deref_ind), current_pos(fcurrent_pos) {}
1566 operator D&() const {
1567 if (q_deref_ind != arr.qel.get_qel()) {
1568 mcerr << "ERROR in IndexingProvider::operator D& (): q_deref_ind != "
1569 "qel.get_qel()\n";
1570 Iprint2n(mcerr, q_deref_ind, arr.qel.get_qel());
1571 mcerr << "Type of T is (in internal notations) " << typeid(D).name()
1572 << '\n';
1573 spexit(mcerr);
1574 }
1575#ifdef ALR_CHECK_BOUND
1576 return arr.el[current_pos];
1577#else
1578 return arr.el.acu(current_pos);
1579#endif
1580 }
1581 D& operator=(const D& f) {
1582 if (q_deref_ind != arr.get_qel().get_qel()) {
1583 mcerr << "ERROR in T& IndexingProvider::operator=(T& f): q_deref_ind "
1584 "!= arr.get_qel().get_qel()\n";
1585 Iprint2n(mcerr, q_deref_ind, arr.get_qel().get_qel());
1586 mcerr << "Type of T is (in internal notations) " << typeid(D).name()
1587 << '\n';
1588 spexit(mcerr);
1589 }
1590#ifdef ALR_CHECK_BOUND
1591 arr.ac_lin(current_pos) = f;
1592#else
1593 arr.acu_lin(current_pos) = f;
1594#endif
1595 // return arr.el[current_pos];
1596 }
1597
1599 if (q_deref_ind >= arr.get_qel().get_qel()) {
1600 mcerr << "ERROR in DynArr::IndexingProvider& DynArr::operator[](long "
1601 "n): q_deref_ind >= arr.get_qel().get_qel()\n";
1602 Iprint2n(mcerr, q_deref_ind, arr.get_qel().get_qel());
1603 mcerr << "Type of T is (in internal notations) " << typeid(D).name()
1604 << '\n';
1605 spexit(mcerr);
1606 }
1607#ifdef ALR_CHECK_EACH_BOUND
1608 if (n < 0 || n >= arr.qel.acu(q_deref_ind)) {
1609 mcerr << "Error in IndexingProvider<D>& "
1610 "IndexingProvider::operator[](long n): n < 0 || n >= "
1611 "qel.acu(q_deref_ind)\n";
1612 Iprint2n(mcout, n, arr.qel.acu(q_deref_ind));
1613 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1614 << '\n';
1615 spexit(mcerr);
1616 }
1617#endif
1618 current_pos += n * arr.get_cum_qel().acu(q_deref_ind);
1619 q_deref_ind++;
1620 return *this;
1621 }
1622
1623 inline const IndexingProvider<D>& operator[](long n) const {
1624 if (q_deref_ind >= arr.get_qel().get_qel()) {
1625 mcerr << "ERROR in DynArr::IndexingProvider& DynArr::operator[](long "
1626 "n): q_deref_ind >= arr.get_qel().get_qel()\n";
1627 Iprint2n(mcerr, q_deref_ind, arr.get_qel().get_qel());
1628 mcerr << "Type of T is (in internal notations) " << typeid(D).name()
1629 << '\n';
1630 spexit(mcerr);
1631 }
1632#ifdef ALR_CHECK_EACH_BOUND
1633 if (n < 0 || n >= arr.qel.acu(q_deref_ind)) {
1634 mcerr << "Error in IndexingProvider<D>& "
1635 "IndexingProvider::operator[](long n): n < 0 || n >= "
1636 "qel.acu(q_deref_ind)\n";
1637 Iprint2n(mcout, n, arr.qel.acu(q_deref_ind));
1638 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1639 << '\n';
1640 spexit(mcerr);
1641 }
1642#endif
1643 current_pos += n * arr.get_cum_qel().acu(q_deref_ind);
1644 q_deref_ind++;
1645 return *this;
1646 }
1647 };
1648
1649 // This operator can be used to provide ordinary indexing [][][]... .
1650 // It is perhaps quite slow compared with ac() functions.
1651 // It is provided only for the use in contexts in which [][][]...
1652 // is needed.
1654 if (qel.get_qel() < 1) {
1655 mcerr << "ERROR in DynArr::IndexingProvider DynArr::operator[](long n): "
1656 "qel.get_qel()< 1, qel.get_qel()=" << qel.get_qel() << '\n';
1657 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1658 << '\n';
1659 spexit(mcerr);
1660 }
1661#ifdef ALR_CHECK_EACH_BOUND
1662 if (n < 0 || n >= qel.acu(0)) {
1663 mcerr << "Error in IndexingProvider<T> DynArr::operator[](long n): n < 0 "
1664 "|| n >= qel.acu(0)\n";
1665 Iprint2n(mcout, n, qel.acu(0));
1666 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1667 << '\n';
1668 spexit(mcerr);
1669 }
1670#endif
1671 return IndexingProvider<T>(*this, 1, n * cum_qel.acu(0));
1672 }
1673
1674 inline const IndexingProvider<T> operator[](long n) const {
1675 if (qel.get_qel() < 1) {
1676 mcerr << "ERROR in DynArr::IndexingProvider DynArr::operator[](long n): "
1677 "qel.get_qel()< 1, qel.get_qel()=" << qel.get_qel() << '\n';
1678 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1679 << '\n';
1680 spexit(mcerr);
1681 }
1682#ifdef ALR_CHECK_EACH_BOUND
1683 if (n < 0 || n >= qel.acu(0)) {
1684 mcerr << "Error in IndexingProvider<T> DynArr::operator[](long n): n < 0 "
1685 "|| n >= qel.acu(0)\n";
1686 Iprint2n(mcout, n, qel.acu(0));
1687 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1688 << '\n';
1689 spexit(mcerr);
1690 }
1691#endif
1692 DynArr<T>* temp = const_cast<DynArr<T>*>(this);
1693 return IndexingProvider<T>(*temp, 1, n * cum_qel.acu(0));
1694 }
1695
1696 T& ac(long i) {
1697 // for 1-dimensional array
1698 if (qel.get_qel() == 1) return el[i];
1699 mcerr << "ERROR in DynArr::ac(long i): qel.get_qel()!= 1, qel.get_qel()="
1700 << qel.get_qel() << '\n';
1701 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1702 << '\n';
1703 spexit(mcerr);
1704 return el[0];
1705 }
1706 const T& ac(long i) const {
1707 // for 1-dimensional array
1708 if (qel.get_qel() == 1) return el[i];
1709 mcerr << "ERROR in DynArr::ac(long i): qel.get_qel()!= 1, qel.get_qel()="
1710 << qel.get_qel() << '\n';
1711 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1712 << '\n';
1713 spexit(mcerr);
1714 return el[0];
1715 }
1716 inline T& acu(long i1) // for 1-dimensional array, completely unchecked
1717 {
1718 return el.acu(i1);
1719 }
1720 inline const T& acu(long i1) const // for 1-dimensional array, completely
1721 // unchecked
1722 {
1723 return el.acu(i1);
1724 }
1725
1726 T& ac(const DynLinArr<long>& ind) // for arbitrary number of dimensions
1727 // but the number of them in array should be equal to size of ind.
1728 // ind is array of indexes. Its first element if the first index,
1729 // second is second, etc.
1730 {
1731 long q;
1732 if ((q = qel.get_qel()) != ind.get_qel()) {
1733 mcerr << "ERROR in DynArr::ac(const DynLinArr<long>& ind): "
1734 << "qel.get_qel()!= ind.get_qel()\n"
1735 << "qel.get_qel()=" << qel.get_qel()
1736 << " ind.get_qel()=" << ind.get_qel() << '\n';
1737 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1738 << '\n';
1739 spexit(mcerr);
1740 }
1741#ifdef ALR_CHECK_EACH_BOUND
1742#ifdef DEBUG_DYNARR
1743 if (q == 1) // faster for this case
1744 return el[ind.acu(0)];
1745 else
1746 return el[calc_lin_ind(ind)];
1747#else
1748 if (q == 1)
1749 return el[ind.acu(0)];
1750 else
1751 return el.acu(calc_lin_ind(ind));
1752#endif
1753#else
1754 if (q == 1)
1755 return el[ind.acu(0)];
1756 else
1757 return el[calc_lin_ind(ind)];
1758#endif
1759 }
1760 const T& ac(const DynLinArr<long>& ind) const // the same as above
1761 {
1762 long q;
1763 if ((q = qel.get_qel()) != ind.get_qel()) {
1764 mcerr << "ERROR in DynArr::ac(const DynLinArr<long>& ind): "
1765 << "qel.get_qel()!= ind.get_qel()\n"
1766 << "qel.get_qel()=" << qel.get_qel()
1767 << " ind.get_qel()=" << ind.get_qel() << '\n';
1768 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1769 << '\n';
1770 spexit(mcerr);
1771 }
1772/*
1773#ifdef ALR_CHECK_EACH_BOUND
1774#ifdef DEBUG_DYNARR
1775 return el[calc_lin_ind(ind)];
1776#else
1777 return el.acu(calc_lin_ind(ind));
1778#endif
1779#else
1780 return el[calc_lin_ind(ind)];
1781#endif
1782 //return el[calc_lin_ind(ind)];
1783 */
1784
1785#ifdef ALR_CHECK_EACH_BOUND
1786#ifdef DEBUG_DYNARR
1787 if (q == 1) // faster for this case
1788 return el[ind.acu(0)];
1789 else
1790 return el[calc_lin_ind(ind)];
1791#else
1792 if (q == 1)
1793 return el[ind.acu(0)];
1794 else
1795 return el.acu(calc_lin_ind(ind));
1796#endif
1797#else
1798 if (q == 1)
1799 return el[ind.acu(0)];
1800 else
1801 return el[calc_lin_ind(ind)];
1802#endif
1803 }
1804
1805 T& acp(const DynLinArr<long>& ind) // the same as above, but
1806 // the size of ind can be more than the number of indexes
1807 // (the rest is unused)
1808 {
1809 long q;
1810 if ((q = qel.get_qel()) > ind.get_qel()) {
1811 mcerr << "ERROR in DynArr::acp(const DynLinArr<long>& ind): "
1812 << "qel.get_qel()!= ind.get_qel()\n"
1813 << "qel.get_qel()=" << qel.get_qel()
1814 << " ind.get_qel()=" << ind.get_qel() << '\n';
1815 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1816 << '\n';
1817 spexit(mcerr);
1818 }
1819
1820#ifdef ALR_CHECK_EACH_BOUND
1821#ifdef DEBUG_DYNARR
1822 if (q == 1) // faster for this case
1823 return el[ind.acu(0)];
1824 else
1825 return el[calc_lin_ind(ind)];
1826#else
1827 if (q == 1)
1828 return el[ind.acu(0)];
1829 else
1830 return el.acu(calc_lin_ind(ind));
1831#endif
1832#else
1833 if (q == 1)
1834 return el[ind.acu(0)];
1835 else
1836 return el[calc_lin_ind(ind)];
1837#endif
1838 }
1839
1840 const T& acp(const DynLinArr<long>& ind) const {
1841 long q;
1842 if ((q = qel.get_qel()) > ind.get_qel()) {
1843 mcerr << "ERROR in DynArr::acp(const DynLinArr<long>& ind): "
1844 << "qel.get_qel()!= ind.get_qel()\n"
1845 << "qel.get_qel()=" << qel.get_qel()
1846 << " ind.get_qel()=" << ind.get_qel() << '\n';
1847 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1848 << '\n';
1849 spexit(mcerr);
1850 }
1851#ifdef ALR_CHECK_EACH_BOUND
1852#ifdef DEBUG_DYNARR
1853 if (q == 1) // faster for this case
1854 return el[ind.acu(0)];
1855 else
1856 return el[calc_lin_ind(ind)];
1857#else
1858 if (q == 1)
1859 return el[ind.acu(0)];
1860 else
1861 return el.acu(calc_lin_ind(ind));
1862#endif
1863#else
1864 if (q == 1)
1865 return el[ind.acu(0)];
1866 else
1867 return el[calc_lin_ind(ind)];
1868#endif
1869 }
1870
1871 T& acu(const DynLinArr<long>& ind) // unchecked
1872 {
1873 if (qel.get_qel() == 1)
1874 return el.acu(ind.acu(0));
1875 else
1876 return el.acu(calc_lin_ind(ind));
1877 }
1878 const T& acu(const DynLinArr<long>& ind) const // unchecked
1879 {
1880 if (qel.get_qel() == 1)
1881 return el.acu(ind.acu(0));
1882 else
1883 return el.acu(calc_lin_ind(ind));
1884 }
1885
1886 T& ac(long i1, long i2) // for 2-dimensional array
1887 {
1888 if (qel.get_qel() == 2) {
1889#ifdef ALR_CHECK_EACH_BOUND
1890 if (i1 >= 0 && i1 < qel.acu(0)) {
1891 if (i2 >= 0 && i2 < qel.acu(1)) {
1892#ifdef DEBUG_DYNARR
1893 return el[i1 * cum_qel.acu(0) + i2];
1894#else
1895 return el.acu(i1 * cum_qel.acu(0) + i2);
1896#endif
1897 } else {
1898 mcerr << "Error in DynArr::ac(long i1, long i2): i2 < 0 || i2 >= "
1899 "qel.acu(1)\n";
1900 Iprint2n(mcout, i2, qel[1]);
1901 }
1902 } else {
1903 mcerr << "Error in DynArr::ac(long i1, long i2): i1 < 0 || i1 >= "
1904 "qel.acu(0)\n";
1905 Iprint2n(mcout, i1, qel[0]);
1906 }
1907 } else {
1908 mcerr << "ERROR in DynArr::ac(long i1, long i2): qel.get_qel()!= 2,"
1909 << " qel.get_qel()=" << qel.get_qel() << '\n';
1910 }
1911 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1912 << '\n';
1913 spexit(mcerr);
1914 return el[0];
1915#else // for ifdef ALR_CHECK_EACH_BOUND
1916 return el[i1 * cum_qel.acu(0) + i2];
1917
1918#endif
1919 }
1920
1921 /*
1922 {
1923 if(qel.get_qel() != 2)
1924 { mcerr<<"ERROR in DynArr::ac(long i1, long i2): qel.get_qel()!= 2,"
1925 <<" qel.get_qel()=" <<qel.get_qel()<<'\n';
1926 mcerr<<"Type of T is (in internal notations) "<<typeid(T).name()<<'\n';
1927 spexit(mcerr); }
1928#ifdef ALR_CHECK_EACH_BOUND
1929 if(i1 < 0 || i1 >= qel.acu(0))
1930 {
1931 mcerr<<"Error in DynArr::ac(long i1, long i2): i1 < 0 || i1 >=
1932qel.acu(0)\n";
1933 Iprint2n(mcout, i1, qel[0]);
1934 spexit(mcerr);
1935 }
1936 if(i2 < 0 || i2 >= qel.acu(1))
1937 {
1938 mcerr<<"Error in DynArr::ac(long i1, long i2): i2 < 0 || i2 >=
1939qel.acu(1)\n";
1940 Iprint2n(mcout, i2, qel[1]);
1941 spexit(mcerr);
1942 }
1943#ifdef DEBUG_DYNARR
1944 return el[i1*cum_qel.acu(0) + i2];
1945#else
1946 return el.acu(i1*cum_qel.acu(0) + i2);
1947#endif
1948#else
1949 return el[i1*cum_qel.acu(0) + i2];
1950#endif
1951 }
1952 */
1953 const T& ac(long i1, long i2) const // for 2-dimensional array
1954 {
1955 if (qel.get_qel() == 2) {
1956#ifdef ALR_CHECK_EACH_BOUND
1957 if (i1 >= 0 && i1 < qel.acu(0)) {
1958 if (i2 >= 0 && i2 < qel.acu(1)) {
1959#ifdef DEBUG_DYNARR
1960 return el[i1 * cum_qel.acu(0) + i2];
1961#else
1962 return el.acu(i1 * cum_qel.acu(0) + i2);
1963#endif
1964 } else {
1965 mcerr << "Error in DynArr::ac(long i1, long i2): i2 < 0 || i2 >= "
1966 "qel.acu(1)\n";
1967 Iprint2n(mcout, i2, qel[1]);
1968 }
1969 } else {
1970 mcerr << "Error in DynArr::ac(long i1, long i2): i1 < 0 || i1 >= "
1971 "qel.acu(0)\n";
1972 Iprint2n(mcout, i1, qel[0]);
1973 }
1974 } else {
1975 mcerr << "ERROR in DynArr::ac(long i1, long i2): qel.get_qel()!= 2,"
1976 << " qel.get_qel()=" << qel.get_qel() << '\n';
1977 }
1978 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
1979 << '\n';
1980 spexit(mcerr);
1981 return el[0];
1982#else // for ifdef ALR_CHECK_EACH_BOUND
1983 return el[i1 * cum_qel.acu(0) + i2];
1984
1985#endif
1986 }
1987 /*
1988 {
1989 if(qel.get_qel() != 2)
1990 { mcerr<<"ERROR in DynArr::ac(long i1, long i2): qel.get_qel()!= 2,"
1991 <<" qel.get_qel()=" <<qel.get_qel()<<'\n';
1992 mcerr<<"Type of T is (in internal notations) "<<typeid(T).name()<<'\n';
1993 spexit(mcerr); }
1994#ifdef ALR_CHECK_EACH_BOUND
1995 if(i1 < 0 || i1 >= qel.acu(0))
1996 {
1997 mcerr<<"Error in DynArr::ac(long i1, long i2): i1 < 0 || i1 >=
1998qel.acu(0)\n";
1999 Iprint2n(mcout, i1, qel[0]);
2000 spexit(mcerr);
2001 }
2002 if(i2 < 0 || i2 >= qel.acu(1))
2003 {
2004 mcerr<<"Error in DynArr::ac(long i1, long i2): i2 < 0 || i2 >=
2005qel.acu(1)\n";
2006 Iprint2n(mcout, i2, qel[1]);
2007 spexit(mcerr);
2008 }
2009#ifdef DEBUG_DYNARR
2010 return el.acu(i1*cum_qel.acu(0) + i2);
2011#else
2012 return el[i1*cum_qel.acu(0) + i2];
2013#endif
2014#else
2015 return el[i1*cum_qel.acu(0) + i2];
2016#endif
2017 //return el[i1*cum_qel[0] + i2];
2018 }
2019 */
2020 inline T& acu(long i1,
2021 long i2) // for 2-dimensional array, completely unchecked
2022 {
2023 return el.acu(i1 * cum_qel.acu(0) + i2);
2024 }
2025 inline const T& acu(long i1, long i2) const // for 2-dimensional array
2026 {
2027 return el.acu(i1 * cum_qel.acu(0) + i2);
2028 }
2029
2030 T& ac(long i1, long i2, long i3) // for 3-dimensional array
2031 {
2032 if (qel.get_qel() != 3) {
2033 mcerr << "ERROR in DynArr::ac(long i1, long i2, long i3): "
2034 "qel.get_qel()!= 3,"
2035 << " qel.get_qel()=" << qel.get_qel() << '\n';
2036 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2037 << '\n';
2038 spexit(mcerr);
2039 }
2040#ifdef ALR_CHECK_EACH_BOUND
2041 if (i1 < 0 || i1 >= qel.acu(0)) {
2042 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i1 < 0 || i1 "
2043 ">= qel.acu(0)\n";
2044 Iprint2n(mcout, i1, qel[0]);
2045 spexit(mcerr);
2046 }
2047 if (i2 < 0 || i2 >= qel.acu(1)) {
2048 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i2 < 0 || i2 "
2049 ">= qel.acu(1)\n";
2050 Iprint2n(mcout, i2, qel[1]);
2051 spexit(mcerr);
2052 }
2053 if (i3 < 0 || i3 >= qel.acu(2)) {
2054 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i3 < 0 || i3 "
2055 ">= qel.acu(2)\n";
2056 Iprint2n(mcout, i3, qel[2]);
2057 spexit(mcerr);
2058 }
2059#ifdef DEBUG_DYNARR
2060 return el.acu(i1 * cum_qel.acu(0) + i2 * cum_qel.acu(1) + i3);
2061#else
2062 return el[i1 * cum_qel.acu(0) + i2 * cum_qel[1] + i3];
2063#endif
2064#else
2065 return el[i1 * cum_qel.acu(0) + i2 * cum_qel[1] + i3];
2066#endif
2067 // return el[i1*cum_qel[0] + i2*cum_qel[1] + i3];
2068 }
2069
2070 const T& ac(long i1, long i2, long i3) const // for 3-dimensional array
2071 {
2072 if (qel.get_qel() != 3) {
2073 mcerr << "ERROR in DynArr::ac(long i1, long i2, long i3): "
2074 "qel.get_qel()!= 3,"
2075 << " qel.get_qel()=" << qel.get_qel() << '\n';
2076 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2077 << '\n';
2078 spexit(mcerr);
2079 }
2080#ifdef ALR_CHECK_EACH_BOUND
2081 if (i1 < 0 || i1 >= qel.acu(0)) {
2082 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i1 < 0 || i1 "
2083 ">= qel.acu(0)\n";
2084 Iprint2n(mcout, i1, qel[0]);
2085 spexit(mcerr);
2086 }
2087 if (i2 < 0 || i2 >= qel.acu(1)) {
2088 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i2 < 0 || i2 "
2089 ">= qel.acu(1)\n";
2090 Iprint2n(mcout, i2, qel[1]);
2091 spexit(mcerr);
2092 }
2093 if (i3 < 0 || i3 >= qel.acu(2)) {
2094 mcerr << "Error in DynArr::ac(long i1, long i2, long i3): i3 < 0 || i3 "
2095 ">= qel.acu(2)\n";
2096 Iprint2n(mcout, i3, qel[2]);
2097 spexit(mcerr);
2098 }
2099#ifdef DEBUG_DYNARR
2100 return el.acu(i1 * cum_qel.acu(0) + i2 * cum_qel.acu(1) + i3);
2101#else
2102 return el[i1 * cum_qel.acu(0) + i2 * cum_qel[1] + i3];
2103#endif
2104#else
2105 return el[i1 * cum_qel.acu(0) + i2 * cum_qel[1] + i3];
2106#endif
2107 // return el[i1*cum_qel[0] + i2*cum_qel[1] + i3];
2108 }
2109
2110 long get_qel_lin(void) const { return el.get_qel(); }
2111
2112 // access to array as linear array
2113 inline T& ac_lin(long n) {
2114 long qelln = el.get_qel();
2115#ifdef ALR_CHECK_BOUND
2116 if (n >= 0 && n < qelln) return el[n];
2117 mcerr << "ERROR in T& DynArr::ac_lin(long n): "
2118 << "n is out of bounds, n=" << n << " qelln=" << qelln << '\n';
2119 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2120 << '\n';
2121 spexit(mcerr);
2122 return el[0];
2123#else
2124 return el[n];
2125#endif
2126 }
2127 inline const T& ac_lin(long n) const {
2128 long qelln = el.get_qel();
2129#ifdef ALR_CHECK_BOUND
2130 if (n >= 0 && n < qelln) return el[n];
2131 mcerr << "ERROR in T& DynArr::ac_lin(long n): "
2132 << "n is out of bounds, n=" << n << " qelln=" << qelln << '\n';
2133 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2134 << '\n';
2135 spexit(mcerr);
2136 return el[0];
2137#else
2138 return el[n];
2139#endif
2140 }
2141 // access to array as linear array always without check
2142 inline T& acu_lin(long n) { return el[n]; }
2143 inline const T& acu_lin(long n) const { return el[n]; }
2144
2145 void assignAll(const T& val);
2146
2147 long get_qdim(void) const { return qel.get_qel(); }
2148 const DynLinArr<long>& get_qel(void) const { return qel; }
2149 const DynLinArr<T>& get_el(void) const { return el; }
2150
2151 // The following is mainly for debug (diagnostic print):
2152 const DynLinArr<long>& get_cum_qel(void) const { return cum_qel; }
2153
2154 // void put_qel(const DynLinArr<long>& fqel, T* val=NULL);
2155 void put_qel(T* val = NULL);
2156 // 25.10.2006: Today I do not understand these following comments.
2157 // They looks like simple copy from these in DynLinArr.
2158 // creates array with size fqel
2159 // If old array existed, then
2160 // If it was less than fqel, it all is copied to new array
2161 // and the other elements are either remains not inited
2162 // or assignned *val.
2163 // else its fqel part is copyed to new array.
2164
2165 void clear(void) {
2166 qel.clear();
2167 cum_qel.clear();
2168 el.clear();
2169 }
2170
2171 int confirm_ind(const DynLinArr<long>& ind) { return gconfirm_ind(qel, ind); }
2173 return gconfirm_ind_ext(qel, ind);
2174 }
2176
2177 // Apply any function of one argument (of type T) to each element.
2178 template <class P>
2179 friend void apply1(DynArr<P>& ar, void (*fun)(P& f));
2180
2181 // Apply any function of two arguments
2182 // (first of which is of type T and the second is of type of address
2183 // of another function (possibly apply1) to each element.
2184 template <class P, class X>
2185 friend void apply2(DynArr<P>& ar, void (*fun1)(P& f, void (*fun21)(X& f)),
2186 void (*fun2)(X& f));
2187
2188 void check(void) const {
2189 qel.check();
2190 cum_qel.check();
2191 el.check();
2192 }
2193 int get_s_non_emplty(void) const {
2194 long q = qel.get_qel();
2195 if (q == 0) return 0;
2196 long n;
2197 for (n = 0; n < q; n++) {
2198 if (qel[n] <= 0) return 0;
2199 }
2200 return 1;
2201 }
2202 virtual DynArr* copy() const { return new DynArr(*this); }
2203 virtual ~DynArr() {}
2204
2205 private:
2206 mutable DynLinArr<long> qel;
2207 // Linear array with number of elements by each dimension
2208 mutable DynLinArr<long> cum_qel;
2209 // "cumulative qel": each element contains product
2210 // of next elements of qel.
2211 // The last element is always 1.
2212 // Used for fast search of proper element in el.
2213
2214 mutable DynLinArr<T> el;
2215 // Contains all elements.
2216 // The last index varies faster.
2217
2218 long calc_lin_ind(const DynLinArr<long>& ind) const {
2219 long i = 0;
2220 long n;
2221 long qdim1 = qel.get_qel() - 1;
2222 /*
2223 // This check is not necessary by two reasons
2224 // 1. The checks of this condition are made in calling functions.
2225 // 2. The correct condition is not != but >.
2226 if(qdim1 != ind.get_qel() - 1)
2227 {
2228 mcerr<<"ERROR in long DynArr::calc_lin_ind(const DynLinArr<long>& ind)
2229const\n";
2230 mcerr<<"qdim1 != ind.get_qel() - 1\n";
2231 Iprint2n(mcerr, qdim1, (ind.get_qel() - 1));
2232 spexit(mcerr);
2233 }
2234 */
2235 for (n = 0; n < qdim1; n++) {
2236#ifdef ALR_CHECK_EACH_BOUND
2237#ifdef DEBUG_DYNARR
2238 if (ind[n] < 0 || ind[n] >= qel[n]) {
2239 mcerr << "ERROR in long DynArr::calc_lin_ind(const DynLinArr<long>& "
2240 "ind) const\n";
2241 mcerr << "ind[n] < 0 || ind[n] >= qel[n]\n";
2242 Iprint3n(mcout, n, ind[n], qel[n]);
2243 Iprintn(mcout, qel);
2244 spexit(mcerr);
2245 }
2246#else
2247 if (ind.acu(n) < 0 || ind.acu(n) >= qel.acu(n)) {
2248 mcerr << "ERROR in long DynArr::calc_lin_ind(const DynLinArr<long>& "
2249 "ind) const\n";
2250 mcerr << "ind.acu(n) < 0 || ind.acu(n) >= qel.acu(n)\n";
2251 Iprint3n(mcout, n, ind[n], qel[n]);
2252 Iprintn(mcout, qel);
2253 spexit(mcerr);
2254 }
2255#endif
2256#endif
2257 i += ind[n] * cum_qel[n];
2258 }
2259#ifdef ALR_CHECK_EACH_BOUND
2260#ifdef DEBUG_DYNARR
2261 if (ind[qdim1] < 0 || ind[qdim1] >= qel[qdim1]) {
2262 mcerr << "ERROR in long DynArr::calc_lin_ind(const DynLinArr<long>& ind) "
2263 "const\n";
2264 mcerr << "ind[qdim1] < 0 || ind[qdim1] >= qel[qdim1]\n";
2265 Iprint3n(mcout, n, ind[qdim1], qel[qdim1]);
2266 Iprintn(mcout, qel);
2267 spexit(mcerr);
2268 }
2269#else
2270 if (ind.acu(qdim1) < 0 || ind.acu(qdim1) >= qel.acu(qdim1)) {
2271 mcerr << "ERROR in long DynArr::calc_lin_ind(const DynLinArr<long>& ind) "
2272 "const\n";
2273 mcerr << "ind.acu(qdim1) < 0 || ind.acu(qdim1) >= qel.acu(qdim1)\n";
2274 Iprint3n(mcout, n, ind[qdim1], qel[qdim1]);
2275 Iprintn(mcout, qel);
2276 spexit(mcerr);
2277 }
2278#endif
2279#endif
2280 i += ind[qdim1]; // the last index, for which multiplication by cum_qel
2281 // is not necessary.
2282 return i;
2283 }
2284};
2285
2286template <class T>
2288#ifdef DEBUG_DYNARR
2289 mcout << "DynArr<T>& DynArr<T>::operator=(const DynArr<T>& f)\n";
2290#endif
2291 if (this != &f) {
2292 // mcout<<"DynLinArr<T>& operator=(const DynLinArr<T>& f): long(el)="
2293 //<<long(el)<<'\n';
2294 check();
2295 f.check();
2296 qel = f.qel;
2297 cum_qel = f.cum_qel;
2298 el = f.el;
2299 }
2300 return *this;
2301}
2302
2303template <class T>
2304template <class D>
2306#ifdef DEBUG_DYNLINARR
2307 mcout << "DynArr<T>& DynArr<T>::operator=(const DynArr<D>& f)\n";
2308#endif
2309 if (this == &f) return *this;
2310 check();
2311 f.check();
2312 DynLinArr<long> fqel = f.get_qel();
2313 DynLinArr<long> fcum_qel = f.get_cum_qel();
2314 // for example, one of its elements.
2315 const long q = f.get_qel_lin();
2316 T* temp_el = (q > 0) ? (new T[q]) : (T*)NULL;
2317 for (long n = 0; n < q; n++) temp_el[n] = f.acu_lin(n);
2318 pass(q, fqel, fcum_qel, temp_el);
2319 return *this;
2320}
2321
2322template <class T>
2323void apply1(DynArr<T>& ar, void (*fun)(T& f)) {
2324 const long q = ar.el.get_qel();
2325 for (long n = 0; n < q; n++) (*fun)(ar.el[n]);
2326}
2327template <class T, class X>
2328void apply2(DynArr<T>& ar, void (*fun1)(T& f, void (*fun21)(X& f)),
2329 void (*fun2)(X& f)) {
2330 const long q = ar.el.get_qel();
2331 for (long n = 0; n < q; n++) (*fun1)(ar.el[n], fun2);
2332}
2333
2334int find_next_comb(const DynLinArr<long>& qel, DynLinArr<long>& f);
2335int find_prev_comb(const DynLinArr<long>& qel, DynLinArr<long>& f);
2336int find_next_comb_not_less(const DynLinArr<long>& qel, DynLinArr<long>& f);
2337
2338template <class T>
2340 public:
2342 : ncur(fdar->get_qdim()), dar((DynArr<T>*)fdar) {
2343 long n;
2344 long qdim1 = ncur.get_qel() - 1;
2345 if (qdim1 >= 0) {
2346 for (n = 0; n < qdim1; n++) ncur[n] = 0;
2347 ncur[qdim1] = -1;
2348 }
2349 }
2350 T* more(void) // Just next element. Why not "next", do not remember.
2351 {
2352 if (find_next_comb(dar->get_qel(), ncur))
2353 return &(dar->ac(ncur));
2354 else
2355 return NULL;
2356 }
2357
2358 T* current(void) // Element currently pointed by ncut.
2359 {
2360 long n;
2361 long qdim = ncur.get_qel();
2362 if (qdim <= 0) return NULL;
2363 for (n = 0; n < qdim; n++) {
2364 if (ncur[n] < 0 || ncur[n] >= dar->get_qel()[n]) return NULL;
2365 }
2366 return &(dar->ac(ncur));
2367 }
2368
2369 T* less(void) // Switch current to previous.
2370 // Again do not remember why not" prev"
2371 {
2372 if (find_prev_comb(dar->get_qel(), ncur))
2373 return &(dar->ac(ncur));
2374 else
2375 return NULL;
2376 }
2377
2378 const DynLinArr<long>& get_ncur(void) const { return ncur; }
2379
2380 private:
2381 DynLinArr<long> ncur;
2382 DynArr<T>* dar;
2383};
2384
2385extern DynLinArr<long> qel_communicat;
2386
2387template <class T>
2389 // by default val=NULL
2390{
2391 check();
2392 if (qel.get_qel() == 0) {
2393 *this = DynArr<T>(qel_communicat, val);
2394 return;
2395 }
2396
2397 DynArr<T> datemp(qel_communicat, val); // all init to val
2398 IterDynArr<T> iter(&datemp);
2399 T* at;
2400 while ((at = iter.more()) != NULL) {
2401 if (confirm_ind_ext(iter.get_ncur()))
2402 *at = acp(iter.get_ncur()); // change to old values where they were
2403 }
2404 *this = datemp;
2405}
2406
2407template <class T>
2408int operator==(const DynLinArr<T>& f1, const DynLinArr<T>& f2) {
2409 if (f1.get_qel() != f2.get_qel()) return 0;
2410 long q = f1.get_qel();
2411 long n;
2412 for (n = 0; n < q; n++) {
2413 if (!(f1.acu(n) == f2.acu(n))) return 0;
2414 }
2415 return 1;
2416}
2417
2418template <class T, class P>
2419int apeq_mant(const DynLinArr<T>& f1, const DynLinArr<T>& f2, P prec) {
2420 if (f1.get_qel() != f2.get_qel()) return 0;
2421 long q = f1.get_qel();
2422 long n;
2423 for (n = 0; n < q; n++) {
2424 if (!apeq_mant(f1.acu(n), f2.acu(n), prec)) return 0;
2425 }
2426 return 1;
2427}
2428
2429template <class T>
2430int operator!=(const DynLinArr<T>& f1, const DynLinArr<T>& f2) {
2431 if (f1 == f2)
2432 return 0;
2433 else
2434 return 1;
2435}
2436
2437template <class T>
2438int operator==(const DynArr<T>& f1, const DynArr<T>& f2) {
2439 if (f1.get_qel() != f2.get_qel()) return 0;
2440 if (f1.get_el() != f2.get_el()) return 0;
2441 return 1;
2442}
2443
2444template <class T, class P>
2445int apeq_mant(const DynArr<T>& f1, const DynArr<T>& f2, P prec) {
2446 if (f1.get_qel() != f2.get_qel()) return 0;
2447 if (!apeq_mant(f1.get_el(), f2.get_el(), prec)) return 0;
2448 return 1;
2449}
2450
2451template <class T>
2452int operator!=(const DynArr<T>& f1, const DynArr<T>& f2) {
2453 if (f1.get_qel() == f2.get_qel()) return 0;
2454 if (f1.get_el() == f2.get_el()) return 0;
2455 return 1;
2456}
2457
2458template <class T>
2459void DynArr<T>::assignAll(const T& val) {
2460 check();
2461 // try faster and simpler way (30.10.2006):
2462 el.assignAll(val);
2463 /*
2464 IterDynArr<T> iter(this);
2465 T* at;
2466 while( (at=iter.more()) != NULL )
2467 {
2468 *at=val;
2469 }
2470 */
2471}
2472
2473template <class T, class X>
2474void copy_DynArr(const DynArr<T>& s, DynArr<X>& d) {
2475 mfunnamep(
2476 "template<class T, class X> void copy_DynArr(const DynArr<T>& s, "
2477 "DynArr<X>& d)");
2478 s.check();
2479 d.check();
2480 d = DynArr<X>(s.get_qel(), NULL);
2481 IterDynArr<T> iter(&s);
2482 T* at;
2483 while ((at = iter.more()) != NULL) {
2484 const DynLinArr<long>& ncur = iter.get_ncur();
2485 d.ac(ncur) = *at;
2486 }
2487}
2488
2489// Convert types of elements from T to X.
2490template <class T, class X>
2492 mfunnamep(
2493 "template<class T, class X> void convert_DynArr(const DynArr<T>& "
2494 "s, DynArr<X>& d)");
2495 s.check();
2496 d.check();
2497 d = DynArr<X>(s.get_qel(), NULL);
2498 IterDynArr<T> iter(&s);
2499 T* at;
2500 while ((at = iter.more()) != NULL) {
2501 const DynLinArr<long>& ncur = iter.get_ncur();
2502 d.ac(ncur) = X(*at);
2503 }
2504}
2505
2506template <class T>
2508 check();
2509 DynArr<T> r(1, qel);
2510 long n;
2511 for (n = 0; n < qel; n++) {
2512 r.ac(0, n) = el[n];
2513 }
2514 return r;
2515}
2516template <class T>
2518 mfunnamep("template<class T> DynArr<T> DynArr<T>::top(void)");
2519 check();
2520 long qdim = get_qdim();
2521 check_econd11(qdim, != 2, mcerr);
2522 long n1, n2;
2523 DynArr<T> r(qel[1], qel[0]);
2524 for (n1 = 0; n1 < qel[0]; n1++) {
2525 for (n2 = 0; n2 < qel[1]; n2++) {
2526 r.ac(n2, n1) = ac(n1, n2);
2527 }
2528 }
2529 return r;
2530}
2531
2532template <class T>
2534 // mcout<<"template<class T> DynLinArr<T>::DynLinArr(const DynArr<T>& f):\n";
2535 f.check();
2536 long qdim = f.get_qdim();
2537 if (qdim != 1) {
2538 mcerr << "ERROR in DynLinArr<T>::DynLinArr(const DynArr<T>& f):\n"
2539 << "f.get_qdim() != 1, f.get_qdim()=" << f.get_qdim() << '\n';
2540 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2541 << '\n';
2542 spexit(mcerr);
2543 }
2544 const DynLinArr<long>& qelem = f.get_qel();
2545 qel = qelem[0];
2546 // mcout<<"qel="<<qel<<'\n';
2547 if (qel > 0) {
2548 el = new T[qel];
2549 for (long n = 0; n < qel; n++) el[n] = f.ac(n);
2550 } else
2551 el = NULL;
2552}
2553
2554template <class T>
2555DynLinArr<T>::DynLinArr(const DynArr<T>& f, int n_of_dim,
2556 // 0 - first dim) 1 - second dim)
2557 long roc_number)
2558 // takes only mentioned raw or column.
2559{
2560 f.check();
2561 long qdim = f.get_qdim();
2562 if (qdim != 2) {
2563 mcerr << "ERROR in DynLinArr<T>::DynLinArr(const DynArr<T>& f, int "
2564 "n_of_dim,long roc_number):\n"
2565 << "f.get_qdim() != 2, f.get_qdim()=" << f.get_qdim() << '\n';
2566 mcerr << "Type of T is (in internal notations) " << typeid(T).name()
2567 << '\n';
2568 spexit(mcerr);
2569 }
2570 const DynLinArr<long>& qelem = f.get_qel();
2571 if (n_of_dim == 0) {
2572 qel = qelem[1];
2573 } else {
2574 qel = qelem[0];
2575 }
2576 // mcout<<"qel="<<qel<<'\n';
2577 if (qel > 0) {
2578 el = new T[qel];
2579 long n;
2580 if (n_of_dim == 0) {
2581 for (n = 0; n < qel; n++) el[n] = f.ac(roc_number, n);
2582 } else {
2583 for (n = 0; n < qel; n++) el[n] = f.ac(n, roc_number);
2584 }
2585 }
2586}
2587
2588template <class T>
2589std::ostream& operator<<(std::ostream& file, const DynArr<T>& f) {
2590 // mfunnamep("template<class T> std::ostream& operator<<(std::ostream& file,
2591 // const DynArr<T>& f)");
2592 f.check();
2593 Ifile << "DynArr<T>: qdim=" << f.get_qdim() << '\n';
2594 indn.n += 2;
2595 if (s_short_output > 0) {
2596 Ifile << noindent << f.get_qel() << yesindent;
2597 } else {
2598 Ifile << "qel=" << noindent << f.get_qel() << yesindent;
2599 Ifile << "cum_qel=" << noindent << f.get_cum_qel() << yesindent;
2600 }
2601 if (f.get_s_non_emplty() == 1) {
2602 if (s_short_output == 0) {
2603 Ifile << "Content element by element:\n";
2604 Ifile << "(The first number is sequencial number, then there are "
2605 "indexes, the last is the element)\n";
2606 // DynArr<T>& ff(f);
2607 }
2608 long nseq = 0;
2609 IterDynArr<T> iter_f(&((DynArr<T>&)f));
2610 T* at;
2611 while ((at = iter_f.more()) != NULL) {
2612 std::ostringstream ost;
2613 if (s_short_output == 0) {
2614 // Ifile<<"ncur="<<noindent<<iter_f.get_ncur()<<yesindent;
2615 Ifile << "nseq=" << std::setw(5) << nseq << " ncur=";
2616 long n;
2617 for (n = 0; n < iter_f.get_ncur().get_qel(); n++) {
2618 file << ' ' << std::setw(5) << iter_f.get_ncur()[n];
2619 }
2620 ost << indn << " element=" << noindent << (*at) << yesindent;
2621 } else {
2622 ost << indn << noindent << (*at) << yesindent;
2623 }
2624 put_one_n(ost);
2625 file << ost.str();
2626 nseq++;
2627 }
2628 file << yesindent;
2629 } else {
2630 if (s_short_output == 0) {
2631 Ifile << "Content is empty.\n";
2632 }
2633 }
2634 indn.n -= 2;
2635 return file;
2636}
2637/*
2638template<class T>
2639void DybArr<T>::short_output(std::ostream& file)
2640{
2641 mfunnamep("template<class T> void DybArr<T>::short_output(std::ostream&
2642file))");
2643 f.check();
2644 Ifile<<"DynArr<T>: qdim="<<f.get_qdim()<<'\n';
2645 indn.n+=2;
2646 qel.short_output(file);
2647 if(f.get_s_non_emplty() == 1)
2648 {
2649 long nseq=0;
2650 IterDynArr<T> iter_f( &((DynArr<T>&) f));
2651 T* at;
2652 while( (at=iter_f.more()) != NULL )
2653 {
2654 std::ostringstream ost;
2655 ost<<indn<<noindent<<(*at)<<yesindent;
2656 put_one_n(ost);
2657 file<<ost.str();
2658 nseq++;
2659 }
2660 file<<yesindent;
2661 }
2662 indn.n-=2;
2663 return file;
2664}
2665*/
2666template <class T>
2667std::istream& operator>>(std::istream& file, DynArr<T>& f) {
2668 mfunnamep(
2669 "template<class T> istream& operator>>(istream& file, DynArr<T>& f)");
2670 definp_endpar dep(&file, 0, 1, 0, s_short_output);
2671 long qdim = 0;
2672 dep.s_short = 0;
2673 DEFINPAP(qdim);
2674 dep.s_short = s_short_output;
2675 check_econd11(qdim, < 0, mcerr);
2676 if (s_short_output == 0) {
2677 set_position("qel=DynLinArr<T>:", *dep.istrm, dep.s_rewind, dep.s_req_sep);
2678 } else {
2679 set_position("DynLinArr<T>:", *dep.istrm, dep.s_rewind, dep.s_req_sep);
2680 }
2681 DynLinArr<long> qel_loc;
2682 // mcout<<"now will read qel_loc\n";
2683 file >> qel_loc;
2684 // mcout<<"qel_loc is read\n";
2685 if (s_short_output == 0) {
2686 set_position("cum_qel=DynLinArr<T>:", *dep.istrm, dep.s_rewind,
2687 dep.s_req_sep);
2688 DynLinArr<long> cum_qel_loc;
2689 file >> cum_qel_loc; // this is in general unnecessary
2690 }
2691 if (qel_loc.get_qel() > 0) {
2692 f.pilfer(DynArr<T>(qel_loc, NULL));
2693 long nseq;
2694 long n;
2695 long qseq = qel_loc[0];
2696 for (n = 1; n < qel_loc.get_qel(); n++) {
2697 qseq *= qel_loc[n];
2698 }
2699 for (n = 0; n < qseq; n++) {
2700 if (s_short_output == 0) {
2701 DEFINPAP(nseq);
2702 check_econd12(nseq, !=, n, mcerr);
2703 DynLinArr<long> ncur(qel_loc.get_qel());
2704 set_position("ncur=", *dep.istrm, dep.s_rewind, dep.s_req_sep);
2705 long m;
2706 for (m = 0; m < qel_loc.get_qel(); m++) {
2707 file >> ncur[m];
2708 }
2709 // T element;
2710 // DEFINPAP(element);
2711 // f.ac(ncur) = element;
2712 set_position("element=", *dep.istrm, dep.s_rewind, dep.s_req_sep);
2713 }
2714 file >> f.ac_lin(n);
2715 }
2716 } else {
2717 if (s_short_output == 0) {
2718 // just pass to end
2719 set_position("Content is empty.", *dep.istrm, dep.s_rewind,
2720 dep.s_req_sep);
2721 }
2722 f.pilfer(DynArr<T>());
2723 }
2724 return file;
2725}
2726
2727/*
2728template<class T>
2729void DynArr<T>::short_read(istream& file)
2730{
2731 mfunnamep("template<class T> void DynArr<T>::short_read(istream& file)");
2732 definp_endpar dep(&file, 0, 1, 0);
2733 long qdim=0;
2734 DEFINPAP(qdim);
2735 check_econd11(qdim, < 0 , mcerr);
2736 DynLinArr<long> qel_loc;
2737 qel_loc.short_read(file);
2738 // generate cum
2739 if(qel_loc.get_qel() > 0 )
2740 {
2741 f.pilfer(DynArr<T>(qel_loc, NULL));
2742 long nseq;
2743 long n;
2744 long qseq=qel[0];
2745 for(n=1; n<el.get_qel(); n++)
2746 {
2747 qseq*=el[n];
2748 }
2749 for(n=0; n<qseq; n++)
2750 {
2751 file>>f.ac(ncur);
2752 }
2753 }
2754 else
2755 {
2756 // just pass to end
2757 set_position("Content is empty.",
2758 *dep.istrm, dep.s_rewind, dep.s_req_sep);
2759 }
2760 return file;
2761}
2762*/
2763
2764template <class T>
2765void print_DynArr(std::ostream& file, const DynArr<T>& f, int l) {
2766 // mfunnamep("template<class T> oid print_DynArr(std::ostream& file, const
2767 // DynArr<T>& f, int l)");
2768 f.check();
2769 // Ifile<<"DynArr<T>: qdim="<<f.get_qdim()
2770 // <<" qel="<<noindent<<f.get_qel()<<yesindent<<'\n';
2771 Ifile << "DynArr<T>: qdim=" << f.get_qdim() << '\n';
2772 indn.n += 2;
2773 Ifile << "qel=" << noindent << f.get_qel() << yesindent;
2774 Ifile << "cum_qel=" << noindent << f.get_cum_qel() << yesindent;
2775 Ifile << "Content element by element:\n";
2776 Ifile << "(The first number is sequencial number, then there are indexes, "
2777 "the last is the element)\n";
2778 // DynArr<T>& ff(f);
2779 long nseq = 0;
2780 IterDynArr<T> iter_f(&((DynArr<T>&)f));
2781 T* at;
2782 while ((at = iter_f.more()) != NULL) {
2783 // Ifile<<"ncur="<<noindent<<iter_f.get_ncur()<<yesindent;
2784 Ifile << "nseq=" << std::setw(5) << nseq << " ncur=";
2785 long n;
2786 for (n = 0; n < iter_f.get_ncur().get_qel(); n++) {
2787 file << ' ' << std::setw(5) << iter_f.get_ncur()[n];
2788 }
2789 // file<<'\n';
2790 // Ifile<<"element="<<noindent; at->print(file, l);
2791 // file<<yesindent<<'\n';
2792 std::ostringstream ost;
2793 ost << indn << " element=" << noindent;
2794 at->print(ost, l);
2795 ost << yesindent;
2796 put_one_n(ost);
2797 file << ost.str();
2798 }
2799 file << yesindent;
2800 indn.n -= 2;
2801}
2802
2803// New experimental approach.
2804// give the width of field, which is put in setw().
2805// Whether the array will be printed in single lines
2806// or by columns, is determined by whether 80 symbols are enough
2807void print_DynArr_int_w(std::ostream& file, const DynArr<int>& f, int w);
2808
2809void print_DynArr_float(std::ostream& file, const DynArr<float>& f);
2810void print_DynArr_double(std::ostream& file, const DynArr<double>& f);
2811// ^Identical functions
2812// See AbsArrD for similar function with DoubleAc
2813
2814#define Iprintda_double(file, name) \
2815 file << indn << #name << "=" << noindent; \
2816 print_DynArr_double(file, name);
2817// See AbsArrD for similar function with DoubleAc
2818
2819}
2820
2821#endif
#define check_econd11(a, signb, stream)
#define mfunnamep(string)
#define spexit(stream)
#define check_econd12(a, sign, b, stream)
IndexingProvider(DynArr< D > &farr, long fq_deref_ind, long fcurrent_pos)
Definition AbsArr.h:1564
IndexingProvider< D > & operator[](long n)
Definition AbsArr.h:1598
const IndexingProvider< D > & operator[](long n) const
Definition AbsArr.h:1623
D & operator=(const D &f)
Definition AbsArr.h:1581
const T & ac(long i1, long i2, long i3) const
Definition AbsArr.h:2070
int confirm_ind(const DynLinArr< long > &ind)
Definition AbsArr.h:2171
DynArr(long fqel1, long fqel2, long fqel3, T *val=NULL)
Definition AbsArr.h:1438
const DynLinArr< T > & get_el(void) const
Definition AbsArr.h:2149
void clear(void)
Definition AbsArr.h:2165
const T & acp(const DynLinArr< long > &ind) const
Definition AbsArr.h:1840
DynArr(const DynArr< T > &f)
Definition AbsArr.h:1502
DynArr(const DynLinArr< long > &fqel, T *val)
Definition AbsArr.h:1486
DynArr(long fqel, T val, ArgInterp_Val)
Definition AbsArr.h:1379
T & ac(long i1, long i2)
Definition AbsArr.h:1886
T & acu(long i1, long i2)
Definition AbsArr.h:2020
const T & ac(const DynLinArr< long > &ind) const
Definition AbsArr.h:1760
DynArr(long fqel, const T *ar, ArgInterp_Arr)
Definition AbsArr.h:1390
T & acu(long i1)
Definition AbsArr.h:1716
int confirm_ind_ext(const DynLinArr< long > &ind)
Definition AbsArr.h:2172
IndexingProvider< T > operator[](long n)
Definition AbsArr.h:1653
virtual DynArr * copy() const
Definition AbsArr.h:2202
const DynLinArr< long > & get_cum_qel(void) const
Definition AbsArr.h:2152
void check(void) const
Definition AbsArr.h:2188
const T & ac(long i) const
Definition AbsArr.h:1706
T & ac(long i)
Definition AbsArr.h:1696
DynArr(const DynArr< T > &f, Pilfer)
Definition AbsArr.h:1508
DynArr(long fqel1, long fqel2, long fqel3, long fqel4, T *val=NULL)
Definition AbsArr.h:1452
const T & acu(long i1) const
Definition AbsArr.h:1720
void pilfer(const DynArr< T > &f)
Definition AbsArr.h:1515
DynArr< T > & operator=(const DynArr< T > &f)
Definition AbsArr.h:2287
DynArr(long fqel1, long fqel2, T val, ArgInterp_Val)
Definition AbsArr.h:1422
long get_qel_lin(void) const
Definition AbsArr.h:2110
T & ac_lin(long n)
Definition AbsArr.h:2113
const IndexingProvider< T > operator[](long n) const
Definition AbsArr.h:1674
void assignAll(const T &val)
Definition AbsArr.h:2459
const T & acu(const DynLinArr< long > &ind) const
Definition AbsArr.h:1878
friend void apply2(DynArr< P > &ar, void(*fun1)(P &f, void(*fun21)(X &f)), void(*fun2)(X &f))
DynArr< T > & operator=(const DynArr< D > &f)
Definition AbsArr.h:2305
const T & acu(long i1, long i2) const
Definition AbsArr.h:2025
DynArr(void)
Definition AbsArr.h:1366
const T & ac(long i1, long i2) const
Definition AbsArr.h:1953
const DynLinArr< long > & get_qel(void) const
Definition AbsArr.h:2148
friend void apply1(DynArr< P > &ar, void(*fun)(P &f))
DynArr(long fqel, T *val=NULL)
Definition AbsArr.h:1368
DynArr(long fqel1, long fqel2, T *val=NULL)
Definition AbsArr.h:1408
DynArr(const DynLinArr< long > &fqel, T val, ArgInterp_Val)
Definition AbsArr.h:1472
DynArr< T > top(void)
Definition AbsArr.h:2517
void put_qel(T *val=NULL)
Definition AbsArr.h:2388
T & acu_lin(long n)
Definition AbsArr.h:2142
T & ac(long i1, long i2, long i3)
Definition AbsArr.h:2030
int get_s_non_emplty(void) const
Definition AbsArr.h:2193
long get_qdim(void) const
Definition AbsArr.h:2147
virtual ~DynArr()
Definition AbsArr.h:2203
T & ac(const DynLinArr< long > &ind)
Definition AbsArr.h:1726
void pass(long q, DynLinArr< long > fqel, DynLinArr< long > fcum_qel, T *fel)
Definition AbsArr.h:1546
DynArr(const DynLinArr< T > &f)
Definition AbsArr.h:1400
const T & acu_lin(long n) const
Definition AbsArr.h:2143
T & acu(const DynLinArr< long > &ind)
Definition AbsArr.h:1871
const T & ac_lin(long n) const
Definition AbsArr.h:2127
T & acp(const DynLinArr< long > &ind)
Definition AbsArr.h:1805
const T & last_el(void) const
Definition AbsArr.h:269
DynLinArr(const DynLinArr< T > &f, Pilfer)
Definition AbsArr.h:192
virtual DynLinArr * copy() const
Definition AbsArr.h:417
void clear(void)
Definition AbsArr.h:313
void sort_select_decreasing(DynLinArr< long > &sort_ind, long q_to_sort=0) const
Definition AbsArr.h:802
DynLinArr(long fqel, const T *ar, ArgInterp_Arr)
Definition AbsArr.h:146
long get_qel(void) const
Definition AbsArr.h:283
void put_qel(long fqel)
Definition AbsArr.h:527
DynLinArr< T > & operator=(const DynLinArr< D > &f)
Definition AbsArr.h:494
T & acu(long n)
Definition AbsArr.h:247
void sort(DynLinArr< long > &sort_ind, long q_to_sort=0) const
Definition AbsArr.h:682
const T & acu(long n) const
Definition AbsArr.h:251
void put_qel(long fqel, const T *val, ArgInterp_SingleAdr t)
Definition AbsArr.h:569
DynLinArr(long fqel, const T &val)
Definition AbsArr.h:126
void pilfer(const DynLinArr< T > &f)
Definition AbsArr.h:315
friend void apply1(DynLinArr< P > &ar, void(*fun)(P &f))
void pass(long fqel, T *fel)
Definition AbsArr.h:183
DynLinArr(const DynArr< T > &f)
Definition AbsArr.h:2533
void increment(const T &val)
Definition AbsArr.h:308
void sort(long q_to_sort=0)
Definition AbsArr.h:625
void check(void) const
Definition AbsArr.h:433
void increment(const T *val=NULL)
Definition AbsArr.h:303
DynLinArr(const DynArr< T > &f, int n_of_dim, long roc_number)
Definition AbsArr.h:2555
T & operator[](long n)
Definition AbsArr.h:221
friend void apply2(DynLinArr< P > &ar, void(*fun1)(P &f, void(*fun21)(X &f)), void(*fun2)(X &f))
void put_qel(long fqel, const T &val)
Definition AbsArr.h:300
DynLinArr & assignAll(const T &f)
Definition AbsArr.h:207
DynLinArr< T > & operator=(const DynLinArr< T > &f)
Definition AbsArr.h:468
void sort_select_increasing(DynLinArr< long > &sort_ind, long q_to_sort=0) const
Definition AbsArr.h:738
const T & operator[](long n) const
Definition AbsArr.h:234
T & last_el(void)
Definition AbsArr.h:255
virtual ~DynLinArr()
Definition AbsArr.h:406
DynLinArr(long fqel)
Definition AbsArr.h:106
DynLinArr< T > & assignAll1(const X &f)
Definition AbsArr.h:213
DynLinArr(const DynLinArr< T > &f)
Definition AbsArr.h:516
DynArr< T > top(void)
Definition AbsArr.h:2507
DynLinArr(void)
Definition AbsArr.h:105
IterDynArr(const DynArr< T > *fdar)
Definition AbsArr.h:2341
T * current(void)
Definition AbsArr.h:2358
const DynLinArr< long > & get_ncur(void) const
Definition AbsArr.h:2378
T * less(void)
Definition AbsArr.h:2369
T * more(void)
Definition AbsArr.h:2350
IterDynLinArr(DynLinArr< T > *fdar)
Definition AbsArr.h:1255
T * current(void)
Definition AbsArr.h:1263
long get_ncur(void)
Definition AbsArr.h:1277
virtual void print(std::ostream &file, int l=1) const
Definition AbsPtr.cpp:152
std::istream * istrm
Definition definp.h:34
#define DEFINPAP(name)
Definition definp.h:78
Definition BGMesh.cpp:6
void print_DynArr_double(std::ostream &file, const DynArr< double > &f)
Definition AbsArr.cpp:315
void print_DynLinArr(std::ostream &file, const DynLinArr< T > &f, int l)
Definition AbsArr.h:1094
DynLinArr< T > merge(const DynLinArr< T > &fd1, long qfd1, const DynLinArr< T > &fd2, long qfd2)
Definition AbsArr.h:1342
int s_short_output
Definition prstream.cpp:25
void print_DynArr(std::ostream &file, const DynArr< T > &f, int l)
Definition AbsArr.h:2765
std::istream & operator>>(std::istream &file, EqualStepCoorMesh< T > &f)
Definition tline.h:229
std::ostream & noindent(std::ostream &f)
Definition prstream.cpp:17
long max_qel_DynLinArr
Definition AbsArr.cpp:17
void apply2(DynLinArr< T > &ar, void(*fun1)(T &f, void(*fun21)(X &f)), void(*fun2)(X &f))
Definition AbsArr.h:427
void print_DynArr_float(std::ostream &file, const DynArr< float > &f)
Definition AbsArr.cpp:367
void print_DynLinArr_int_double3(std::ostream &file, const DynLinArr< int > &iar, const DynLinArr< double > &dar1, const DynLinArr< double > &dar2, const DynLinArr< double > &dar3)
Definition AbsArr.cpp:174
int operator!=(manip_absvol_treeid &tid1, manip_absvol_treeid &tid2)
Definition volume.h:61
std::ostream & operator<<(std::ostream &file, const BGMesh &bgm)
Definition BGMesh.cpp:37
Pilfer
Definition AbsPtr.h:184
@ steal
Definition AbsPtr.h:185
int ifequal(const DynLinArr< T > &fd1, const DynLinArr< T > &fd2, long qfirst=-1)
Definition AbsArr.h:1302
const int pq_arrelem_in_line
Definition AbsArr.h:1173
void print_DynLinArr_long(std::ostream &file, const DynLinArr< long > &f)
Definition AbsArr.cpp:37
void print_DynLinArr_int_double(std::ostream &file, const DynLinArr< int > &iar, const DynLinArr< double > &dar)
Definition AbsArr.cpp:141
int find_prev_comb(const DynLinArr< long > &qel, DynLinArr< long > &f)
Definition AbsArr.cpp:501
void print_DynLinArr_double2(std::ostream &file, const DynLinArr< double > &f1, const DynLinArr< double > &f2)
Definition AbsArr.cpp:97
int gconfirm_ind_ext(const DynLinArr< long > &qel, const DynLinArr< long > &ind)
Definition AbsArr.cpp:433
void put_one_n(std::ostringstream &ost)
Definition String.h:73
void print_DynLinArr_float(std::ostream &file, const DynLinArr< float > &f)
Definition AbsArr.cpp:57
int operator==(const circumf &f1, const circumf &f2)
Definition circumf.cpp:34
void apply1(DynLinArr< T > &ar, void(*fun)(T &f))
Definition AbsArr.h:422
void copy_DynLinArr(const T &s, X &d)
Definition AbsArr.h:1211
long append(const T &t, DynLinArr< T > &dla, long &qael, T *tempt=NULL, long new_qel=0)
Definition AbsArr.h:947
long set_position(const std::string &word, std::istream &istrm, int s_rewind, int s_req_sep)
Definition definp.cpp:23
int gconfirm_ind(const DynLinArr< long > &qel, const DynLinArr< long > &ind)
Definition AbsArr.cpp:418
void print_DynLinArr_double(std::ostream &file, const DynLinArr< double > &f)
Definition AbsArr.cpp:77
void print_DynArr_int_w(std::ostream &file, const DynArr< int > &f, int w)
Definition AbsArr.cpp:225
void convert_DynLinArr(const T &s, X &d)
Definition AbsArr.h:1225
void print_adr_DynLinArr(std::ostream &file, const DynLinArr< T > &f, int l, long q)
Definition AbsArr.h:1144
int find_next_comb(const DynLinArr< long > &qel, DynLinArr< long > &f)
Definition AbsArr.cpp:450
int find_next_comb_not_less(const DynLinArr< long > &qel, DynLinArr< long > &f)
Definition AbsArr.cpp:483
void definp_any_par(T &inp, const std::string &word, const definp_endpar &dep, int fs_short=0)
Definition definp.h:55
void assignAll_1(DynLinArr< T > &f, const T1 &ft)
Definition AbsArr.h:1244
void convert_DynArr(const DynArr< T > &s, DynArr< X > &d)
Definition AbsArr.h:2491
int apeq_mant(const T &x1, const T &x2, T prec)
Definition minmax.h:55
indentation indn
Definition prstream.cpp:15
void copy_DynArr(const DynArr< T > &s, DynArr< X > &d)
Definition AbsArr.h:2474
void print_DynLinArr_int(std::ostream &file, const DynLinArr< int > &f)
Definition AbsArr.cpp:19
std::ostream & yesindent(std::ostream &f)
Definition prstream.cpp:21
DynLinArr< long > qel_communicat
Definition AbsArr.cpp:519
void put_qel_1(DynLinArr< T > &f, long fq)
Definition AbsArr.h:1235
#define mcout
Definition prstream.h:126
#define Iprint3n(file, name1, name2, name3)
Definition prstream.h:232
#define Ifile
Definition prstream.h:195
#define mcerr
Definition prstream.h:128
#define Iprintn(file, name)
Definition prstream.h:204
#define Iprint2n(file, name1, name2)
Definition prstream.h:219