387 lines
6.2 KiB
C++
387 lines
6.2 KiB
C++
#include <amscppperm1/amscppperm1.hpp>
|
|
|
|
namespace ams
|
|
{
|
|
namespace perm
|
|
{
|
|
|
|
permutation::permutation()
|
|
{
|
|
length = 0;
|
|
data = NULL;
|
|
return;
|
|
}
|
|
|
|
permutation::~permutation()
|
|
{
|
|
length = 0;
|
|
if(data!=NULL) {delete[] data; data=NULL;}
|
|
}
|
|
|
|
permutation::permutation(const permutation& other)
|
|
{
|
|
int res;
|
|
int I;
|
|
length = 0;
|
|
data = NULL;
|
|
|
|
if(this!=&other)
|
|
{
|
|
res = this->resize(other.length);
|
|
if(res==perm_success)
|
|
{
|
|
for(I=0;I<length&&I<other.length;I++)
|
|
{
|
|
this->data[I] = other.data[I];
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
permutation::permutation(const int _length)
|
|
{
|
|
int res;
|
|
int I;
|
|
length = 0;
|
|
data = NULL;
|
|
|
|
res = this->resize(_length);
|
|
if(res==perm_success)
|
|
{
|
|
for(I=0;I<length;I++)
|
|
{
|
|
this->data[I] = I;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
permutation::permutation(const int *parray, const int _length)
|
|
{
|
|
int res;
|
|
int I;
|
|
length = 0;
|
|
data = NULL;
|
|
|
|
res = this->resize(_length);
|
|
if(res==perm_success)
|
|
{
|
|
for(I=0;I<length;I++)
|
|
{
|
|
this->data[I] = parray[I];
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
permutation::permutation(std::initializer_list<int> q)
|
|
{
|
|
int res;
|
|
int I;
|
|
length = 0;
|
|
data = NULL;
|
|
|
|
res = this->resize(q.size());
|
|
if(res==perm_success)
|
|
{
|
|
I = 0;
|
|
for(int elem : q)
|
|
{
|
|
data[I] = elem;
|
|
if(I<length) I++;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
permutation permutation::operator=(const permutation& other)
|
|
{
|
|
int res;
|
|
int I;
|
|
|
|
if(this!=&other)
|
|
{
|
|
res = this->resize(other.length);
|
|
if(res==perm_success)
|
|
{
|
|
for(I=0;I<length&&I<other.length;I++)
|
|
{
|
|
this->data[I] = other.data[I];
|
|
}
|
|
}
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
int permutation::resize(const int _nlength)
|
|
{
|
|
int ret = perm_success;
|
|
int I;
|
|
|
|
int *newdata = NULL;
|
|
|
|
if(_nlength<=0)
|
|
{
|
|
length = 0;
|
|
if(data!=NULL) {delete[] data; data=NULL;}
|
|
ret = perm_failure;
|
|
return ret;
|
|
}
|
|
|
|
newdata = new(std::nothrow) int[_nlength];
|
|
if(newdata==NULL)
|
|
{
|
|
ret = perm_failure;
|
|
return ret;
|
|
}
|
|
|
|
for(I=0;I<length && I<_nlength;I++)
|
|
{
|
|
newdata[I] = data[I];
|
|
}
|
|
for(I=length;I<_nlength;I++)
|
|
{
|
|
newdata[I] = 0; //will have to fill in for it to be a valid permutation
|
|
}
|
|
|
|
if(data!=NULL) {delete[] data; data=NULL;}
|
|
data = newdata;
|
|
length = _nlength;
|
|
ret = perm_success;
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool permutation::valid() const
|
|
{
|
|
bool ret = 1;
|
|
int *wrk = NULL;
|
|
int I,J;
|
|
|
|
wrk = new(std::nothrow) int[length];
|
|
if(wrk==NULL)
|
|
{
|
|
ret = 0; //wrk buffer allocation failed
|
|
return ret;
|
|
}
|
|
|
|
for(I=0;I<length;I++) wrk[I] = 0;
|
|
|
|
for(I=0;I<length;I++)
|
|
{
|
|
J = data[I];
|
|
if(J<0 || J>=length)
|
|
{
|
|
ret = 0;
|
|
break;
|
|
}
|
|
if(wrk[J]==1)
|
|
{
|
|
ret = 0;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
wrk[J] = 1;
|
|
}
|
|
}
|
|
|
|
|
|
if(wrk!=NULL) {delete[] wrk; wrk=NULL;}
|
|
|
|
return ret;
|
|
}
|
|
|
|
bool permutation::operator==(const permutation &other) const
|
|
{
|
|
int I;
|
|
bool ret = 1;
|
|
if(this->length != other.length)
|
|
{
|
|
ret = 0; return ret;
|
|
}
|
|
for(I=0;I<length;I++)
|
|
{
|
|
if(this->data[I]!=other.data[I])
|
|
{
|
|
ret = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int permutation::_intl_calculate_mindex(int *mindex, int *wrk)
|
|
{
|
|
int ret = perm_success;
|
|
//if(!valid()) //<--- a redundant test given that this is only called from levi_civita
|
|
//{
|
|
// ret = perm_failure;
|
|
// return ret;
|
|
//}
|
|
|
|
int I,J,K,L;
|
|
|
|
for(I=0;I<length;I++) wrk[I]=0;
|
|
for(I=0;I<length;I++)
|
|
{
|
|
J = data[I];
|
|
L = 0;
|
|
for(K=0;K<=J;K++)
|
|
{
|
|
if(wrk[K]==0)
|
|
{
|
|
L = L + 1;
|
|
}
|
|
}
|
|
wrk[J] = 1;
|
|
mindex[I] = L-1;
|
|
}
|
|
ret = amsperm1_success;
|
|
|
|
return ret;
|
|
}
|
|
|
|
int permutation::levi_civita()
|
|
{
|
|
int ret = 0;
|
|
int *mindex = NULL;
|
|
int *wrk = NULL;
|
|
|
|
int Q;
|
|
|
|
if(!valid())
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
if(length<=0)
|
|
{
|
|
return ret;
|
|
}
|
|
|
|
mindex = new(std::nothrow) int[length];
|
|
wrk = new(std::nothrow) int[length];
|
|
|
|
this->_intl_calculate_mindex(mindex,wrk);
|
|
|
|
if(length==1)
|
|
{
|
|
ret = 0;
|
|
return ret;
|
|
}
|
|
|
|
Q = (mindex[0] + mindex[1]*length)%2;
|
|
|
|
ret = 2*(!Q)-1;
|
|
|
|
|
|
if(mindex!=NULL) {delete[] mindex; mindex=NULL;}
|
|
if(wrk!=NULL) {delete[] wrk; wrk=NULL;}
|
|
|
|
return ret;
|
|
}
|
|
|
|
permutation permutation::first(int length)
|
|
{
|
|
permutation ret = permutation(length);
|
|
int I;
|
|
for(I=0;I<ret.length;I++)
|
|
{
|
|
ret.data[I] = I;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
permutation permutation::last(int length)
|
|
{
|
|
permutation ret = permutation(length);
|
|
int I;
|
|
for(I=0;I<ret.length;I++)
|
|
{
|
|
ret.data[I] = ret.length-I-1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
permutation permutation::operator*(const permutation &other) const
|
|
{
|
|
int I,J;
|
|
permutation ret = permutation(this->length);
|
|
for(I=0;I<length;I++)
|
|
{
|
|
J = this->data[I];
|
|
ret[I] = other[J];
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
permutation permutation::inverse() const
|
|
{
|
|
int I,J;
|
|
permutation ret = permutation(this->length);
|
|
for(I=0;I<length;I++)
|
|
{
|
|
J = this->data[I];
|
|
ret[J] = I;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int& permutation::operator[](const int ind)
|
|
{
|
|
return data[ind];
|
|
}
|
|
|
|
const int& permutation::operator[](const int ind) const
|
|
{
|
|
return data[ind];
|
|
}
|
|
|
|
int& permutation::at(const int ind)
|
|
{
|
|
return data[ind];
|
|
}
|
|
|
|
const int& permutation::at(const int ind) const
|
|
{
|
|
return data[ind];
|
|
}
|
|
|
|
void permutation::print(int style)
|
|
{
|
|
int I;
|
|
if(style==0)
|
|
{
|
|
printf("{");
|
|
for(I=0;I<length-1;I++) printf("%d,",data[I]);
|
|
printf("%d}",data[length-1]);
|
|
}
|
|
else if(style==1)
|
|
{
|
|
printf("permutation:{");
|
|
for(I=0;I<length-1;I++) printf("%d,",data[I]);
|
|
printf("%d}",data[length-1]);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void test_permutation1()
|
|
{
|
|
permutation a = permutation(5);
|
|
|
|
a.print(1);
|
|
|
|
return;
|
|
}
|
|
|
|
}; //end namespace perm
|
|
}; //end namespace ams
|