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

Last change on this file since 2327 was 2267, checked in by ansari, 23 years ago

MAJ documentation + methode Read/WriteASCII() en virtuelle pure ds BaseArray - Reza 15/11/2002

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}
278
279
280//! Returns true if the two arrays have compatible dimensions.
281/*!
282 \param a : array to be compared
283 \param smo : Return flag = true if the two arrays have the same memory organisation
284 \return true if \c NbDimensions() and \c Size() are equal, false if not
285
286 If the array (on which the operation is being performed, \c this)
287 is a \b Matrix or a \b Vector, the matrix dimensions \c NRows() \c NCols()
288 are checked. The flag \c smo is returned true if the two arrays, viewed
289 as a matrix have the same memory organisation.
290 Otherwise, (if the array is of not a Matrix or a Vector)
291 the size compatibility viewed as a TArray is checked <tt>
292 (Size(k) == a.Size(k), k=0,...NbDimensions()), </tt> disregard of the memory
293 organisation and the row and column index. The flag \c smo is returned true
294 in this case.
295*/
296bool BaseArray::CompareSizes(const BaseArray& a, bool& smo) const
297{
298 if (ndim_ != a.ndim_) return(false);
299 if (arrtype_ == 0) { // Simple TArray, not a matrix
300 smo = true;
301 for(int_4 k=0; k<ndim_; k++)
302 if (size_[k] != a.size_[k]) return(false);
303 return(true);
304 }
305 else {
306 smo = false;
307 if ( (size_[marowi_] != a.size_[a.marowi_]) ||
308 (size_[macoli_] != a.size_[a.macoli_]) ) return(false);
309 if (ndim_ > 2)
310 for(int_4 k=2; k<ndim_; k++)
311 if (size_[k] != a.size_[k]) return(false);
312 if ( (macoli_ == a.macoli_) && (marowi_ == a.marowi_) ||
313 (veceli_ == a.veceli_) ) smo = true;
314 return(true);
315 }
316}
317
318//! Change dimension if some size == 1
319void BaseArray::CompactAllDim()
320{
321 if (ndim_ < 2) return;
322 int_4 ndim = 0;
323 sa_size_t size[BASEARRAY_MAXNDIMS];
324 sa_size_t step[BASEARRAY_MAXNDIMS];
325 for(int_4 k=0; k<ndim_; k++) {
326 if (size_[k] < 2) continue;
327 size[ndim] = size_[k];
328 step[ndim] = step_[k];
329 ndim++;
330 }
331 if (ndim == 0) {
332 size[0] = size_[0];
333 step[0] = step_[0];
334 ndim = 1;
335 }
336 string exmsg = "BaseArray::CompactAllDim() ";
337 if (!UpdateSizes(ndim, size, step, offset_, exmsg)) throw( ParmError(exmsg) );
338 return;
339}
340
341//! Change dimension if some trailed size == 1
342void BaseArray::CompactTrailingDim()
343{
344 if (ndim_ < 2) return;
345 int_4 ndim = 0;
346 sa_size_t size[BASEARRAY_MAXNDIMS];
347 sa_size_t step[BASEARRAY_MAXNDIMS];
348 for(int_4 k=0; k<ndim_; k++) {
349 size[ndim] = size_[k];
350 step[ndim] = step_[k];
351 if (size_[k] > 1) ndim=k;
352 }
353 if (ndim == 0) ndim = 1;
354 string exmsg = "BaseArray::CompactTrailingDim() ";
355 if (!UpdateSizes(ndim, size, step, offset_, exmsg)) throw( ParmError(exmsg) );
356 return;
357}
358
359//! return minimum value for step[ndim]
360int_4 BaseArray::MinStepKA() const
361{
362 for(int_4 ka=0; ka<ndim_; ka++)
363 if (step_[ka] == minstep_) return((int)ka);
364 return(0);
365}
366
367//! return maximum value for step[ndim]
368int_4 BaseArray::MaxSizeKA() const
369{
370 int_4 ka = 0;
371 sa_size_t mx = size_[0];
372 for(int_4 k=1; k<ndim_; k++)
373 if (size_[k] > mx) { ka = k; mx = size_[k]; }
374 return(ka);
375}
376
377
378// Acces lineaire aux elements .... Calcul d'offset
379// --------------------------------------------------
380// Position de l'element 0 du vecteur i selon l'axe ka
381// --------------------------------------------------
382//! return position of first element for vector \b i alond \b ka th axe.
383sa_size_t BaseArray::Offset(int_4 ka, sa_size_t i) const
384{
385
386 if ( (ndim_ < 1) || (i == 0) ) return(offset_);
387 //#ifdef SO_BOUNDCHECKING
388 if (ka >= ndim_)
389 throw RangeCheckError("BaseArray::Offset(int_4 ka, sa_size_t i) Axe KA Error");
390 if ( i*size_[ka] >= totsize_ )
391 throw RangeCheckError("BaseArray::Offset(int_4 ka, sa_size_t i) Index Error");
392 //#endif
393 sa_size_t idx[BASEARRAY_MAXNDIMS];
394 int_4 k;
395 sa_size_t rest = i;
396 idx[ka] = 0;
397 for(k=0; k<ndim_; k++) {
398 if (k == ka) continue;
399 idx[k] = rest%size_[k]; rest /= size_[k];
400 }
401 sa_size_t off = offset_;
402 for(k=0; k<ndim_; k++) off += idx[k]*step_[k];
403 return (off);
404}
405
406//! return position of element \b ip.
407sa_size_t BaseArray::Offset(sa_size_t ip) const
408{
409 if ( (ndim_ < 1) || (ip == 0) ) return(offset_);
410 //#ifdef SO_BOUNDCHECKING
411 if (ip >= totsize_)
412 throw RangeCheckError("BaseArray::Offset(sa_size_t ip) Out of range index ip");
413 //#endif
414
415 sa_size_t idx[BASEARRAY_MAXNDIMS];
416 int_4 k;
417 sa_size_t rest = ip;
418 for(k=0; k<ndim_; k++) {
419 idx[k] = rest%size_[k]; rest /= size_[k];
420 }
421 //#ifdef SO_BOUNDCHECKING
422 if (rest != 0)
423 throw PError("BaseArray::Offset(sa_size_t ip) BUG !!! rest != 0");
424 //#endif
425// if (rest != 0) cerr << " BUG ---- BaseArray::Offset( " << ip << " )" << rest << endl;
426// cerr << " DBG-Offset( " << ip << ")" ;
427// for(k=0; k<ndim_; k++) cerr << idx[k] << "," ;
428// cerr << " ZZZZ " << endl;
429 sa_size_t off = offset_;
430 for(k=0; k<ndim_; k++) off += idx[k]*step_[k];
431 return (off);
432}
433//! return index of element \b ip, along the five array axes
434void BaseArray::IndexAtPosition(sa_size_t ip, sa_size_t & ix, sa_size_t & iy,
435 sa_size_t & iz, sa_size_t & it, sa_size_t & iu) const
436{
437 ix = iy = iz = it = iu = 0;
438 if ( (ndim_ < 1) || (ip == 0) ) return;
439 if (ip >= totsize_)
440 throw RangeCheckError("BaseArray::IndexAtPosition(...) Out of range index ip");
441 sa_size_t idx[BASEARRAY_MAXNDIMS];
442 int_4 k;
443 sa_size_t rest = ip;
444 for(k=0; k<ndim_; k++) {
445 idx[k] = rest%size_[k]; rest /= size_[k];
446 if (rest == 0) break;
447 }
448 if (rest != 0)
449 throw PError("BaseArray::IndexAtPosition(...) BUG !!! rest != 0");
450 ix = idx[0];
451 iy = idx[1];
452 iz = idx[2];
453 it = idx[3];
454 iu = idx[4];
455 return;
456}
457
458//! return various parameters for double loop operations on two arrays.
459void BaseArray::GetOpeParams(const BaseArray& a, bool smo, int_4& ax, int_4& axa, sa_size_t& step,
460 sa_size_t& stepa, sa_size_t& gpas, sa_size_t& naxa) const
461{
462 if (smo) { // Same memory organisation
463 ax = axa = MaxSizeKA();
464 }
465 else {
466 if (Size(RowsKA()) >= Size(ColsKA()) ) {
467 ax = RowsKA();
468 axa = a.RowsKA();
469 }
470 else {
471 ax = ColsKA();
472 axa = a.ColsKA();
473 }
474 }
475 step = Step(ax);
476 stepa = a.Step(axa);
477 gpas = Size(ax)*step;
478 naxa = Size()/Size(ax);
479 return;
480}
481
482// ----------------------------------------------------
483// Impression, etc ...
484// ----------------------------------------------------
485
486//! Show infos on stream \b os (\b si to display DvList)
487void BaseArray::Show(ostream& os, bool si) const
488{
489 if (ndim_ < 1) {
490 os << "\n--- " << BaseArray::InfoString() << " Unallocated Array ! " << endl;
491 return;
492 }
493 os << "\n--- " << InfoString() ;
494 os << " ND=" << ndim_ << " SizeX*Y*...= " ;
495 for(int_4 k=0; k<ndim_; k++) {
496 os << size_[k];
497 if (k<ndim_-1) os << "x";
498 }
499 os << " ---" << endl;
500 if (prt_lev_ > 0) {
501 os << " TotSize= " << totsize_ << " Step(X Y ...)=" ;
502 for(int_4 k=0; k<ndim_; k++) os << step_[k] << " " ;
503 os << " Offset= " << offset_ << endl;
504 }
505 if (prt_lev_ > 1) {
506 os << " MemoryMapping=" << GetMemoryMapping() << " VecType= " << GetVectorType()
507 << " RowsKA= " << RowsKA() << " ColsKA= " << ColsKA()
508 << " VectKA=" << VectKA() << " ArrayType=" << arrtype_ << endl;
509 }
510 if (!si && (prt_lev_ < 2)) return;
511 if (mInfo != NULL) os << (*mInfo) << endl;
512
513}
514
515//! Return BaseArray Type
516string BaseArray::InfoString() const
517{
518 string rs = "BaseArray Type= ";
519 rs += typeid(*this).name() ;
520 return rs;
521}
522
523//! Return attached DVList
524DVList& BaseArray::Info()
525{
526if (mInfo == NULL) mInfo = new DVList;
527return(*mInfo);
528}
529
530//! Update sizes and information for array
531/*!
532 \param ndim : dimension
533 \param siz[ndim] : sizes
534 \param step : step (must be the same on all dimensions)
535 \param offset : offset of the first element
536 \return true if all OK, false if problems appear
537 \return string \b exmsg for explanation in case of problems
538 */
539bool BaseArray::UpdateSizes(int_4 ndim, const sa_size_t * siz, sa_size_t step, sa_size_t offset, string & exmsg)
540{
541 if (ndim >= BASEARRAY_MAXNDIMS) {
542 exmsg += " NDim Error"; return false;
543 }
544 if (step < 1) {
545 exmsg += " Step(=0) Error"; return false;
546 }
547
548 minstep_ = moystep_ = step;
549
550 // Flagging bad updates ...
551 ndim_ = 0;
552
553 totsize_ = 1;
554 int_4 k;
555 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
556 size_[k] = 1;
557 step_[k] = 0;
558 }
559 for(k=0; k<ndim; k++) {
560 size_[k] = siz[k] ;
561 step_[k] = totsize_*step;
562 totsize_ *= size_[k];
563 }
564 if (totsize_ < 1) {
565 exmsg += " Size Error"; return false;
566 }
567 offset_ = offset;
568 // Update OK
569 ndim_ = ndim;
570 // Default for matrices : Memory organisation and Vector type
571 SetMemoryMapping(BaseArray::SameMemoryMapping);
572 return true;
573}
574
575//! Update sizes and information for array
576/*!
577 \param ndim : dimension
578 \param siz[ndim] : sizes
579 \param step[ndim] : steps
580 \param offset : offset of the first element
581 \return true if all OK, false if problems appear
582 \return string \b exmsg for explanation in case of problems
583 */
584bool BaseArray::UpdateSizes(int_4 ndim, const sa_size_t * siz, const sa_size_t * step, sa_size_t offset, string & exmsg)
585{
586 if (ndim >= BASEARRAY_MAXNDIMS) {
587 exmsg += " NDim Error"; return false;
588 }
589
590 // Flagging bad updates ...
591 ndim_ = 0;
592
593 totsize_ = 1;
594 int_4 k;
595 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
596 size_[k] = 1;
597 step_[k] = 0;
598 }
599 sa_size_t minstep = step[0];
600 for(k=0; k<ndim; k++) {
601 size_[k] = siz[k] ;
602 step_[k] = step[k];
603 totsize_ *= size_[k];
604 if (step_[k] < minstep) minstep = step_[k];
605 }
606 if (minstep < 1) {
607 exmsg += " Step(=0) Error"; return false;
608 }
609 if (totsize_ < 1) {
610 exmsg += " Size Error"; return false;
611 }
612 sa_size_t plast = 0;
613 for(k=0; k<ndim; k++) plast += (siz[k]-1)*step[k];
614 if (plast == minstep*(totsize_-1) ) moystep_ = minstep;
615 else moystep_ = 0;
616 minstep_ = minstep;
617 offset_ = offset;
618 // Update OK
619 ndim_ = ndim;
620 // Default for matrices : Memory organisation and Vector type
621 SetMemoryMapping(BaseArray::SameMemoryMapping);
622 return true;
623}
624
625//! Update sizes and information relative to array \b a
626/*!
627 \param a : array to be compare with
628 \return true if all OK, false if problems appear
629 \return string \b exmsg for explanation in case of problems
630 */
631bool BaseArray::UpdateSizes(const BaseArray& a, string & exmsg)
632{
633 if (a.ndim_ >= BASEARRAY_MAXNDIMS) {
634 exmsg += " NDim Error"; return false;
635 }
636
637 // Flagging bad updates ...
638 ndim_ = 0;
639
640 totsize_ = 1;
641 int_4 k;
642 for(k=0; k<BASEARRAY_MAXNDIMS; k++) {
643 size_[k] = 1;
644 step_[k] = 0;
645 }
646 sa_size_t minstep = a.step_[0];
647 for(k=0; k<a.ndim_; k++) {
648 size_[k] = a.size_[k] ;
649 step_[k] = a.step_[k];
650 totsize_ *= size_[k];
651 if (step_[k] < minstep) minstep = step_[k];
652 }
653 if (minstep < 1) {
654 exmsg += " Step(=0) Error"; return false;
655 }
656 if (totsize_ < 1) {
657 exmsg += " Size Error"; return false;
658 }
659
660 minstep_ = a.minstep_;
661 moystep_ = a.moystep_;
662 offset_ = a.offset_;
663 macoli_ = a.macoli_;
664 marowi_ = a.marowi_;
665 veceli_ = a.veceli_;
666 // Update OK
667 ndim_ = a.ndim_;
668 return true;
669}
670
671
672//! Update sizes and information relative to array \b a
673/*!
674 \param a : array to be compare with
675 \param ndim : could be change (but should be less than the ndim of the current class)
676 \param siz[ndim],pos[ndim],step[ndim] : could be changed but must be
677 compatible within the memory size with those of the current class.
678 \return true if all OK, false if problems appear
679 \return string \b exmsg for explanation in case of problems
680 */
681void BaseArray::UpdateSubArraySizes(BaseArray & ra, int_4 ndim, sa_size_t * siz, sa_size_t * pos, sa_size_t * step) const
682{
683 if ( (ndim > ndim_) || (ndim < 1) )
684 throw(SzMismatchError("BaseArray::UpdateSubArraySizes( ... ) NDim Error") );
685 int_4 k;
686 for(k=0; k<ndim; k++)
687 if ( (siz[k]*step[k]+pos[k]) > size_[k] )
688 throw(SzMismatchError("BaseArray::UpdateSubArraySizes( ... ) Size/Pos Error") );
689 sa_size_t offset = offset_;
690 for(k=0; k<ndim_; k++) {
691 offset += pos[k]*step_[k];
692 step[k] *= step_[k];
693 }
694 string exm = "BaseArray::UpdateSubArraySizes() ";
695 if (!ra.UpdateSizes(ndim, siz, step, offset, exm))
696 throw( ParmError(exm) );
697 return;
698}
699
700
Note: See TracBrowser for help on using the repository browser.