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

Last change on this file since 4000 was 3669, checked in by ansari, 16 years ago

Correction ds BaseArray::CompareSizes() - ligne 356-357, test smo=true (same memory organisation) rendu plus restrictif , Reza 24/10/2009

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 \verbatim
121 # ===== For Matrices
122 *** MATHEMATICS: m(row,column) with indexes running [1,n])
123 | 11 12 13 |
124 matrix Math = Mmath= | 21 22 23 |
125 | 31 32 33 |
126 *** IDL, \b FORTRAN: indexes data in \b row-major format:
127 indexes arrays in (column,row) order.
128 index IDL running [0,n[ ; index FORTRAN running [1,n]
129 M in memory: [ 11 12 13 : 21 22 23 : 31 32 33 : ... ]
130 line 1 : line 2 : line 3 : ...
131 ex: Midl(0,2) = Mfor(1,3) = Mmath(3,1) = 31
132 Midl(2,0) = Mfor(3,1) = Mmath(1,3) = 13
133 *** C: indexes data in \b column-major format:
134 indexes arrays in [row][column] order.
135 index C running [0,n[
136 M in memory: [ 11 21 31 : 12 22 32 : 13 23 33 : ... ]
137 column 1 : column 2 : column 3 : ...
138 ex: Mc[2][0] = Mmath(3,1) = 31
139 Mc[0][2] = Mmath(1,3) = 13
140 *** RESUME diff Idl/Fortan/C/Math:
141 Midl(col-1,row-1) = Mfor(col,row) = Mc[row-1][col-1] = Mmath(row,col)
142 TRANSPOSE(column-major array) --> row-major array
143 \endverbatim
144 \return default memory mapping value
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 attached DVList
568DVList& BaseArray::Info()
569{
570if (mInfo == NULL) mInfo = new DVList;
571return(*mInfo);
572}
573
574//! Update sizes and information for array
575/*!
576 \param ndim : dimension
577 \param siz[ndim] : sizes
578 \param step : step (must be the same on all dimensions)
579 \param offset : offset of the first element
580 \return true if all OK, false if problems appear
581 \return string \b exmsg for explanation in case of problems
582 */
583bool BaseArray::UpdateSizes(int_4 ndim, const sa_size_t * siz, sa_size_t step, sa_size_t offset, string & exmsg)
584{
585 if (ndim > BASEARRAY_MAXNDIMS) {
586 exmsg += " NDim Error"; return false;
587 }
588 if (step < 1) {
589 exmsg += " Step(=0) Error"; return false;
590 }
591
592 minstep_ = moystep_ = step;
593
594 // Flagging bad updates ...
595 ndim_ = 0;
596
597 totsize_ = 1;
598 int_4 k;
599 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
600 size_[k] = 1;
601 step_[k] = 0;
602 }
603 for(k=0; k<ndim; k++) {
604 size_[k] = siz[k] ;
605 step_[k] = totsize_*step;
606 totsize_ *= size_[k];
607 }
608 if (totsize_ < 1) {
609 exmsg += " Size Error"; return false;
610 }
611 offset_ = offset;
612 // Update OK
613 ndim_ = ndim;
614 // Default for matrices : Memory organisation and Vector type
615 SetMemoryMapping(BaseArray::SameMemoryMapping);
616 return true;
617}
618
619//! Update sizes and information for array
620/*!
621 \param ndim : dimension
622 \param siz[ndim] : sizes
623 \param step[ndim] : steps
624 \param offset : offset of the first element
625 \return true if all OK, false if problems appear
626 \return string \b exmsg for explanation in case of problems
627 */
628bool BaseArray::UpdateSizes(int_4 ndim, const sa_size_t * siz, const sa_size_t * step, sa_size_t offset, string & exmsg)
629{
630 if (ndim > BASEARRAY_MAXNDIMS) {
631 exmsg += " NDim Error"; return false;
632 }
633
634 // Flagging bad updates ...
635 ndim_ = 0;
636
637 totsize_ = 1;
638 int_4 k;
639 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
640 size_[k] = 1;
641 step_[k] = 0;
642 }
643 sa_size_t minstep = step[0];
644 for(k=0; k<ndim; k++) {
645 size_[k] = siz[k] ;
646 step_[k] = step[k];
647 totsize_ *= size_[k];
648 if (step_[k] < minstep) minstep = step_[k];
649 }
650 if (minstep < 1) {
651 exmsg += " Step(=0) Error"; return false;
652 }
653 if (totsize_ < 1) {
654 exmsg += " Size Error"; return false;
655 }
656 sa_size_t plast = 0;
657 for(k=0; k<ndim; k++) plast += (siz[k]-1)*step[k];
658 if (plast == minstep*(totsize_-1) ) moystep_ = minstep;
659 else moystep_ = 0;
660 minstep_ = minstep;
661 offset_ = offset;
662 // Update OK
663 ndim_ = ndim;
664 // Default for matrices : Memory organisation and Vector type
665 SetMemoryMapping(BaseArray::SameMemoryMapping);
666 return true;
667}
668
669//! Update sizes and information relative to array \b a
670/*!
671 \param a : array to be compare with
672 \return true if all OK, false if problems appear
673 \return string \b exmsg for explanation in case of problems
674 */
675bool BaseArray::UpdateSizes(const BaseArray& a, string & exmsg)
676{
677 if (a.ndim_ > BASEARRAY_MAXNDIMS) {
678 exmsg += " NDim Error"; return false;
679 }
680
681 // Flagging bad updates ...
682 ndim_ = 0;
683
684 totsize_ = 1;
685 int_4 k;
686 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
687 size_[k] = 1;
688 step_[k] = 0;
689 }
690 sa_size_t minstep = a.step_[0];
691 for(k=0; k<a.ndim_; k++) {
692 size_[k] = a.size_[k] ;
693 step_[k] = a.step_[k];
694 totsize_ *= size_[k];
695 if (step_[k] < minstep) minstep = step_[k];
696 }
697 if (minstep < 1) {
698 exmsg += " Step(=0) Error"; return false;
699 }
700 if (totsize_ < 1) {
701 exmsg += " Size Error"; return false;
702 }
703
704 minstep_ = a.minstep_;
705 moystep_ = a.moystep_;
706 offset_ = a.offset_;
707 macoli_ = a.macoli_;
708 marowi_ = a.marowi_;
709 veceli_ = a.veceli_;
710 // Update OK
711 ndim_ = a.ndim_;
712 return true;
713}
714
715
716//! Update sizes information for sub-array \b ra
717/*!
718 \param ra : sub-array for which size information has to be computed
719 \param ndim : number of dimensions for \b ra
720 \param siz[ndim],pos[ndim],step[ndim] : number of elements, offset and step along each dimension,
721 relative to the original array.
722 \warning throw SzMismatchError in case of incompatible dimensions.
723 */
724void BaseArray::UpdateSubArraySizes(BaseArray & ra, int_4 ndim, sa_size_t * siz, sa_size_t * pos, sa_size_t * step) const
725{
726 if ( (ndim > ndim_) || (ndim < 1) )
727 throw(SzMismatchError("BaseArray::UpdateSubArraySizes( ... ) NDim Error") );
728 int_4 k;
729 for(k=0; k<ndim; k++)
730 if ( ((siz[k]-1)*step[k]+pos[k]) >= size_[k] )
731 throw(SzMismatchError("BaseArray::UpdateSubArraySizes( ... ) Size/Pos Error") );
732 sa_size_t offset = offset_;
733 for(k=0; k<ndim_; k++) {
734 offset += pos[k]*step_[k];
735 step[k] *= step_[k];
736 }
737 string exm = "BaseArray::UpdateSubArraySizes() ";
738 if (!ra.UpdateSizes(ndim, siz, step, offset, exm))
739 throw( ParmError(exm) );
740 return;
741}
742
743//! Set the array sizes to zero, corresponding to an unallocated array
744void BaseArray::SetZeroSize()
745{
746 ndim_ = 0;
747 for(int_4 k=0; k<BASEARRAY_MAXNDIMS; k++) step_[k] = size_[k] = 0;
748 totsize_ = 0;
749 minstep_ = 0;
750 moystep_ = 0;
751 offset_ = 0;
752 // On ne change pas l'organisation memoire, le type de vecteur
753 // et le array type
754}
755
Note: See TracBrowser for help on using the repository browser.