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

Last change on this file since 4066 was 4035, checked in by ansari, 14 years ago

1/ modif mineure ds TArray<T>::::ReadASCII() au print level global de BaseArray
2/ Correction bug gestion memoire au niveau des constructeurs de copie TArray/TMatrix/TVector
avec un BaseArray en argument. Ajout argument optionnel bool pack a ces constructeurs
3/ On autorise desormais la creation des objets TArray/TMatrix/TVector par constructeur de
copie sur des objets non alloues

Reza, 14/11/2011

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