source: Sophya/trunk/SophyaLib/TArray/basarr.cc@ 1543

Last change on this file since 1543 was 1517, checked in by ansari, 24 years ago

Rajout classe ComplexMathArray pour operations sur tableaux complexes (real(), imag() ,...) - Ajout fonctions TArray::ReadASCII() (pas encore implementee) et TArray::WriteASCII() - Reza 12/6/2001

File size: 20.2 KB
Line 
1// Base class for numerical arrays
2// R. Ansari, C.Magneville 03/2000
3
4#include "machdefs.h"
5#include <stdio.h>
6#include <stdlib.h>
7#include "pexceptions.h"
8#include "basarr.h"
9
10/*!
11 \class SOPHYA::BaseArray
12 \ingroup TArray
13 Base class for template arrays
14 No data are connected to this class.
15
16 Define base methods, enum and defaults for TArray , TMatrix and TVector.
17*/
18
19// Variables statiques globales
20char * BaseArray::ck_op_msg_[6] =
21 {"???", "Size(int )", "IsPacked(int )"
22 ,"Stride(int )", "ElemCheckBound()", "operator()" };
23int_4 BaseArray::max_nprt_ = 50;
24int_4 BaseArray::prt_lev_ = 0;
25short BaseArray::default_memory_mapping = CMemoryMapping;
26short BaseArray::default_vector_type = ColumnVector;
27sa_size_t BaseArray::openmp_size_threshold = 200000;
28
29// ------ Methodes statiques globales --------
30
31//! Set maximum number of printed elements and print level
32/*!
33 \param nprt : maximum number of print
34 \param lev : print level
35*/
36void BaseArray::SetMaxPrint(int_4 nprt, int_4 lev)
37{
38 max_nprt_ = nprt;
39 prt_lev_ = (lev < 3) ? lev : 3;
40}
41
42//! Set Size threshold for parallel routine call
43/*!
44 \param thr : thresold value
45*/
46void BaseArray::SetOpenMPSizeThreshold(sa_size_t thr)
47{
48 openmp_size_threshold = thr;
49}
50
51
52//! Compute totale size
53/*!
54 \param ndim : number of dimensions
55 \param siz : array of size along the \b ndim dimensions
56 \param step[ndim] : step value
57 \param offset : offset value
58 \return Total size of the array
59*/
60sa_size_t BaseArray::ComputeTotalSize(int_4 ndim, const sa_size_t * siz, sa_size_t step, sa_size_t offset)
61{
62 sa_size_t rs = step;
63 for(sa_size_t k=0; k<ndim; k++) rs *= siz[k];
64 return(rs+offset);
65}
66
67//! Set Default Memory Mapping
68/*!
69 \param mm : Memory Mapping type
70 \verbatim
71 mm == CMemoryMapping : C like memory mapping
72 mm == FortranMemoryMapping : Fortran like memory mapping
73 \endverbatim
74 \verbatim
75 # ===== For Matrices
76 *** MATHEMATICS: m(row,column) with indexes running [1,n])
77 | 11 12 13 |
78 matrix Math = Mmath= | 21 22 23 |
79 | 31 32 33 |
80 *** IDL, \b FORTRAN: indexes data in \b row-major format:
81 indexes arrays in (column,row) order.
82 index IDL running [0,n[ ; index FORTRAN running [1,n]
83 M in memory: [ 11 12 13 : 21 22 23 : 31 32 33 : ... ]
84 line 1 : line 2 : line 3 : ...
85 ex: Midl(0,2) = Mfor(1,3) = Mmath(3,1) = 31
86 Midl(2,0) = Mfor(3,1) = Mmath(1,3) = 13
87 *** C: indexes data in \b column-major format:
88 indexes arrays in [row][column] order.
89 index C running [0,n[
90 M in memory: [ 11 21 31 : 12 22 32 : 13 23 33 : ... ]
91 column 1 : column 2 : column 3 : ...
92 ex: Mc[2][0] = Mmath(3,1) = 31
93 Mc[0][2] = Mmath(1,3) = 13
94 *** RESUME diff Idl/Fortan/C/Math:
95 Midl(col-1,row-1) = Mfor(col,row) = Mc[row-1][col-1] = Mmath(row,col)
96 TRANSPOSE(column-major array) --> row-major array
97 \endverbatim
98 \return default memory mapping value
99 */
100short BaseArray::SetDefaultMemoryMapping(short mm)
101{
102 default_memory_mapping = (mm != CMemoryMapping) ? FortranMemoryMapping : CMemoryMapping;
103 return default_memory_mapping;
104}
105
106//! Set Default Vector Type
107/*!
108 \param vt : vector type (ColumnVector,RowVector)
109 \return default vector type value
110 */
111short BaseArray::SetDefaultVectorType(short vt)
112{
113 default_vector_type = (vt != ColumnVector) ? RowVector : ColumnVector ;
114 return default_vector_type;
115}
116
117//! Select Memory Mapping
118/*!
119 Do essentially nothing.
120 \param mm : type of Memory Mapping (CMemoryMapping,FortranMemoryMapping)
121 \return return \b mm if it makes sense or default memory mapping value
122 \sa SetDefaultMemoryMapping
123 */
124short BaseArray::SelectMemoryMapping(short mm)
125{
126 if ( (mm == CMemoryMapping) || (mm == FortranMemoryMapping) ) return (mm) ;
127 else return (default_memory_mapping);
128}
129
130//! Select Vector type
131/*!
132 Do essentially nothing.
133 \param vt : vector type (ColumnVector,RowVector)
134 \return return \b vt if it makes sense or default vector type
135 \sa SetDefaultVectorType
136 */
137short BaseArray::SelectVectorType(short vt)
138{
139 if ((vt == ColumnVector) || (vt == RowVector)) return(vt);
140 else return(default_vector_type);
141}
142
143//! Update Memory Mapping
144/*!
145 Update variables marowi_ macoli_ veceli_
146 \param mm : type of Memory Mapping (CMemoryMapping,FortranMemoryMapping)
147 \sa SetDefaultMemoryMapping
148 */
149void BaseArray::UpdateMemoryMapping(short mm)
150{
151 short vt = default_vector_type;
152 if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) mm = default_memory_mapping;
153 if (mm == CMemoryMapping) {
154 marowi_ = 1; macoli_ = 0;
155 }
156 else {
157 marowi_ = 0; macoli_ = 1;
158 }
159
160 if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) ) {
161 // Choix automatique Vecteur ligne ou colonne
162 if ( size_[macoli_] == 1) veceli_ = marowi_;
163 else veceli_ = macoli_;
164 }
165 else veceli_ = (vt == ColumnVector ) ? marowi_ : macoli_;
166}
167
168//! Update Memory Mapping
169/*!
170 \param a : Array to be compared with
171 \param mm : type of Memory Mapping or memory mapping transfert
172 (SameMemoryMapping,AutoMemoryMapping,CMemoryMapping,FortranMemoryMapping)
173 \sa SetDefaultMemoryMapping
174 */
175void BaseArray::UpdateMemoryMapping(BaseArray const & a, short mm)
176{
177 short vt = default_vector_type;
178 if (mm == SameMemoryMapping) {
179 mm = ((a.marowi_ == 1) ? CMemoryMapping : FortranMemoryMapping);
180 vt = (a.marowi_ == a.veceli_) ? ColumnVector : RowVector;
181 }
182 else if (mm == AutoMemoryMapping) mm = default_memory_mapping;
183
184 if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) mm = default_memory_mapping;
185 if (mm == CMemoryMapping) {
186 marowi_ = 1; macoli_ = 0;
187 }
188 else {
189 marowi_ = 0; macoli_ = 1;
190 }
191 if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) ) {
192 // Choix automatique Vecteur ligne ou colonne
193 if ( size_[macoli_] == 1) veceli_ = marowi_;
194 else veceli_ = macoli_;
195 }
196 else veceli_ = (vt == ColumnVector ) ? marowi_ : macoli_;
197}
198
199//! Set Memory Mapping type
200/*!
201 Compute values for variables marowi_ macoli_ veceli_
202 \param mm : Memory Mapping type (SameMemoryMapping,AutoMemoryMapping
203 ,CMemoryMapping,FortranMemoryMapping)
204 \sa SetDefaultMemoryMapping
205 */
206void BaseArray::SetMemoryMapping(short mm)
207{
208 if (mm == SameMemoryMapping) return;
209 if (mm == AutoMemoryMapping) mm = default_memory_mapping;
210 if ( (mm != CMemoryMapping) && (mm != FortranMemoryMapping) ) return;
211 short vt = (marowi_ == veceli_) ? ColumnVector : RowVector;
212 if (mm == CMemoryMapping) {
213 marowi_ = 1; macoli_ = 0;
214 }
215 else {
216 marowi_ = 0; macoli_ = 1;
217 }
218 if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) ) {
219 // Choix automatique Vecteur ligne ou colonne
220 if ( size_[macoli_] == 1) veceli_ = marowi_;
221 else veceli_ = macoli_;
222 }
223 else veceli_ = (vt == ColumnVector ) ? marowi_ : macoli_;
224}
225
226//! Set Vector Type
227/*!
228 Compute values for variable veceli_
229 \param vt : vector type ()
230 \sa SetDefaultVectorType
231 */
232void BaseArray::SetVectorType(short vt)
233{
234 if (vt == SameVectorType) return;
235 if (vt == AutoVectorType) vt = default_vector_type;
236 if ( (ndim_ == 2) && ((size_[0] == 1) || (size_[1] == 1)) ) {
237 // Choix automatique Vecteur ligne ou colonne
238 if ( size_[macoli_] == 1) veceli_ = marowi_;
239 else veceli_ = macoli_;
240 }
241 else veceli_ = (vt == ColumnVector ) ? marowi_ : macoli_;
242}
243
244// -------------------------------------------------------
245// Methodes de la classe
246// -------------------------------------------------------
247
248//! Default constructor
249BaseArray::BaseArray()
250 : mInfo(NULL)
251{
252 ndim_ = 0;
253 for(int_4 k=0; k<BASEARRAY_MAXNDIMS; k++) step_[k] = size_[k] = 0;
254 totsize_ = 0;
255 minstep_ = 0;
256 moystep_ = 0;
257 offset_ = 0;
258 // Default for matrices : Memory organisation and Vector type
259 if (default_memory_mapping == CMemoryMapping) {
260 marowi_ = 1; macoli_ = 0;
261 }
262 else {
263 marowi_ = 0; macoli_ = 1;
264 }
265 veceli_ = (default_vector_type == ColumnVector ) ? marowi_ : macoli_;
266 arrtype_ = 0; // Default Array type, not a Matrix or Vector
267
268}
269
270//! Destructor
271BaseArray::~BaseArray()
272{
273}
274
275
276//! Returns true if the two arrays have compatible dimensions.
277/*!
278 \param a : array to be compared
279 \param smo : Return flag = true if the two arrays have the same memory organisation
280 \return true if \c NbDimensions() and \c Size() are equal, false if not
281
282 If the array (on which the operation is being performed, \c this)
283 is a \b Matrix or a \b Vector, the matrix dimensions \c NRows() \c NCols()
284 are checked. The flag \c smo is returned true if the two arrays, viewed
285 as a matrix have the same memory organisation.
286 Otherwise, (if the array is of not a Matrix or a Vector)
287 the size compatibility viewed as a TArray is checked <tt>
288 (Size(k) == a.Size(k), k=0,...NbDimensions()), </tt> disregard of the memory
289 organisation and the row and column index. The flag \c smo is returned true
290 in this case.
291*/
292bool BaseArray::CompareSizes(const BaseArray& a, bool& smo) const
293{
294 if (ndim_ != a.ndim_) return(false);
295 if (arrtype_ == 0) { // Simple TArray, not a matrix
296 smo = true;
297 for(int_4 k=0; k<ndim_; k++)
298 if (size_[k] != a.size_[k]) return(false);
299 return(true);
300 }
301 else {
302 smo = false;
303 if ( (size_[marowi_] != a.size_[a.marowi_]) ||
304 (size_[macoli_] != a.size_[a.macoli_]) ) return(false);
305 if (ndim_ > 2)
306 for(int_4 k=2; k<ndim_; k++)
307 if (size_[k] != a.size_[k]) return(false);
308 if ( (macoli_ == a.macoli_) && (marowi_ == a.marowi_) ||
309 (veceli_ == a.veceli_) ) smo = true;
310 return(true);
311 }
312}
313
314//! Change dimension if some size == 1
315void BaseArray::CompactAllDim()
316{
317 if (ndim_ < 2) return;
318 int_4 ndim = 0;
319 sa_size_t size[BASEARRAY_MAXNDIMS];
320 sa_size_t step[BASEARRAY_MAXNDIMS];
321 for(int_4 k=0; k<ndim_; k++) {
322 if (size_[k] < 2) continue;
323 size[ndim] = size_[k];
324 step[ndim] = step_[k];
325 ndim++;
326 }
327 if (ndim == 0) {
328 size[0] = size_[0];
329 step[0] = step_[0];
330 ndim = 1;
331 }
332 string exmsg = "BaseArray::CompactAllDim() ";
333 if (!UpdateSizes(ndim, size, step, offset_, exmsg)) throw( ParmError(exmsg) );
334 return;
335}
336
337//! Change dimension if some trailed size == 1
338void BaseArray::CompactTrailingDim()
339{
340 if (ndim_ < 2) return;
341 int_4 ndim = 0;
342 sa_size_t size[BASEARRAY_MAXNDIMS];
343 sa_size_t step[BASEARRAY_MAXNDIMS];
344 for(int_4 k=0; k<ndim_; k++) {
345 size[ndim] = size_[k];
346 step[ndim] = step_[k];
347 if (size_[k] > 1) ndim=k;
348 }
349 if (ndim == 0) ndim = 1;
350 string exmsg = "BaseArray::CompactTrailingDim() ";
351 if (!UpdateSizes(ndim, size, step, offset_, exmsg)) throw( ParmError(exmsg) );
352 return;
353}
354
355//! return minimum value for step[ndim]
356int_4 BaseArray::MinStepKA() const
357{
358 for(int_4 ka=0; ka<ndim_; ka++)
359 if (step_[ka] == minstep_) return((int)ka);
360 return(0);
361}
362
363//! return maximum value for step[ndim]
364int_4 BaseArray::MaxSizeKA() const
365{
366 int_4 ka = 0;
367 sa_size_t mx = size_[0];
368 for(int_4 k=1; k<ndim_; k++)
369 if (size_[k] > mx) { ka = k; mx = size_[k]; }
370 return(ka);
371}
372
373
374// Acces lineaire aux elements .... Calcul d'offset
375// --------------------------------------------------
376// Position de l'element 0 du vecteur i selon l'axe ka
377// --------------------------------------------------
378//! return position of first element for vector \b i alond \b ka th axe.
379sa_size_t BaseArray::Offset(int_4 ka, sa_size_t i) const
380{
381
382 if ( (ndim_ < 1) || (i == 0) ) return(offset_);
383 //#ifdef SO_BOUNDCHECKING
384 if (ka >= ndim_)
385 throw RangeCheckError("BaseArray::Offset(int_4 ka, sa_size_t i) Axe KA Error");
386 if ( i*size_[ka] >= totsize_ )
387 throw RangeCheckError("BaseArray::Offset(int_4 ka, sa_size_t i) Index Error");
388 //#endif
389 sa_size_t idx[BASEARRAY_MAXNDIMS];
390 int_4 k;
391 sa_size_t rest = i;
392 idx[ka] = 0;
393 for(k=0; k<ndim_; k++) {
394 if (k == ka) continue;
395 idx[k] = rest%size_[k]; rest /= size_[k];
396 }
397 sa_size_t off = offset_;
398 for(k=0; k<ndim_; k++) off += idx[k]*step_[k];
399 return (off);
400}
401
402//! return position of element \b ip.
403sa_size_t BaseArray::Offset(sa_size_t ip) const
404{
405 if ( (ndim_ < 1) || (ip == 0) ) return(offset_);
406 //#ifdef SO_BOUNDCHECKING
407 if (ip >= totsize_)
408 throw RangeCheckError("BaseArray::Offset(sa_size_t ip) Out of range index ip");
409 //#endif
410
411 sa_size_t idx[BASEARRAY_MAXNDIMS];
412 int_4 k;
413 sa_size_t rest = ip;
414 for(k=0; k<ndim_; k++) {
415 idx[k] = rest%size_[k]; rest /= size_[k];
416 }
417 //#ifdef SO_BOUNDCHECKING
418 if (rest != 0)
419 throw PError("BaseArray::Offset(sa_size_t ip) BUG !!! rest != 0");
420 //#endif
421// if (rest != 0) cerr << " BUG ---- BaseArray::Offset( " << ip << " )" << rest << endl;
422// cerr << " DBG-Offset( " << ip << ")" ;
423// for(k=0; k<ndim_; k++) cerr << idx[k] << "," ;
424// cerr << " ZZZZ " << endl;
425 sa_size_t off = offset_;
426 for(k=0; k<ndim_; k++) off += idx[k]*step_[k];
427 return (off);
428}
429//! return index of element \b ip, along the five array axes
430void BaseArray::IndexAtPosition(sa_size_t ip, sa_size_t & ix, sa_size_t & iy,
431 sa_size_t & iz, sa_size_t & it, sa_size_t & iu) const
432{
433 ix = iy = iz = it = iu = 0;
434 if ( (ndim_ < 1) || (ip == 0) ) return;
435 if (ip >= totsize_)
436 throw RangeCheckError("BaseArray::IndexAtPosition(...) Out of range index ip");
437 sa_size_t idx[BASEARRAY_MAXNDIMS];
438 int_4 k;
439 sa_size_t rest = ip;
440 for(k=0; k<ndim_; k++) {
441 idx[k] = rest%size_[k]; rest /= size_[k];
442 if (rest == 0) break;
443 }
444 if (rest != 0)
445 throw PError("BaseArray::IndexAtPosition(...) BUG !!! rest != 0");
446 ix = idx[0];
447 iy = idx[1];
448 iz = idx[2];
449 it = idx[3];
450 iu = idx[4];
451 return;
452}
453
454//! return various parameters for double loop operations on two arrays.
455void BaseArray::GetOpeParams(const BaseArray& a, bool smo, int_4& ax, int_4& axa, sa_size_t& step,
456 sa_size_t& stepa, sa_size_t& gpas, sa_size_t& naxa) const
457{
458 if (smo) { // Same memory organisation
459 ax = axa = MaxSizeKA();
460 }
461 else {
462 if (Size(RowsKA()) >= Size(ColsKA()) ) {
463 ax = RowsKA();
464 axa = a.RowsKA();
465 }
466 else {
467 ax = ColsKA();
468 axa = a.ColsKA();
469 }
470 }
471 step = Step(ax);
472 stepa = a.Step(axa);
473 gpas = Size(ax)*step;
474 naxa = Size()/Size(ax);
475 return;
476}
477
478// ----------------------------------------------------
479// Impression, etc ...
480// ----------------------------------------------------
481
482//! Show infos on stream \b os (\b si to display DvList)
483void BaseArray::Show(ostream& os, bool si) const
484{
485 if (ndim_ < 1) {
486 os << "\n--- " << BaseArray::InfoString() << " Unallocated Array ! " << endl;
487 return;
488 }
489 os << "\n--- " << InfoString() ;
490 os << " ND=" << ndim_ << " SizeX*Y*...= " ;
491 for(int_4 k=0; k<ndim_; k++) {
492 os << size_[k];
493 if (k<ndim_-1) os << "x";
494 }
495 os << " ---" << endl;
496 if (prt_lev_ > 0) {
497 os << " TotSize= " << totsize_ << " Step(X Y ...)=" ;
498 for(int_4 k=0; k<ndim_; k++) os << step_[k] << " " ;
499 os << " Offset= " << offset_ << endl;
500 }
501 if (prt_lev_ > 1) {
502 os << " MemoryMapping=" << GetMemoryMapping() << " VecType= " << GetVectorType()
503 << " RowsKA= " << RowsKA() << " ColsKA= " << ColsKA()
504 << " VectKA=" << VectKA() << " ArrayType=" << arrtype_ << endl;
505 }
506 if (!si && (prt_lev_ < 2)) return;
507 if (mInfo != NULL) os << (*mInfo) << endl;
508
509}
510
511//! Return BaseArray Type
512string BaseArray::InfoString() const
513{
514 string rs = "BaseArray Type= ";
515 rs += typeid(*this).name() ;
516 return rs;
517}
518
519//! Return attached DVList
520DVList& BaseArray::Info()
521{
522if (mInfo == NULL) mInfo = new DVList;
523return(*mInfo);
524}
525
526//! Update sizes and information for array
527/*!
528 \param ndim : dimension
529 \param siz[ndim] : sizes
530 \param step : step (must be the same on all dimensions)
531 \param offset : offset of the first element
532 \return true if all OK, false if problems appear
533 \return string \b exmsg for explanation in case of problems
534 */
535bool BaseArray::UpdateSizes(int_4 ndim, const sa_size_t * siz, sa_size_t step, sa_size_t offset, string & exmsg)
536{
537 if (ndim >= BASEARRAY_MAXNDIMS) {
538 exmsg += " NDim Error"; return false;
539 }
540 if (step < 1) {
541 exmsg += " Step(=0) Error"; return false;
542 }
543
544 minstep_ = moystep_ = step;
545
546 // Flagging bad updates ...
547 ndim_ = 0;
548
549 totsize_ = 1;
550 int_4 k;
551 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
552 size_[k] = 1;
553 step_[k] = 0;
554 }
555 for(k=0; k<ndim; k++) {
556 size_[k] = siz[k] ;
557 step_[k] = totsize_*step;
558 totsize_ *= size_[k];
559 }
560 if (totsize_ < 1) {
561 exmsg += " Size Error"; return false;
562 }
563 offset_ = offset;
564 // Default for matrices : Memory organisation and Vector type
565 if (default_memory_mapping == CMemoryMapping) {
566 marowi_ = 1; macoli_ = 0;
567 }
568 else {
569 marowi_ = 0; macoli_ = 1;
570 }
571 veceli_ = (default_vector_type == ColumnVector ) ? marowi_ : macoli_;
572 // Update OK
573 ndim_ = ndim;
574 return true;
575}
576
577//! Update sizes and information for array
578/*!
579 \param ndim : dimension
580 \param siz[ndim] : sizes
581 \param step[ndim] : steps
582 \param offset : offset of the first element
583 \return true if all OK, false if problems appear
584 \return string \b exmsg for explanation in case of problems
585 */
586bool BaseArray::UpdateSizes(int_4 ndim, const sa_size_t * siz, const sa_size_t * step, sa_size_t offset, string & exmsg)
587{
588 if (ndim >= BASEARRAY_MAXNDIMS) {
589 exmsg += " NDim Error"; return false;
590 }
591
592 // Flagging bad updates ...
593 ndim_ = 0;
594
595 totsize_ = 1;
596 int_4 k;
597 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
598 size_[k] = 1;
599 step_[k] = 0;
600 }
601 sa_size_t minstep = step[0];
602 for(k=0; k<ndim; k++) {
603 size_[k] = siz[k] ;
604 step_[k] = step[k];
605 totsize_ *= size_[k];
606 if (step_[k] < minstep) minstep = step_[k];
607 }
608 if (minstep < 1) {
609 exmsg += " Step(=0) Error"; return false;
610 }
611 if (totsize_ < 1) {
612 exmsg += " Size Error"; return false;
613 }
614 sa_size_t plast = 0;
615 for(k=0; k<ndim; k++) plast += (siz[k]-1)*step[k];
616 if (plast == minstep*totsize_ ) moystep_ = minstep;
617 else moystep_ = 0;
618 minstep_ = minstep;
619 offset_ = offset;
620 // Default for matrices : Memory organisation and Vector type
621 if (default_memory_mapping == CMemoryMapping) {
622 marowi_ = 1; macoli_ = 0;
623 }
624 else {
625 marowi_ = 0; macoli_ = 1;
626 }
627 veceli_ = (default_vector_type == ColumnVector ) ? marowi_ : macoli_;
628 // Update OK
629 ndim_ = ndim;
630 return true;
631}
632
633//! Update sizes and information relative to array \b a
634/*!
635 \param a : array to be compare with
636 \return true if all OK, false if problems appear
637 \return string \b exmsg for explanation in case of problems
638 */
639bool BaseArray::UpdateSizes(const BaseArray& a, string & exmsg)
640{
641 if (a.ndim_ >= BASEARRAY_MAXNDIMS) {
642 exmsg += " NDim Error"; return false;
643 }
644
645 // Flagging bad updates ...
646 ndim_ = 0;
647
648 totsize_ = 1;
649 int_4 k;
650 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
651 size_[k] = 1;
652 step_[k] = 0;
653 }
654 sa_size_t minstep = a.step_[0];
655 for(k=0; k<a.ndim_; k++) {
656 size_[k] = a.size_[k] ;
657 step_[k] = a.step_[k];
658 totsize_ *= size_[k];
659 if (step_[k] < minstep) minstep = step_[k];
660 }
661 if (minstep < 1) {
662 exmsg += " Step(=0) Error"; return false;
663 }
664 if (totsize_ < 1) {
665 exmsg += " Size Error"; return false;
666 }
667
668 minstep_ = a.minstep_;
669 moystep_ = a.moystep_;
670 offset_ = a.offset_;
671 macoli_ = a.macoli_;
672 marowi_ = a.marowi_;
673 veceli_ = a.veceli_;
674 // Update OK
675 ndim_ = a.ndim_;
676 return true;
677}
678
679
680//! Update sizes and information relative to array \b a
681/*!
682 \param a : array to be compare with
683 \param ndim : could be change (but should be less than the ndim of the current class)
684 \param siz[ndim],pos[ndim],step[ndim] : could be changed but must be
685 compatible within the memory size with those of the current class.
686 \return true if all OK, false if problems appear
687 \return string \b exmsg for explanation in case of problems
688 */
689void BaseArray::UpdateSubArraySizes(BaseArray & ra, int_4 ndim, sa_size_t * siz, sa_size_t * pos, sa_size_t * step) const
690{
691 if ( (ndim > ndim_) || (ndim < 1) )
692 throw(SzMismatchError("BaseArray::UpdateSubArraySizes( ... ) NDim Error") );
693 int_4 k;
694 for(k=0; k<ndim; k++)
695 if ( (siz[k]*step[k]+pos[k]) > size_[k] )
696 throw(SzMismatchError("BaseArray::UpdateSubArraySizes( ... ) Size/Pos Error") );
697 sa_size_t offset = offset_;
698 for(k=0; k<ndim_; k++) {
699 offset += pos[k]*step_[k];
700 step[k] *= step_[k];
701 }
702 string exm = "BaseArray::UpdateSubArraySizes() ";
703 if (!ra.UpdateSizes(ndim, siz, step, offset, exm))
704 throw( ParmError(exm) );
705 return;
706}
707
708
Note: See TracBrowser for help on using the repository browser.