updates
parent
a0d02475cc
commit
073d1ce57c
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,541 @@
|
||||
#include <amscppperm1/amscppperm1.hpp>
|
||||
|
||||
namespace ams
|
||||
{
|
||||
namespace perm
|
||||
{
|
||||
|
||||
ipermutation::ipermutation()
|
||||
{
|
||||
length = 0;
|
||||
perm = NULL;
|
||||
index = -1;
|
||||
mind = NULL;
|
||||
wrk = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ipermutation::~ipermutation()
|
||||
{
|
||||
if(perm!=NULL) {delete[] perm; perm = NULL;}
|
||||
if(mind!=NULL) {delete[] mind; mind = NULL;}
|
||||
if(wrk!=NULL) {delete[] wrk; wrk = NULL;}
|
||||
length = 0;
|
||||
index = -1;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ipermutation::ipermutation(const int _length)
|
||||
{
|
||||
length = 0;
|
||||
perm = NULL;
|
||||
index = -1;
|
||||
mind = NULL;
|
||||
wrk = NULL;
|
||||
|
||||
this->resize(_length);
|
||||
}
|
||||
|
||||
ipermutation::ipermutation(const int _index, const int _length)
|
||||
{
|
||||
int res = perm_failure;
|
||||
length = 0;
|
||||
perm = NULL;
|
||||
index = -1;
|
||||
mind = NULL;
|
||||
wrk = NULL;
|
||||
|
||||
if(_length>0)
|
||||
{
|
||||
res = this->resize(_length);
|
||||
if(res==perm_success)
|
||||
{
|
||||
index = _index;
|
||||
amsperm1_index_to_mindex(index,mind,length);
|
||||
amsperm1_mindex_to_perm(mind,perm,wrk,length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ipermutation::ipermutation(const int *parray, const int _length)
|
||||
{
|
||||
int I;
|
||||
int res = perm_failure;
|
||||
length = 0;
|
||||
perm = NULL;
|
||||
index = -1;
|
||||
mind = NULL;
|
||||
wrk = NULL;
|
||||
|
||||
if(_length>0)
|
||||
{
|
||||
res = this->resize(_length);
|
||||
if(res==perm_success)
|
||||
{
|
||||
for(I=0;I<length;I++) perm[I] = parray[I];
|
||||
amsperm1_perm_to_mindex(perm,mind,wrk,length);
|
||||
index = amsperm1_mindex_to_index(mind,length);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ipermutation::ipermutation(std::initializer_list<int> q)
|
||||
{
|
||||
int I;
|
||||
//int elem;
|
||||
int res = perm_failure;
|
||||
length = 0;
|
||||
perm = NULL;
|
||||
index = -1;
|
||||
mind = NULL;
|
||||
wrk = NULL;
|
||||
|
||||
if(q.size()>0)
|
||||
{
|
||||
res = this->resize(q.size());
|
||||
if(res==perm_success)
|
||||
{
|
||||
//for(I=0;I<length;I++) perm[I] = q[I];
|
||||
//need to access things with annoying c++ish iterators
|
||||
I = 0;
|
||||
for(int elem : q)
|
||||
{
|
||||
perm[I] = elem;
|
||||
if(I<length) I++;
|
||||
}
|
||||
amsperm1_perm_to_mindex(perm,mind,wrk,length);
|
||||
index = amsperm1_mindex_to_index(mind,length);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int ipermutation::resize(const int _nlength)
|
||||
{
|
||||
int ret = perm_success;
|
||||
|
||||
int *newperm = NULL;
|
||||
int *newmind = NULL;
|
||||
int *newwrk = NULL;
|
||||
int newind;
|
||||
|
||||
int I;
|
||||
|
||||
if(_nlength<=0)
|
||||
{
|
||||
length = 0;
|
||||
index = -1;
|
||||
if(perm!=NULL) {delete[] perm; perm=NULL;}
|
||||
if(mind!=NULL) {delete[] mind; mind=NULL;}
|
||||
if(wrk!=NULL) {delete[] wrk; wrk=NULL;}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
newperm = new(std::nothrow) int[_nlength];
|
||||
newmind = new(std::nothrow) int[_nlength];
|
||||
newwrk = new(std::nothrow) int[_nlength];
|
||||
|
||||
if(newperm==NULL || newmind == NULL || newwrk == NULL)
|
||||
{
|
||||
if(newperm!=NULL) {delete[] newperm; newperm=NULL;}
|
||||
if(newmind!=NULL) {delete[] newmind; newmind=NULL;}
|
||||
if(newwrk!=NULL) {delete[] newwrk; newwrk=NULL;}
|
||||
|
||||
ret = perm_failure;
|
||||
return ret;
|
||||
}
|
||||
|
||||
for(I=0;I<length && I<_nlength; I++)
|
||||
{
|
||||
newmind[I] = mind[I];
|
||||
}
|
||||
for(I=length;I<_nlength;I++) newmind[I] = 0;
|
||||
|
||||
newind = amsperm1_mindex_to_index(newmind,_nlength);
|
||||
amsperm1_mindex_to_perm(newmind,newperm,newwrk,_nlength);
|
||||
|
||||
if(perm!=NULL) {delete[] perm; perm = NULL;}
|
||||
if(mind!=NULL) {delete[] mind; mind = NULL;}
|
||||
if(wrk!=NULL) {delete[] wrk; wrk = NULL;}
|
||||
length = 0;
|
||||
index = -1;
|
||||
|
||||
length = _nlength;
|
||||
index = newind;
|
||||
perm = newperm;
|
||||
mind = newmind;
|
||||
wrk = newwrk;
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ipermutation::ipermutation(const ipermutation& other)
|
||||
{
|
||||
int res;
|
||||
length = 0;
|
||||
perm = NULL;
|
||||
index = -1;
|
||||
mind = NULL;
|
||||
wrk = NULL;
|
||||
|
||||
int I;
|
||||
|
||||
if(this!=&other)
|
||||
{
|
||||
res = this->resize(other.length);
|
||||
if(res==perm_success)
|
||||
{
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
this->perm[I] = other.perm[I];
|
||||
this->wrk[I] = other.wrk[I];
|
||||
this->mind[I] = other.mind[I];
|
||||
this->index = other.index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ipermutation ipermutation::operator=(const ipermutation &other)
|
||||
{
|
||||
int res;
|
||||
int I;
|
||||
if(this!=&other)
|
||||
{
|
||||
res = this->resize(other.length);
|
||||
if(res==perm_success)
|
||||
{
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
this->perm[I] = other.perm[I];
|
||||
this->wrk[I] = other.wrk[I];
|
||||
this->mind[I] = other.mind[I];
|
||||
this->index = other.index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
int& ipermutation::operator[](const int ind)
|
||||
{
|
||||
return perm[ind];
|
||||
}
|
||||
|
||||
const int& ipermutation::operator[](const int ind) const
|
||||
{
|
||||
return perm[ind];
|
||||
}
|
||||
|
||||
int& ipermutation::at(const int ind)
|
||||
{
|
||||
return perm[ind];
|
||||
}
|
||||
|
||||
const int& ipermutation::at(const int ind) const
|
||||
{
|
||||
return perm[ind];
|
||||
}
|
||||
|
||||
int factorial(int n)
|
||||
{
|
||||
return amsperm1_factorial(n);
|
||||
}
|
||||
|
||||
bool ipermutation::valid() const
|
||||
{
|
||||
bool ret = 1;
|
||||
int *lmind = NULL;
|
||||
int *lwrk = NULL;
|
||||
int *lperm = NULL;
|
||||
|
||||
if(index<0 || index>=factorial(length))
|
||||
{
|
||||
ret = 0; return ret;
|
||||
}
|
||||
|
||||
//other tests - skip for speed?
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ipermutation::operator==(const ipermutation other) const
|
||||
{
|
||||
bool ret = 1;
|
||||
int I;
|
||||
|
||||
if(length!=other.length)
|
||||
{
|
||||
ret = 0; return ret;
|
||||
}
|
||||
if(index != other.index)
|
||||
{
|
||||
ret = 0; return ret;
|
||||
}
|
||||
|
||||
//additional tests (skip for speed?)
|
||||
for(I=0;I<length && I<other.length;I++)
|
||||
{
|
||||
if(perm[I]!=other.perm[I]) {ret = 0; break;}
|
||||
if(mind[I]!=other.mind[I]) {ret = 0; break;}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ipermutation ipermutation_first(int _nlength)
|
||||
{
|
||||
ipermutation ret = ipermutation(0,_nlength);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ipermutation ipermutation_last(int _nlength)
|
||||
{
|
||||
int f = factorial(_nlength);
|
||||
ipermutation ret = ipermutation(f-1,_nlength);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int levi_civita(const ipermutation p)
|
||||
{
|
||||
int ret = 0;
|
||||
bool v = p.valid();
|
||||
if(v)
|
||||
{
|
||||
ret = 2*(!(p.index%2))-1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//pre-increment operator
|
||||
ipermutation& ipermutation::operator++()
|
||||
{
|
||||
int I;
|
||||
if(valid())
|
||||
{
|
||||
if(index+1>=0 && index+1<factorial(length))
|
||||
{
|
||||
index = index + 1;
|
||||
amsperm1_index_to_mindex(index,mind,length);
|
||||
amsperm1_mindex_to_perm(mind,perm,wrk,length);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = -1;
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
perm[I] = -1;
|
||||
mind[I] = -1;
|
||||
wrk[I] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
ipermutation& ipermutation::operator--()
|
||||
{
|
||||
int I;
|
||||
if(valid())
|
||||
{
|
||||
if(index-1>=0 && index-1<factorial(length))
|
||||
{
|
||||
index = index - 1;
|
||||
amsperm1_index_to_mindex(index,mind,length);
|
||||
amsperm1_mindex_to_perm(mind,perm,wrk,length);
|
||||
}
|
||||
else
|
||||
{
|
||||
index = -1;
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
perm[I] = -1;
|
||||
mind[I] = -1;
|
||||
wrk[I] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//post-increment operators
|
||||
ipermutation ipermutation::operator++(int)
|
||||
{
|
||||
ipermutation ret = *this;
|
||||
//++ret;
|
||||
this->operator++();
|
||||
return ret;
|
||||
}
|
||||
|
||||
ipermutation ipermutation::operator--(int)
|
||||
{
|
||||
ipermutation ret = *this;
|
||||
//--ret;
|
||||
this->operator--();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ipermutation::print(int style)
|
||||
{
|
||||
int I;
|
||||
if(style==0)
|
||||
{
|
||||
printf("{");
|
||||
for(I=0;I<length-1;I++) printf("%d,",perm[I]);
|
||||
printf("%d}",perm[length-1]);
|
||||
}
|
||||
else if(style==1)
|
||||
{
|
||||
printf("%d:{",index);
|
||||
for(I=0;I<length-1;I++) printf("%d,",perm[I]);
|
||||
printf("%d}",perm[length-1]);
|
||||
}
|
||||
else if(style==2)
|
||||
{
|
||||
printf("ipermutation[%d]:{",index);
|
||||
for(I=0;I<length-1;I++) printf("%d,",perm[I]);
|
||||
printf("%d}",perm[length-1]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void test_ipermutation1()
|
||||
{
|
||||
ipermutation a = ipermutation(4);
|
||||
ipermutation *b = NULL;
|
||||
|
||||
b = new(std::nothrow) ipermutation(4);
|
||||
|
||||
a.print(); printf("\n");
|
||||
b->print(); printf("\n");
|
||||
a++;
|
||||
a.print(); printf("\n");
|
||||
++a; a.print(); printf("\n");
|
||||
a++;
|
||||
a++;
|
||||
a++;
|
||||
*b = a;
|
||||
b->print(2); printf("\n");
|
||||
b->resize(3);
|
||||
a.resize(5);
|
||||
a.print(); printf("\n");
|
||||
b->print(); printf("\n");
|
||||
int I;
|
||||
*b = ipermutation_first(3);
|
||||
for(I=0;I<8;I++)
|
||||
{
|
||||
|
||||
b->print(2); printf("\n");
|
||||
(*b)++;
|
||||
}
|
||||
|
||||
for(a=ipermutation_last(3);a.valid();a--)
|
||||
{
|
||||
a.print(2); printf("\n");
|
||||
}
|
||||
|
||||
delete(b);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ipermutation::recalc_from_perm()
|
||||
{
|
||||
amsperm1_perm_to_mindex(perm,mind,wrk,length);
|
||||
index = amsperm1_mindex_to_index(mind,length);
|
||||
return;
|
||||
}
|
||||
|
||||
//compose permutations
|
||||
ipermutation ipermutation::operator*(const ipermutation b) const
|
||||
{
|
||||
int I,J;
|
||||
ipermutation ret = ipermutation(this->length);
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
J = this->perm[I];
|
||||
ret[I] = b[J];
|
||||
}
|
||||
ret.recalc_from_perm();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//invert permutation
|
||||
ipermutation ipermutation::inverse() const
|
||||
{
|
||||
int I,J;
|
||||
ipermutation ret = ipermutation(this->length);
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
J = this->perm[I];
|
||||
ret[J] = I;
|
||||
}
|
||||
|
||||
ret.recalc_from_perm();
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//returns first and last permutations of a given lengthension
|
||||
ipermutation ipermutation::first(int _nlength)
|
||||
{
|
||||
ipermutation ret = ipermutation(0,_nlength);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ipermutation ipermutation::last(int _nlength)
|
||||
{
|
||||
int f = factorial(_nlength);
|
||||
ipermutation ret = ipermutation(f-1,_nlength);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ipermutation::levi_civita() const
|
||||
{
|
||||
int ret = 0;
|
||||
if(valid())
|
||||
{
|
||||
ret = 2*(!(index%2))-1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void test_ipermutation2()
|
||||
{
|
||||
ipermutation a,b,c;
|
||||
int q1[] = {2,0,1,3};
|
||||
int q2[] = {3,0,2,1};
|
||||
|
||||
a = ipermutation(q1,4);
|
||||
b = ipermutation({3,0,2,1});
|
||||
c = a*b;
|
||||
a.print(); printf("\n");
|
||||
b.print(); printf("\n");
|
||||
c.print(); printf("\n");
|
||||
c = b*a;
|
||||
c.print(); printf("\n");
|
||||
|
||||
b = {3,0,2,1};
|
||||
b = a.inverse();
|
||||
c = b*a;
|
||||
|
||||
a.print(); printf("\n");
|
||||
b.print(); printf("\n");
|
||||
c.print(); printf("\n");
|
||||
c = a*b;
|
||||
c.print(); printf("\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}; //end namespace perm
|
||||
}; //end namespace ams
|
Loading…
Reference in New Issue