updates
This commit is contained in:
Binary file not shown.
Binary file not shown.
BIN
build_linux64/objstore/ipermutation.o
Normal file
BIN
build_linux64/objstore/ipermutation.o
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -5,6 +5,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <new>
|
#include <new>
|
||||||
|
#include <initializer_list>
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@ -89,6 +90,7 @@ public:
|
|||||||
ipermutation(const int _length);
|
ipermutation(const int _length);
|
||||||
ipermutation(const int _index, const int _length);
|
ipermutation(const int _index, const int _length);
|
||||||
ipermutation(const int *parray, const int _length);
|
ipermutation(const int *parray, const int _length);
|
||||||
|
ipermutation(std::initializer_list<int> q);
|
||||||
~ipermutation();
|
~ipermutation();
|
||||||
|
|
||||||
ipermutation(const ipermutation& other);
|
ipermutation(const ipermutation& other);
|
||||||
@ -98,6 +100,8 @@ public:
|
|||||||
ipermutation operator=(const ipermutation &other);
|
ipermutation operator=(const ipermutation &other);
|
||||||
int& operator[](const int ind);
|
int& operator[](const int ind);
|
||||||
const int& operator[](const int ind) const;
|
const int& operator[](const int ind) const;
|
||||||
|
int& at(const int ind);
|
||||||
|
const int& at(const int ind) const;
|
||||||
|
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
bool operator==(const ipermutation other) const;
|
bool operator==(const ipermutation other) const;
|
||||||
@ -121,6 +125,8 @@ public:
|
|||||||
|
|
||||||
void print(int style=0);
|
void print(int style=0);
|
||||||
|
|
||||||
|
void recalc_from_perm();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ipermutation ipermutation_first(int _nlength);
|
ipermutation ipermutation_first(int _nlength);
|
||||||
@ -128,18 +134,54 @@ ipermutation ipermutation_last(int _nlength);
|
|||||||
int levi_civita(const ipermutation p);
|
int levi_civita(const ipermutation p);
|
||||||
|
|
||||||
void test_ipermutation1();
|
void test_ipermutation1();
|
||||||
|
void test_ipermutation2();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// non-indexable permutation class
|
// non-indexable permutation class
|
||||||
// the same permutation logic, but for larger permutation sets
|
// the same permutation logic, but for larger permutation sets
|
||||||
// can't index, can't increment or decrement a sequence, but can still
|
// can't index, can't increment or decrement a sequence, but can still
|
||||||
// compose, test validity, test levi_civita sign, apply to arrays, etc.
|
// compose, test validity, test levi_civita sign, apply to arrays, etc.
|
||||||
|
//
|
||||||
|
//maybe I *can* increment/decrement by converting to a multi-index (later, possibly not essential)
|
||||||
class permutation
|
class permutation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int length;
|
int length;
|
||||||
int *data;
|
int *data;
|
||||||
|
|
||||||
|
permutation();
|
||||||
|
permutation(const int _length);
|
||||||
|
permutation(const int *parray, const int _length);
|
||||||
|
permutation(std::initializer_list<int> q);
|
||||||
|
~permutation();
|
||||||
|
|
||||||
|
permutation(const permutation& other);
|
||||||
|
|
||||||
|
int resize(const int _nlength);
|
||||||
|
|
||||||
|
permutation operator=(const permutation &other);
|
||||||
|
|
||||||
|
bool valid() const;
|
||||||
|
bool operator==(const permutation &other) const;
|
||||||
|
|
||||||
|
int& operator[](const int ind);
|
||||||
|
const int& operator[](const int ind) const;
|
||||||
|
int& at(const int ind);
|
||||||
|
const int& at(const int ind) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static permutation first(int length);
|
||||||
|
static permutation last(int length);
|
||||||
|
|
||||||
|
permutation operator*(const permutation &other) const; //composition
|
||||||
|
permutation inverse() const;
|
||||||
|
|
||||||
|
int _intl_calculate_mindex(int *mindex, int *wrk);
|
||||||
|
int levi_civita();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
541
src/amscppperm1/ipermutation.cpp
Normal file
541
src/amscppperm1/ipermutation.cpp
Normal file
@ -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
|
@ -5,445 +5,356 @@ namespace ams
|
|||||||
namespace perm
|
namespace perm
|
||||||
{
|
{
|
||||||
|
|
||||||
ipermutation::ipermutation()
|
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)
|
||||||
{
|
{
|
||||||
length = 0;
|
res = this->resize(other.length);
|
||||||
perm = NULL;
|
if(res==perm_success)
|
||||||
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);
|
for(I=0;I<length&&I<other.length;I++)
|
||||||
if(res==perm_success)
|
|
||||||
{
|
{
|
||||||
index = _index;
|
this->data[I] = other.data[I];
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ipermutation ipermutation::operator=(const ipermutation &other)
|
permutation::permutation(const int _length)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
int I;
|
||||||
|
length = 0;
|
||||||
|
data = NULL;
|
||||||
|
|
||||||
|
res = this->resize(_length);
|
||||||
|
if(res==perm_success)
|
||||||
{
|
{
|
||||||
int res;
|
for(I=0;I<length;I++)
|
||||||
int I;
|
|
||||||
if(this!=&other)
|
|
||||||
{
|
{
|
||||||
res = this->resize(other.length);
|
this->data[I] = I;
|
||||||
if(res==perm_success)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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++)
|
||||||
{
|
{
|
||||||
for(I=0;I<length;I++)
|
this->data[I] = other.data[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;
|
|
||||||
}
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
int& ipermutation::operator[](const int ind)
|
int permutation::resize(const int _nlength)
|
||||||
|
{
|
||||||
|
int ret = perm_success;
|
||||||
|
int I;
|
||||||
|
|
||||||
|
int *newdata = NULL;
|
||||||
|
|
||||||
|
if(_nlength<=0)
|
||||||
{
|
{
|
||||||
return perm[ind];
|
length = 0;
|
||||||
}
|
if(data!=NULL) {delete[] data; data=NULL;}
|
||||||
|
ret = perm_failure;
|
||||||
const int& ipermutation::operator[](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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ipermutation::operator==(const ipermutation other) const
|
newdata = new(std::nothrow) int[_nlength];
|
||||||
|
if(newdata==NULL)
|
||||||
{
|
{
|
||||||
bool ret = 1;
|
ret = perm_failure;
|
||||||
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipermutation ipermutation_first(int _nlength)
|
for(I=0;I<length && I<_nlength;I++)
|
||||||
{
|
{
|
||||||
ipermutation ret = ipermutation(0,_nlength);
|
newdata[I] = data[I];
|
||||||
return ret;
|
}
|
||||||
|
for(I=length;I<_nlength;I++)
|
||||||
|
{
|
||||||
|
newdata[I] = 0; //will have to fill in for it to be a valid permutation
|
||||||
}
|
}
|
||||||
|
|
||||||
ipermutation ipermutation_last(int _nlength)
|
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)
|
||||||
{
|
{
|
||||||
int f = factorial(_nlength);
|
ret = 0; //wrk buffer allocation failed
|
||||||
ipermutation ret = ipermutation(f-1,_nlength);
|
return ret;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int levi_civita(const ipermutation p)
|
for(I=0;I<length;I++) wrk[I] = 0;
|
||||||
|
|
||||||
|
for(I=0;I<length;I++)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
J = data[I];
|
||||||
bool v = p.valid();
|
if(J<0 || J>=length)
|
||||||
if(v)
|
|
||||||
{
|
{
|
||||||
ret = 2*(!(p.index%2))-1;
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(wrk[J]==1)
|
||||||
|
{
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wrk[J] = 1;
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//pre-increment operator
|
|
||||||
ipermutation& ipermutation::operator++()
|
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)
|
||||||
{
|
{
|
||||||
int I;
|
ret = 0; return ret;
|
||||||
if(valid())
|
}
|
||||||
|
for(I=0;I<length;I++)
|
||||||
|
{
|
||||||
|
if(this->data[I]!=other.data[I])
|
||||||
{
|
{
|
||||||
if(index+1>=0 && index+1<factorial(length))
|
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)
|
||||||
{
|
{
|
||||||
index = index + 1;
|
L = L + 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;
|
wrk[J] = 1;
|
||||||
|
mindex[I] = L-1;
|
||||||
}
|
}
|
||||||
|
ret = amsperm1_success;
|
||||||
|
|
||||||
ipermutation& ipermutation::operator--()
|
return ret;
|
||||||
{
|
}
|
||||||
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
|
int permutation::levi_civita()
|
||||||
ipermutation ipermutation::operator++(int)
|
{
|
||||||
|
int ret = 0;
|
||||||
|
int *mindex = NULL;
|
||||||
|
int *wrk = NULL;
|
||||||
|
|
||||||
|
int Q;
|
||||||
|
|
||||||
|
if(!valid())
|
||||||
{
|
{
|
||||||
ipermutation ret = *this;
|
|
||||||
//++ret;
|
|
||||||
this->operator++();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipermutation ipermutation::operator--(int)
|
if(length<=0)
|
||||||
{
|
{
|
||||||
ipermutation ret = *this;
|
|
||||||
//--ret;
|
|
||||||
this->operator--();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ipermutation::print(int style)
|
mindex = new(std::nothrow) int[length];
|
||||||
|
wrk = new(std::nothrow) int[length];
|
||||||
|
|
||||||
|
this->_intl_calculate_mindex(mindex,wrk);
|
||||||
|
|
||||||
|
if(length==1)
|
||||||
{
|
{
|
||||||
int I;
|
ret = 0;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
//compose permutations
|
|
||||||
ipermutation ipermutation::operator*(const ipermutation b) const
|
|
||||||
{
|
|
||||||
ipermutation ret = ipermutation(this->length);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//invert permutation
|
|
||||||
ipermutation ipermutation::inverse() const
|
|
||||||
{
|
|
||||||
ipermutation ret = ipermutation(this->length);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
//returns first and last permutations of a given lengthension
|
|
||||||
ipermutation ipermutation::first(int _nlength)
|
|
||||||
{
|
|
||||||
ipermutation ret = ipermutation(0,_nlength);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipermutation ipermutation::last(int _nlength)
|
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++)
|
||||||
{
|
{
|
||||||
int f = factorial(_nlength);
|
ret.data[I] = I;
|
||||||
ipermutation ret = ipermutation(f-1,_nlength);
|
}
|
||||||
return ret;
|
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];
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipermutation::levi_civita() const
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
permutation permutation::inverse() const
|
||||||
|
{
|
||||||
|
int I,J;
|
||||||
|
permutation ret = permutation(this->length);
|
||||||
|
for(I=0;I<length;I++)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
J = this->data[I];
|
||||||
if(valid())
|
ret[J] = I;
|
||||||
{
|
|
||||||
ret = 2*(!(index%2))-1;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
}; //end namespace perm
|
}; //end namespace perm
|
||||||
}; //end namespace ams
|
}; //end namespace ams
|
@ -6,5 +6,6 @@ int main(int argc, char* argv[])
|
|||||||
printf("ams c++ permutation library tests.\n");
|
printf("ams c++ permutation library tests.\n");
|
||||||
//amsperm1_test_basicperm1();
|
//amsperm1_test_basicperm1();
|
||||||
//ams::perm::test_ipermutation1();
|
//ams::perm::test_ipermutation1();
|
||||||
|
ams::perm::test_ipermutation2();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
Reference in New Issue
Block a user