Commit 2d199598 authored by Reza  ANSARI's avatar Reza ANSARI
Browse files

1) Ajout methode d'extraction de sous-tableaux TArray<T>::SubArray() ou le sous-tableau

est defini par std::vector<Range>
2) Changement de comportement de SubArray() avec le flag bool compact, qui appelle desormais
CompactAllDimensions() au lieu de CompactTrailingDimensions() - Effet se propage aussi a la
methode PackAndCopySubArray()
3) Ajout nouveau constructeur a la classe Range() qui peut decoder une chaine sous la forme start:end:step
et une methode statique Range::str2vranges() qui decode une chaine de caracteres,
                                                          Reza , 17/06/2022
parent 07104e31
......@@ -604,8 +604,8 @@ TArray<T> TArray<T>::ReShape(sa_size_t nx, sa_size_t ny, sa_size_t nz, sa_size_t
\warning data is shared between the original array and the sub-array
\param rx,ry,rz,rt,ru : ranges of extraction along the 5 dimensions (X,Y,Z,T,U) of the array
\param compact : if \b compact == true, compact trailing dimensions (suppressed if =1)
(See CompactTrailingDimensions() )
\param compact : if \b compact == true, compact all dimensions (suppressed if =1)
(See CompactAllDimensions() )
\sa SOPHYA::Range
*/
template <class T>
......@@ -619,7 +619,7 @@ TArray<T> TArray<T>::SubArray(Range rx, Range ry, Range rz, Range rt, Range ru,
rx.Update(SizeX());
if (NbDimensions() > 1) ry.Update(SizeY());
else ry.Update(0);
if (NbDimensions() > 1) rz.Update(SizeZ());
if (NbDimensions() > 2) rz.Update(SizeZ());
else rz.Update(0);
if (NbDimensions() > 3) rt.Update(Size(3));
else rt.Update(0);
......@@ -651,7 +651,46 @@ TArray<T> TArray<T>::SubArray(Range rx, Range ry, Range rz, Range rt, Range ru,
TArray<T> ra;
UpdateSubArraySizes(ra, ndim, size, pos, step);
ra.DataBlock().Share(this->DataBlock());
if (compact) ra.CompactTrailingDim();
if (compact) ra.CompactAllDimensions();
return(ra);
}
/*!
\brief Extract a sub-array defined by the set of ranges specified as the std::vector<Range>
\warning The provided vector of ranges should have a size equal to the array rank, a SzMismatchError
is generated.
\warning data is shared between the original array and the sub-array
\param vrng : size, offset and step along each of the array dimensions, 0:X, 1:Y, 2:Z ...
\param compact : if \b compact == true, compact all dimensions (suppressed if =1)
(See CompactAllDimensions() )
\sa SOPHYA::Range
*/
template <class T>
TArray<T> TArray<T>::SubArray(std::vector<Range> & vrng, bool compact) const
{
if (NbDimensions() < 1)
throw NotAllocatedError("TArray<T>::SubArray(vector<Range>) - Not Allocated Array ! ");
int_4 ndim = 0;
if (vrng.size() != (size_t)Rank())
throw NotAllocatedError("TArray<T>::SubArray(vector<Range>& vrng) vrng.size() ! Rank()");
sa_size_t size[BASEARRAY_MAXNDIMS];
sa_size_t step[BASEARRAY_MAXNDIMS];
sa_size_t pos[BASEARRAY_MAXNDIMS];
for(size_t i=0; i<vrng.size(); i++) {
// Updating Range objects using actual array size
vrng[i].Update(Size(i));
size[i] = vrng[i].Size();
step[i] = vrng[i].Step();
pos[i] = vrng[i].Start();
}
ndim = ndim_;
TArray<T> ra;
UpdateSubArraySizes(ra, ndim, size, pos, step);
ra.DataBlock().Share(this->DataBlock());
if (compact) ra.CompactAllDimensions();
return(ra);
}
......@@ -681,9 +720,41 @@ TArray<T> TArray<T>::PackAndCopySubArray(Range rx, Range ry, Range rz, Range rt,
else st=0;
if (sa.NbDimensions() > 4) su=sa.Size(4);
else su=0;
TArray<T> retarr(sx,sy,sz,st,su, false);
retarr = sa;
return retarr;
return sa.PackElements(true);
}
/*!
\brief Returns a packed array corresponding to a copy of the sub-array defined by the ranges, specified as as std::vector<Range>
\warning The provided vector of ranges should have a size equal to the array rank, a SzMismatchError
is generated.
\warning array data is copied in all cases, even if the defined sub-array is a packed array.
\param vrng : size, offset and step along each of the array dimensions, 0:X, 1:Y, 2:Z ...
\sa SOPHYA::Range
*/
template <class T>
TArray<T> TArray<T>::PackAndCopySubArray(std::vector<Range> & vrng) const
{
if (NbDimensions() < 1)
throw NotAllocatedError("TArray<T>::PackAndCopySubArray(std::vector<Range> &) - Not Allocated Array ! ");
if (vrng.size() != (size_t)Rank())
throw NotAllocatedError("TArray<T>::PackAndCopySubArray(vector<Range>& vrng) vrng.size() ! Rank()");
TArray<T> sa=SubArray(vrng, true);
// Updating Range objects using actual array size
sa_size_t sx=0,sy=0,sz=0,st=0,su=0;
sx=sa.SizeX();
if (sa.NbDimensions() > 1) sy=sa.SizeY();
else sy=0;
if (sa.NbDimensions() > 2) sz=sa.SizeZ();
else sz=0;
if (sa.NbDimensions() > 3) st=sa.Size(3);
else st=0;
if (sa.NbDimensions() > 4) su=sa.Size(4);
else su=0;
return sa.PackElements(true);
}
// ...... Operation de calcul sur les tableaux ......
......
......@@ -112,6 +112,7 @@ public:
// SubArrays - $CHECK$ Reza 03/2000 je ne sais pas s'il faut declarer ca const ??
TArray<T> SubArray(Range rx, Range ry, Range rz, Range rt, Range ru, bool compact=true) const ;
TArray<T> SubArray(std::vector<Range> & vrng, bool compact=true) const ;
//! Extract the first 3D subarray specified by rx, ry, rz. (see SubArray() )
inline TArray<T> operator () (Range rx, Range ry, Range rz) const
......@@ -125,6 +126,7 @@ public:
// Return a packed array, equal to the sub-array defined by the ranges - no data sharing
TArray<T> PackAndCopySubArray(Range rx, Range ry, Range rz=Range::first(), Range rt=Range::first(), Range ru=Range::first()) const;
TArray<T> PackAndCopySubArray(std::vector<Range> & vrng) const;
// ---- Access to data
// Definition of virtual element acces method inherited from BaseArray class
......
......@@ -11,6 +11,7 @@
#include "machdefs.h"
#include "utilarr.h"
#include "randr48.h"
#include "strutilxx.h"
using namespace std;
......@@ -432,6 +433,54 @@ Range::Range(Range const & a)
{
}
/*!
\param s : string defining the index range can be specified in the following forms
\verbatim
start -> a single index=start
start:end -> the index range start <= index <= end (step=1)
start:end:step -> index range start <= index <= end with increment step
: -> index range = Range::all()
start: -> index range start <= index <= lastIndex()
\endverbatim
\warning Can throw ParmError (empty string or bad syntax)
*/
Range::Range(std::string s)
{
start_ = 1;
end_ = lastIndex();
size_ = 1;
step_ = 1;
size_t l = s.length();
if (l<1) throw ParmError("Range::Range(string s) empty string s");
if (s==":") {
start_=end_=Range::lastIndex();
}
size_t p = s.find(':');
if (p>=l) {
start_=end_=atol(s.c_str());
return;
}
start_=atol(s.substr(0,p).c_str());
if (p==(l-1)) {
end_=Range::lastIndex();
return;
}
std::string s2=s.substr(p+1);
l=s2.length();
p = s2.find(':');
if (p==0) throw ParmError("Range::Range(string s) bad syntax , misplaced : ");
if ((p>=l)||(p==(l-1))) {
end_=atol(s2.c_str());
if (end_>=start_) size_ = (end_-start_)+1;
return;
}
sa_size_t end_=atol(s2.substr(0,p).c_str());
sa_size_t step_=atol(s2.substr(p+1).c_str());
if (step_<1) throw ParmError("Range::Range(string s) bad syntax , step<1 ");
if (end_>=start_) size_ = (end_-start_)/step_+1;
return;
}
/* --Methode-- */
Range& Range::operator = (Range const & a)
{
......@@ -447,6 +496,12 @@ bool Range::IsEqual(Range const & a) const
return true;
}
/* --Methode-- */
std::ostream& Range::Print(std::ostream& os) const
{
os<<"Range(start="<<start_<<",end="<<end_<<",step="<<step_<<")";
return os;
}
/*!
This method is called to recompute index ranges, specifying the original array size
......@@ -454,7 +509,7 @@ bool Range::IsEqual(Range const & a) const
*/
void Range::Update(sa_size_t osz)
{
if (end_ >= 0) return;
if ((start_>=0) && (end_ >= 0)) return;
if (osz == 0) {
start_ = end_ = 0;
size_ = step_ = 1;
......@@ -478,6 +533,23 @@ void Range::Update(sa_size_t osz)
return;
}
/*!
\param s : string defining the set of index ranges specified in the form [rs1,rs2,rs3...]
with each rs specified as start:end:step , or short forms described in Range(string s)
*/
std::vector<Range> Range::str2vranges(std::string s)
{
size_t l = s.length();
if (l<3) throw ParmError("Range::str2vranges(s) empty string (len<3)");
if ((s[0]!='[')||(s[l-1]!=']'))
throw ParmError("Range::str2vranges(s) string not delimited by [ ] ");
s=s.substr(1,l-2);
std::vector<std::string> vs;
SplitStringToVString(s,vs,',');
std::vector<Range> vr;
for(size_t ii=0; ii<vs.size(); ii++) vr.push_back(Range(vs[ii]));
return vr;
}
/*
Range & Range::operator = (sa_size_t start)
{
......
......@@ -126,8 +126,9 @@ private:
mutable MuTyV retv_;
};
//! prints/displays the enumerated sequence on the ostream \b os
inline std::ostream& operator << (std::ostream& os, const EnumeratedSequence& a)
{ a.Print(os); return(os); }
{ a.Print(os); return(os); }
//inline EnumeratedSequence operator , (MuTyV const & a, MuTyV const & b)
//{ EnumeratedSequence seq; return ((seq,a),b) ; }
......@@ -144,11 +145,13 @@ public:
Range(sa_size_t start, sa_size_t end, sa_size_t step);
//! General Index range specification, using size or start/end and increment
Range(sa_size_t start, sa_size_t end, sa_size_t size, sa_size_t step);
//! Index range specified as a string, in the form start:end:step
Range(std::string s);
//! copy constructor
Range(Range const & a);
//! copy (equal) operator
Range& operator = (Range const & a);
//! equality between two Range object - return true if equal
//! tests the equality between two Range object - return true if equal
bool IsEqual(Range const & a) const;
//! Return a reference to the start index
inline sa_size_t & Start() { return start_; }
......@@ -166,6 +169,8 @@ public:
inline sa_size_t Size() const { return size_; }
//! Return the step (const version)
inline sa_size_t Step() const { return step_; }
//! prints/displays the Range object on the ostream \b os - No new line appended
std::ostream& Print(std::ostream& os) const;
//! return a constant value defining the first element
inline static sa_size_t firstIndex() { return 0; }
//! return a constant value as a placeholder for the last valid index
......@@ -179,7 +184,8 @@ public:
//! return a Range object specifing the last valid index
inline static Range last()
{ return Range(Range::lastIndex() , Range::lastIndex(), 1, 1); }
//! return a vector of ranges decoding the provided string as [rs1,rs2,...] with rs=start:end:step
static std::vector<Range> str2vranges(std::string s);
//! For internal TArray module use.
void Update(sa_size_t osz);
......@@ -190,14 +196,18 @@ protected:
sa_size_t step_; //!< step
};
//! \brief equality comparison operator between two ranges
//! equality comparison operator between two ranges
inline bool operator == (Range const& a1, Range const& a2)
{ return a1.IsEqual(a2); }
//! \brief equality comparison operator between two ranges
//! inequality comparison operator between two ranges
inline bool operator != (Range const& a1, Range const& a2)
{ return !(a1.IsEqual(a2)); }
//! prints/displays the Range objet on the ostream \b os
inline std::ostream& operator << (std::ostream& os, const Range& a)
{ a.Print(os); return(os); }
//////////////////////////////////////////////////////////
//! Class to define an identity matrix
class IdentityMatrix {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment