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

Last change on this file since 1837 was 1636, checked in by ansari, 24 years ago

Correction bugs ds UpdateSize (calcul AvgStep() et configuration Vecteur/Matrices + protection constructeur TArray() depuis NDataBlock - Reza 13/8/2001

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