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