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

Last change on this file since 2564 was 2412, checked in by ansari, 22 years ago

Correction oubli delete mInfo ds TArray/BaseArray - Reza 21/07/03

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