Commit a8096991 authored by Reza  ANSARI's avatar Reza ANSARI
Browse files

1/ Possibilite de mettre des indices negatifs pour start,end dans Range,

  ce qui specifie des index comptes a partir de la fin du tableau
2/ MAJ du programme arrt.cc (nouvelle fonction) avec nouveaux tests pour
  les changements dans Range, et decode de Range a partir de chaines de
  caracteres de type start:end , start:end:step
3/ Numero de version SOPHYA -> 2.565
                                           Reza  4/07/2022
parent a3130f68
......@@ -2,7 +2,7 @@
#define SVERSION_H
#define SOPHYA_VERSION 2.5
#define SOPHYA_REVISION 62
#define SOPHYA_REVISION 65
#define SOPHYA_TAG "V_Jun2022"
#endif
......@@ -351,10 +351,15 @@ sa_size_t EnumeratedSequence::FillFromFile(istream& is, sa_size_t& nr, sa_size_t
This class can be used to define a range of indices. Range objects are used to extract
sub-arrays and slices, from arrays and matrices.
\sa SOPHYA::TArray SOPHYA::TMatrix
It is possible to specify negative values for the start, and/or end indices.
Negative values correspond to an element index counted from the end of the array,
-1 correspond to the last element, -2 to the element before the last one ...
*/
/*!
Constructor defining a range corresponding to the single index \b start
Constructor defining a range corresponding to the single index \b start.
A negative value specify an element index counted from the last element (-1:last element)
\param start : start=end index
*/
Range::Range(sa_size_t start)
......@@ -366,12 +371,15 @@ Range::Range(sa_size_t start)
}
/*!
Constructor defining defining the range of indices, from \b start to \b end
Constructor defining defining the range of indices, from \b start to \b end (start <= index <= end)
negatives values correspond to indexes counted from the last element (-1: last element)
\param start : start index (inclusive)
\param end : end index (inclusive)
*/
Range::Range(sa_size_t start, sa_size_t end)
{
if ((start>0)&&(end>0)&&(start>end))
throw RangeCheckError("Range::Range(start, end) ERROR : start>end with start>0, end>0 ");
start_ = start;
end_ = end;
if (end >= start) size_ = end-start+1;
......@@ -381,12 +389,18 @@ Range::Range(sa_size_t start, sa_size_t end)
/*!
Constructor defining defining the range of indices, from \b start to \b end
negatives values can be specified for start,end and correspond then to indexes counted
from the last element (-1: last element)
\param start : start index (inclusive)
\param end : end index (inclusive)
\param step : step (or stride) = index increment
\param step : step (or stride) = index increment - should be positive (step \>= 1)
step is set to one (step=1) if less thane one (step < 1)
*/
Range::Range(sa_size_t start, sa_size_t end, sa_size_t step)
{
if ((start>0)&&(end>0)&&(start>end))
throw RangeCheckError("Range::Range(start, end, step) ERROR : start>end with start>0, end>0 ");
start_ = start;
end_ = end;
step_ = (step > 0) ? step : 1;
......@@ -403,27 +417,31 @@ Range::Range(sa_size_t start, sa_size_t end, sa_size_t step)
\param size : size (number of elements, used if \>= 1 )
\param step : step (or stride) = index increment
\warning If \b size \>= 1 , \b end index computed automatically.
If \b size \< 1 and \b end < \b start , equivalent to \b end = Range()::lastIndex()
\verbatim
o size <= 0 : same as Range(start,end,step)
o size > 0
start>=0 : end computed as end=start+(size-1)*step
start<0 : start computed as start=end-(size-1)*step
\endverbatim
*/
Range::Range(sa_size_t start, sa_size_t end, sa_size_t size, sa_size_t step)
{
start_ = start;
step_ = (step > 0) ? step : 1;
if (size > 0) { // Nb d'elements fixe
size_ = size;
if ( (start == end) && (end == Range::lastIndex()) ) start_ = end_ = end;
else end_ = start_+(size_-1)*step_;
}
else {
if (end >= start) { // Indice de fin fixe
end_ = end;
if (size < 1) {
if ((start>0)&&(end>0)&&(start>end))
throw RangeCheckError("Range::Range(start, end, size, step) ERROR : size<1 and start>end with start>0, end>0 ");
start_ = start;
end_ = end;
step_ = (step > 0) ? step : 1;
if (step < 1) step = 1;
if (end >= start)
size_ = (end-start)/step_+1;
}
else { // rien fixe
size_ = 0;
end_ = Range::lastIndex();
}
else size_ = 0;
}
else { // size>0 : Nb d'elements fixe
size_ = size;
if (start >= 0) { start_=start; end_= start_+(size_-1)*step_; }
else { end_=end; start_=end_-(size_-1)*step_; }
}
}
......@@ -468,14 +486,18 @@ Range::Range(std::string s)
std::string s2=s.substr(p+1);
l=s2.length();
p = s2.find(':');
//DBG cout<<" *DBG*B* s2="<<s2<<" l="<<l<<" p="<<p<<endl;
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());
end_=atol(s2.substr(0,p).c_str());
step_=atol(s2.substr(p+1).c_str());
//DBG cout<<" *DBG*C* s2.substr(0,p)="<<s2.substr(0,p)<<" end="<<end_
//DBG <<" s2.substr(p+1)="<<s2.substr(p+1)<<" step="<<step_<<endl;
if (step_<1) throw ParmError("Range::Range(string s) bad syntax , step<1 ");
if (end_>=start_) size_ = (end_-start_)/step_+1;
return;
......@@ -499,7 +521,7 @@ bool Range::IsEqual(Range const & a) const
/* --Methode-- */
std::ostream& Range::Print(std::ostream& os) const
{
os<<"Range(start="<<start_<<",end="<<end_<<",step="<<step_<<")";
os<<"Range(start="<<start_<<",end="<<end_<<",step="<<step_<<",size="<<size_<<")";
return os;
}
......@@ -509,25 +531,23 @@ std::ostream& Range::Print(std::ostream& os) const
*/
void Range::Update(sa_size_t osz)
{
if ((start_>=0) && (end_ >= 0)) return;
if (osz == 0) {
start_ = end_ = 0;
size_ = step_ = 1;
return;
}
if (end_ == start_) {
end_ = osz-1;
if ((size_ > 0) && (size_ <= osz/step_))
start_ = end_ - (size_-1)*step_;
else {
start_ = end_;
size_ = 1;
if ((start_>=0) && (end_ >= 0)) {
if ((start_>end_)||(end_>=osz)) {
cout<<"Range::Update(osz="<<osz<<") ERROR start="<<start_<<" end="<<end_<<endl;
throw RangeCheckError("Range::Update(osz) ERROR (start_>end_)||(end_>=osz)");
}
return;
}
else {
end_ = osz-1;
size_ = (end_-start_)/step_+1;
}
if (start_<0) start_=osz+start_;
if (end_<0) end_=osz+end_;
if ((start_>end_)||(end_>=osz))
throw RangeCheckError("Range::Update(osz) ERROR (start_>end_)||(end_>=osz) after value update");
size_ = (end_-start_)/step_+1;
//DBG cout << ">>> DBG/Update start=" << start_ << " end=" << end_
//DBG << " size=" << size_ << " step=" << step_ << endl;
return;
......
......@@ -4,7 +4,7 @@
Programme de test des fonctions de base sur les
TArray/TMatrix de SOPHYA
(2000-2006) updated 2014
(2000-2006) updated 2014, 2016, 2022
csh> arrt
# -> Help/Usage
# Pour effectuer les tests avec RC
......@@ -13,7 +13,7 @@
## Test avec des plus grandes tailles
csh> arrt check 700
# Pour verification avec les impressions
csh> arrt a / w / m / ascio
csh> arrt a / w / m / ascio / range
----------------------------------------------------------*/
#include "sopnamsp.h"
#include "machdefs.h"
......@@ -38,6 +38,8 @@ void _ZZ_TestTMatrixRC_YY_(TMatrix<r_8> & m); // this is in sopemtx.cc
static int checktarr(int msz=32);
static int checktarr_funcfloat(int msz=32);
static int checktarr_cmplx(int msz=32);
// Fonction checktarr_range(int msz, int prt) ajoute en 2022
static int checktarr_range(int prt=0);
//----------------------------------------------------------------------------------
static int prtlev = 1;
......@@ -50,17 +52,18 @@ int main(int narg, char* arg[])
InitTim(); // Initializing the CPU timer
if ((narg < 2)||((narg>1)&&(strcmp(arg[1],"-h")==0))) {
cout << " arrt - TArray<T> Test - Usage arrt check/a/w/m/z [size=5] [prtlev=1] [nprt=50]\n"
cout << " arrt - TArray<T> Test - Usage arrt check/a/w/m/range/z [size=32] [prtlev=1] [nprt=50]\n"
<< " a: Simple Array Test w: a+ PPersist Test (FIO_TArray<T>) \n"
<< " m: Matrix and Vector Test \n"
<< " check: TArray Test/Check with Rc (minimal size for check=32) \n"
<< " ascio: Test of ascii I/O \n"
<< " ascio: Test of ascii I/O \n"
<< " range: additional checks for the Range class \n"
<< " z: Appel_ZZ_TestTMatrixRC_YY_ " << endl;
exit(0);
}
string opt = arg[1];
int sz = 5;
int sz = 32;
if (narg > 2) sz = atoi(arg[2]);
uint_4 nprt = 50;
if (narg > 3) prtlev = atoi(arg[3]);
......@@ -69,7 +72,7 @@ int main(int narg, char* arg[])
BaseArray::SetMaxPrint(nprt, prtlev);
int rc = 0;
int rc1=0, rc2=0, rc3=0;
int rc1=0, rc2=0, rc3=0, rc4=0;
try {
if (opt == "w") tstarr(true);
else if (opt == "a") tstarr(false);
......@@ -83,6 +86,7 @@ int main(int narg, char* arg[])
}
else if (opt == "m") tstmtx(sz);
else if (opt == "ascio") tstasciiio();
else if (opt == "range") checktarr_range(2);
else if (opt == "check") {
Timer tm("arrt.cc");
rc1 = checktarr(sz);
......@@ -94,7 +98,9 @@ int main(int narg, char* arg[])
rc3 = checktarr_cmplx(sz);
cout<<"=======> arrt.cc/Info Rc from checktarr_cmplx() : " << rc3 << endl;
tm.Split("Done checktarr_cmplx()");
rc=rc1+256*rc2+4096*rc3;
rc4 = checktarr_range(0);
cout<<"=======> arrt.cc/Info Rc from checktarr_range() : " << rc4 << endl;
rc=rc1+256*rc2+4096*rc3+65536*rc4;
}
else {
cout << " arrt/Error : unknown option ! " << endl;
......@@ -1281,3 +1287,220 @@ int checktarr_cmplx(int sz)
return rc;
}
ostream& list_range_index(ostream& os, Range const& rng)
{
os<<"... indexlist: {";
for(sa_size_t i=rng.Start(); i<=rng.End(); i+=rng.Step()) {
if (i>rng.Start()) os<<", "<<i;
else os<<i;
}
os<<"}"<<endl;
return os;
}
//----------------------------------------------------------------------------------------
//---- checktarr_range: Range / TArray / SubArray tests with return code and print ------
//--------------------- (Fonction written in June 2022) -------------------------------
//---------------------------------- Rc=0 if OK -----------------------------------
static int checktarr_range(int prt)
{
/* Exemple de tableau de taille 12 : (RevIndex: index a partir de la fin)
Index 0 1 2 3 4 5 6 7 8 9 10 11
RevIndex: -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1
Range(1,9,3): x x x ={1,4,7}
Range(-7,-3): x x x x x ={5,6,7,8,9}
Range(-7,-3,2): x x x ={5,7,9}
Range(-1,-1,3,1): x x x ={9,10,11}
Range(-1,-1,3,2): x x x ={7,9,11}
*/
cout << "\n :::::: CheckArrayRange (Function checktarr_range(prt="<<prt<<") :::::: " << endl;
sa_size_t szr=12;
if (prt>0) {
sa_size_t sz=szr;
Range rng(1,9,3);
cout<<" Range(1,9,3): "<<rng; rng.Update(sz); cout<< " After Update(sz="<<sz<<"): "<<rng<<endl;
if (prt>1) list_range_index(cout,rng);
rng=Range(-7,-3);
cout<<" Range(-7,-3): "<<rng; rng.Update(sz); cout<< " After Update(sz="<<sz<<"): "<<rng<<endl;
if (prt>1) list_range_index(cout,rng);
rng=Range(-7,-3,2);
cout<<" Range(-7,-3,2): "<<rng; rng.Update(sz); cout<< " After Update(sz="<<sz<<"): "<<rng<<endl;
if (prt>1) list_range_index(cout,rng);
rng=Range(-1,-1,3,1);
cout<<" Range(-1,-1,3,1): "<<rng; rng.Update(sz); cout<< " After Update(sz="<<sz<<"): "<<rng<<endl;
if (prt>1) list_range_index(cout,rng);
rng=Range(-1,-1,3,2);
cout<<" Range(-1,-1,3,2): "<<rng; rng.Update(sz); cout<< " After Update(sz="<<sz<<"): "<<rng<<endl;
if (prt>1) list_range_index(cout,rng);
rng=Range(string("6:8"));
cout<<" Range('6:8'): "<<rng; rng.Update(sz); cout<< " After Update(sz="<<sz<<"): "<<rng<<endl;
if (prt>1) list_range_index(cout,rng);
rng=Range(string("6:10:3"));
cout<<" Range('6:10:3'): "<<rng; rng.Update(sz); cout<< " After Update(sz="<<sz<<"): "<<rng<<endl;
if (prt>1) list_range_index(cout,rng);
rng=Range(string("9:"));
cout<<" Range('9:'): "<<rng; rng.Update(sz); cout<< " After Update(sz="<<sz<<"): "<<rng<<endl;
if (prt>1) list_range_index(cout,rng);
rng=Range(string("-4:"));
cout<<" Range('-4:'): "<<rng; rng.Update(sz); cout<< " After Update(sz="<<sz<<"): "<<rng<<endl;
if (prt>1) list_range_index(cout,rng);
}
int rc = 0;
Range r1(0),r2(0);
r1=Range(-1,-1,3,1); r2=Range(9,11); r1.Update(szr);
if (r1 != r2) {
rc++;
if (prtlev>0) cout << " Range decoding error for range: r1="<<r1<<" r2="<<r2<<endl;
}
r1=Range(-1,-1,3,2); r2=Range(7,11,2); r1.Update(szr);
if (r1 != r2) {
rc++;
if (prtlev>0) cout << " Range decoding error for range: r1="<<r1<<" r2="<<r2<<endl;
}
r1 = Range(string("6:8")); r2=Range(6,8);
if (r1 != r2) {
rc++;
if (prtlev>0) cout << " Range decoding error for range: r1="<<r1<<" r2="<<r2<<endl;
}
r1 = Range(string("6:10:3")); r2=Range(6,10,3);
if (r1 != r2) {
rc++;
if (prtlev>0) cout << " Range decoding error for range: r1="<<r1<<" r2="<<r2<<endl;
}
r1 = Range(string("9:")); r2=Range(9,Range::lastIndex());
r1.Update(szr); r2.Update(szr);
if (r1 != r2) {
rc++;
if (prtlev>0) cout << " Range decoding error for range: r1="<<r1<<" r2="<<r2<<endl;
}
r1 = Range(string("-4:")); r2=Range(-4,Range::lastIndex());
r1.Update(szr); r2.Update(szr);
if (r1 != r2) {
rc++;
if (prtlev>0) cout << " Range decoding error for range: r1="<<r1<<" r2="<<r2<<endl;
}
r1 = Range(string("-6:-1:3")); r2=Range(-6,Range::lastIndex(),3);
r1.Update(szr); r2.Update(szr);
if (r1 != r2) {
rc++;
if (prtlev>0) cout << " Range decoding error for range: r1="<<r1<<" r2="<<r2<<endl;
}
if (rc==0)
cout << "(1) checktarr_range() - Range decoding OK " << endl;
else
cout << "(1) checktarr_range() - Range decoding ERROR rc=" <<rc<<endl;
sa_size_t szz=5;
TArray<int_4> IA(szr,szr,szz);
TArray<int_4> IV(szr);
IV = RegularSequence(1.,3.);
TArray<int_4> IA2(szr,szr);
std::vector<Range> vrng2;
vrng2.push_back(Range::all());
vrng2.push_back(Range::all());
for(sa_size_t j=0; j<szr; j++) {
vrng2[1] = Range(j);
//DBG cout<<"*DBG* IA2.SubArray(vrng2) for j="<<j<<endl;
IA2.SubArray(vrng2) = IV+(int_4)(j*200);
}
std::vector<Range> vrng;
vrng.push_back(Range::all());
vrng.push_back(Range::all());
vrng.push_back(Range::all());
for(sa_size_t k=0; k<szz; k++) {
vrng[2] = Range(k);
//DBG cout<<"*DBG* IA.SubArray(vrng) for k="<<k<<endl;
IA.SubArray(vrng) = IA2+(int_4)(k*10000);
}
if (prt>1) cout<<" --- Array IA after fill: "<<IA<<endl;
std::vector<Range> vrngs=Range::str2vranges(string("[:,:,2]"));
TArray<int_4> IAE=IA.SubArray(vrngs);
TArray<int_4> DAE=IAE-(IA2+(int_4)20000);
int_4 vmin, vmax;
DAE.MinMax(vmin, vmax);
if ((vmin!=0)||(vmax!=0)) {
rc += 16;
cout << "(2) checktarr_range() Subarray extraction ERROR for IAE, min="<<vmin<<" max="<<vmax<<" -> Rc+=16"<<endl;
}
else cout << "(2) checktarr_range() Subarray extraction OK for IAE"<<endl;
// TArray<int_4> IAE2=IA(Range(-5,Range::last()), Range(0,1), Range::all());
int errcnt=0;
{
vrngs.clear();
vrngs=Range::str2vranges(string("[-5:]"));
TArray<int_4> IVE=IV.SubArray(vrngs);
TArray<int_4> IVCK(5);
IVCK=RegularSequence(1.+3.*(szr-5),3.);
TArray<int_4> DVE=IVE-IVCK;
DVE.MinMax(vmin, vmax);
if ((vmin!=0)||(vmax!=0)) errcnt+=2;
}
{
vrngs.clear();
vrngs.push_back(Range(-1,-1,3,2));
TArray<int_4> IVE=IV.SubArray(vrngs);
TArray<int_4> IVCK(3);
IVCK=RegularSequence(1.+3.*(szr-5),6.);
TArray<int_4> DVE=IVE-IVCK;
DVE.MinMax(vmin, vmax);
if ((vmin!=0)||(vmax!=0)) errcnt+=4;
}
if (errcnt>0) {
rc += 32;
cout << "(3) checktarr_range() Subarray extraction ERROR for IVE, errcnt="<<errcnt<<endl;
}
else
cout << "(3) checktarr_range() Subarray extraction OK for IVE"<<endl;
errcnt=0;
//--- Extraction sous tableau a partir du tableau 3D
{
vrngs.clear();
vrngs=Range::str2vranges(string("[-5:,6:10:2,3]"));
TArray<int_4> IAE2=IA.SubArray(vrngs);
TArray<int_4> IVCK(5);
IVCK=RegularSequence(1.+3.*(szr-5),3.);
TArray<int_4> IACK(5,3);
for(sa_size_t j=0; j<3; j++)
IACK(Range::all(), Range(j), Range::all()) = (IVCK+(int_4)((j*2+6)*200));
if (prtlev>2) {
cout<<"--- Array IAE2 (extract): "<<IAE2;
cout<<"--- Array IACK: "<<IACK;
}
TArray<int_4> DAE2=IAE2-(IACK+(int_4)30000);
DAE2.MinMax(vmin, vmax);
if ((vmin!=0)||(vmax!=0)) errcnt+=2;
else {
if (prtlev>1) cout<<"... DAE2=IAE2-(IACK+(int_4)30000) check OK"<<endl;
}
vrngs[2]=Range(4);
IAE2=IA.SubArray(vrngs);
DAE2=IAE2-(IACK+(int_4)40000);
DAE2.MinMax(vmin, vmax);
if ((vmin!=0)||(vmax!=0)) errcnt+=4;
else {
if (prtlev>1) cout<<"... DAE2=IAE2-(IACK+(int_4)40000) check OK"<<endl;
}
vrngs[1]=Range(-8,-4,2);
vrngs[2]=Range(-3);
IAE2=IA.SubArray(vrngs);
DAE2=IAE2-(IACK+(int_4)(20000-2*200));
DAE2.MinMax(vmin, vmax);
if ((vmin!=0)||(vmax!=0)) errcnt+=8;
else {
if (prtlev>1) cout<<"... DAE2=IAE2-(IACK+(int_4)(20000-2*200)) check OK"<<endl;
}
}
if (errcnt>0) {
rc += 64;
cout << "(4) checktarr_range() Subarray extraction ERROR for IAE2, errcnt="<<errcnt<<endl;
}
else
cout << "(4) checktarr_range() Subarray extraction OK for IAE2"<<endl;
return rc;
}
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