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

Last change on this file since 2583 was 2583, checked in by cmv, 21 years ago
  • Intro decision auto d'optimisation produit de matrices
  • Possibilite a l'utilisateur pour choisir l'optimisation
  • cas FxC optimise par copie

cmv 30/07/04

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