iterative permutation library update
This commit is contained in:
@ -3,14 +3,8 @@
|
||||
{
|
||||
"path": "."
|
||||
},
|
||||
{
|
||||
"path": "../../sourceprojs23/camsimglib3"
|
||||
},
|
||||
{
|
||||
"path": "../../sourceprojs23/amsmathutil2"
|
||||
},
|
||||
{
|
||||
"path": "../../sourceprojs23/amscppfilesys3"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
build_mingw64/libamscppperm1.mingw64.a
Normal file
BIN
build_mingw64/libamscppperm1.mingw64.a
Normal file
Binary file not shown.
BIN
build_mingw64/objstore/amscppperm1.o
Normal file
BIN
build_mingw64/objstore/amscppperm1.o
Normal file
Binary file not shown.
BIN
build_mingw64/objstore/permutation.o
Normal file
BIN
build_mingw64/objstore/permutation.o
Normal file
Binary file not shown.
BIN
build_mingw64/objstore/permutation_basic.o
Normal file
BIN
build_mingw64/objstore/permutation_basic.o
Normal file
Binary file not shown.
BIN
build_mingw64/tests.exe
Normal file
BIN
build_mingw64/tests.exe
Normal file
Binary file not shown.
BIN
build_msvc64/libamscppperm1.msvc64.lib
Normal file
BIN
build_msvc64/libamscppperm1.msvc64.lib
Normal file
Binary file not shown.
BIN
build_msvc64/objstore/amscppperm1.obj
Normal file
BIN
build_msvc64/objstore/amscppperm1.obj
Normal file
Binary file not shown.
BIN
build_msvc64/objstore/permutation.obj
Normal file
BIN
build_msvc64/objstore/permutation.obj
Normal file
Binary file not shown.
BIN
build_msvc64/objstore/permutation_basic.obj
Normal file
BIN
build_msvc64/objstore/permutation_basic.obj
Normal file
Binary file not shown.
BIN
build_msvc64/tests.exe
Normal file
BIN
build_msvc64/tests.exe
Normal file
Binary file not shown.
@ -4,6 +4,61 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <new>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
////////////////////////////////////////////
|
||||
//Basic operations on preallocated buffers//
|
||||
//for C library export //
|
||||
////////////////////////////////////////////
|
||||
|
||||
static const int amsperm1_success = 0;
|
||||
static const int amsperm1_failure = -1;
|
||||
|
||||
//basic factorial found with integer loop
|
||||
int amsperm1_factorial(int n);
|
||||
|
||||
//Is the multi-index in the appropriate factoriadic range?
|
||||
// position 0 can range from [0 to length)
|
||||
// position 1 can range from [0 to (length-1))
|
||||
//parameters:
|
||||
// int mindex[length] - multi-index input
|
||||
// int length - multi-index length output
|
||||
bool amsperm1_mindex_valid(int *mindex, int length);
|
||||
|
||||
|
||||
bool amsperm1_perm_valid(int *perm, int *wrk, int length);
|
||||
|
||||
//returns a factoriadic multi-index for a given index.
|
||||
//Each factoriadic multi-index corresponds to a permutation according to a simple algorithm
|
||||
// factoriadic indices range from (ex 4 length case) {0,0,0,0} to {3,2,1,0}
|
||||
// parameters:
|
||||
// index - [0 to factorial(length)) index of permutation
|
||||
// mindex - factoriadic multi-index output (size=length)
|
||||
// length - length of the permutation (number of elements to permute)
|
||||
// return value:
|
||||
// 0: success
|
||||
// -1 : privided index was out of the valid range
|
||||
int amsperm1_index_to_mindex(int index, int *mindex, int length);
|
||||
|
||||
int amsperm1_mindex_to_index(int *mindex, int length);
|
||||
|
||||
|
||||
int amsperm1_mindex_to_perm(int *mindex, int *perm, int *wrk, int length);
|
||||
|
||||
|
||||
int amsperm1_perm_to_mindex(int *perm, int *mindex, int *wrk, int length);
|
||||
|
||||
int amsperm1_index_to_perm(int index, int *perm, int *mindex, int *wrk, int length);
|
||||
|
||||
int amsperm1_perm_to_index(int *perm, int *mindex, int *wrk, int length);
|
||||
|
||||
void amsperm1_test_basicperm1();
|
||||
|
||||
}; //end extern C
|
||||
|
||||
|
||||
|
||||
namespace ams
|
||||
@ -11,42 +66,83 @@ namespace ams
|
||||
namespace perm
|
||||
{
|
||||
|
||||
//Basic operations on preallocated buffers
|
||||
//for later C library export
|
||||
|
||||
static const int perm_success = 0;
|
||||
static const int perm_failure = -1;
|
||||
|
||||
int factorial(int n);
|
||||
|
||||
int index_to_mindex(int index, int *mindex, int ndim);
|
||||
|
||||
int mindex_to_index(int *mindex, int ndim);
|
||||
int mindex_to_perm(int *mindex, int *perm, int *wrk, int ndim);
|
||||
int perm_to_mindex(int *perm, int *mindex, int *wrk, int ndim);
|
||||
|
||||
bool perm_valid(int *perm, int ndim);
|
||||
|
||||
bool mindex_valid(int *mindex, int ndim);
|
||||
|
||||
void index_to_perm(int index, int *perm, int ndim);
|
||||
int perm_to_index(int *perm, int ndim);
|
||||
|
||||
|
||||
|
||||
|
||||
//Permutation class
|
||||
class permutation
|
||||
//Iteratable Permutation Class
|
||||
//Provides an object for iterating over permutations of low dimension
|
||||
//These can be stepped along
|
||||
class ipermutation
|
||||
{
|
||||
public:
|
||||
int dim;
|
||||
int *data;
|
||||
int length;
|
||||
int *perm; //permutation
|
||||
|
||||
int index; //do I want these also stored with the permutation variable?
|
||||
int *mind; //factoriadic multi-index
|
||||
int *wrk; //working memory buffer
|
||||
|
||||
ipermutation();
|
||||
ipermutation(const int _length);
|
||||
ipermutation(const int _index, const int _length);
|
||||
ipermutation(const int *parray, const int _length);
|
||||
~ipermutation();
|
||||
|
||||
ipermutation(const ipermutation& other);
|
||||
|
||||
int resize(const int _nlength);
|
||||
|
||||
ipermutation operator=(const ipermutation &other);
|
||||
int& operator[](const int ind);
|
||||
const int& operator[](const int ind) const;
|
||||
|
||||
bool valid() const;
|
||||
bool operator==(const ipermutation other) const;
|
||||
|
||||
//pre-increment operator
|
||||
ipermutation& operator++();
|
||||
ipermutation& operator--();
|
||||
|
||||
//post-increment operators
|
||||
ipermutation operator++(int);
|
||||
ipermutation operator--(int);
|
||||
|
||||
ipermutation operator*(const ipermutation b) const; //compose permutations
|
||||
ipermutation inverse() const; //invert permutation
|
||||
|
||||
//returns first and last permutations of a given lengthension
|
||||
static ipermutation first(int _nlength);
|
||||
static ipermutation last(int _nlength);
|
||||
|
||||
int levi_civita() const;
|
||||
|
||||
void print(int style=0);
|
||||
|
||||
permutation();
|
||||
permutation(int _dim);
|
||||
~permutation();
|
||||
};
|
||||
|
||||
ipermutation ipermutation_first(int _nlength);
|
||||
ipermutation ipermutation_last(int _nlength);
|
||||
int levi_civita(const ipermutation p);
|
||||
|
||||
void test_ipermutation1();
|
||||
|
||||
// non-indexable permutation class
|
||||
// the same permutation logic, but for larger permutation sets
|
||||
// can't index, can't increment or decrement a sequence, but can still
|
||||
// compose, test validity, test levi_civita sign, apply to arrays, etc.
|
||||
class permutation
|
||||
{
|
||||
public:
|
||||
int length;
|
||||
int *data;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
}; //end namespace perm
|
||||
}; //end namespace ams
|
||||
|
||||
|
@ -5,21 +5,445 @@ namespace ams
|
||||
namespace perm
|
||||
{
|
||||
|
||||
permutation::permutation()
|
||||
ipermutation::ipermutation()
|
||||
{
|
||||
dim = 0;
|
||||
data = NULL;
|
||||
length = 0;
|
||||
perm = NULL;
|
||||
index = -1;
|
||||
mind = NULL;
|
||||
wrk = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
permutation::~permutation()
|
||||
ipermutation::~ipermutation()
|
||||
{
|
||||
if(data!=NULL) {delete[] data; data = NULL;}
|
||||
dim = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}; //end namespace perm
|
||||
}; //end namespace ams
|
@ -1,16 +1,14 @@
|
||||
#include <amscppperm1/amscppperm1.hpp>
|
||||
|
||||
namespace ams
|
||||
{
|
||||
namespace perm
|
||||
extern "C"
|
||||
{
|
||||
|
||||
//basic factorial found with integer loop
|
||||
int factorial(int n)
|
||||
int amsperm1_factorial(int n)
|
||||
{
|
||||
int I;
|
||||
int ret = 0;
|
||||
if(n>=0)
|
||||
if(n>=0 && n<=12)
|
||||
{
|
||||
ret = 1;
|
||||
for(I=0;I<n;I++)
|
||||
@ -18,29 +16,33 @@ namespace perm
|
||||
ret = ret*(I+1);
|
||||
}
|
||||
}
|
||||
if(n>12)
|
||||
{
|
||||
ret = -1; //overflow error
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//returns a factoriadic multi-index for a given index.
|
||||
//Each factoriadic multi-index corresponds to a permutation according to a simple algorithm
|
||||
// factoriadic indices range from (ex 4 dim case) {0,0,0,0} to {3,2,1,0}
|
||||
// factoriadic indices range from (ex 4 length case) {0,0,0,0} to {3,2,1,0}
|
||||
// parameters:
|
||||
// index - [0 to factorial(ndim)) index of permutation
|
||||
// mindex - factoriadic multi-index output (size=ndim)
|
||||
// ndim - dimension of the permutation (number of elements to permute)
|
||||
// index - [0 to factorial(length)) index of permutation
|
||||
// mindex - factoriadic multi-index output (size=length)
|
||||
// length - length of the permutation (number of elements to permute)
|
||||
// return value:
|
||||
// 0: success
|
||||
// -1 : privided index was out of the valid range
|
||||
int index_to_mindex(int index, int *mindex, int ndim)
|
||||
int amsperm1_index_to_mindex(int index, int *mindex, int length)
|
||||
{
|
||||
int ret = -1;
|
||||
int ret = amsperm1_failure;
|
||||
int I,J,K;
|
||||
if(index>=0 && index<factorial(ndim))
|
||||
if(index>=0 && index<amsperm1_factorial(length))
|
||||
{
|
||||
ret = 0; //success
|
||||
K = ndim;
|
||||
ret = amsperm1_success; //success
|
||||
K = length;
|
||||
J = index;
|
||||
for(I=0;I<ndim;I++)
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
mindex[I] = J%K;
|
||||
J = (J - mindex[I])/K;
|
||||
@ -49,9 +51,9 @@ namespace perm
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = -1; //error
|
||||
ret = amsperm1_failure; //error
|
||||
//invalid index
|
||||
for(I=0;I<ndim;I++)
|
||||
for(I=0;I<length;I++)
|
||||
mindex[I] = -1;
|
||||
}
|
||||
|
||||
@ -60,15 +62,18 @@ namespace perm
|
||||
}
|
||||
|
||||
//Is the multi-index in the appropriate factoriadic range?
|
||||
// position 0 can range from [0 to ndim)
|
||||
// position 1 can range from [0 to (ndim-1))
|
||||
bool mindex_valid(int *mindex, int ndim)
|
||||
// position 0 can range from [0 to length)
|
||||
// position 1 can range from [0 to (length-1))
|
||||
//parameters:
|
||||
// int mindex[length] - multi-index input
|
||||
// int length - multi-index length output
|
||||
bool amsperm1_mindex_valid(int *mindex, int length)
|
||||
{
|
||||
int I;
|
||||
bool ret = 1;
|
||||
for(I=0;I<ndim;I++)
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
if(mindex[I]<0 || mindex[I]>=(ndim-I))
|
||||
if(mindex[I]<0 || mindex[I]>=(length-I))
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
@ -77,19 +82,19 @@ namespace perm
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mindex_to_index(int *mindex, int ndim)
|
||||
int amsperm1_mindex_to_index(int *mindex, int length)
|
||||
{
|
||||
int ret = -1;
|
||||
int I;
|
||||
int K;
|
||||
if(mindex_valid(mindex,ndim))
|
||||
if(amsperm1_mindex_valid(mindex,length))
|
||||
{
|
||||
K = 1;
|
||||
ret = 0;
|
||||
for(I=0;I<ndim;I++)
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
ret = ret + mindex[I]*K;
|
||||
K = K*(ndim-I);
|
||||
K = K*(length-I);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -101,20 +106,198 @@ namespace perm
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mindex_to_perm(int *mindex, int *perm, int *wrk, int ndim)
|
||||
//multi-index to permutation
|
||||
//parameters:
|
||||
// mindex[length] - input factoriadic multi-index
|
||||
// perm[length] - output permutation
|
||||
// wrk[length] - working memory buffer
|
||||
// length - length of permutation
|
||||
//return values:
|
||||
// amsperm1_success - result should be a valid permutation
|
||||
// amsperm1_failure - invalid multi-index supplied
|
||||
int amsperm1_mindex_to_perm(int *mindex, int *perm, int *wrk, int length)
|
||||
{
|
||||
int ret = -1;
|
||||
int I,J,K,L;
|
||||
int ret = amsperm1_failure;
|
||||
if(!amsperm1_mindex_valid(mindex,length))
|
||||
{
|
||||
ret = amsperm1_failure;
|
||||
for(I=0;I<length;I++) perm[I] = -1;
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(I=0;I<length;I++) wrk[I] = 0;
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
J = mindex[I];
|
||||
L = 0;
|
||||
for(K=0;K<length;K++)
|
||||
{
|
||||
if(wrk[K]==0)
|
||||
{
|
||||
L = L + 1;
|
||||
if(L==(J+1))
|
||||
{
|
||||
perm[I] = K;
|
||||
wrk[K] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = amsperm1_success;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int perm_to_mindex(int *perm, int *mindex, int *wrk, int ndim)
|
||||
//check validity of permutation
|
||||
//parameters:
|
||||
//int perm[length] - input permutation
|
||||
//int wrk[length] - working buffer
|
||||
//int length - permutation array length
|
||||
//return values:
|
||||
// 1 - is a valid permutation
|
||||
// 0 - is not a valid permutation
|
||||
bool amsperm1_perm_valid(int *perm, int *wrk, int length)
|
||||
{
|
||||
int ret = -1;
|
||||
bool ret = 1;
|
||||
int I;
|
||||
for(I=0;I<length;I++) wrk[I] = 0;
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
if(perm[I]<0 || perm[I]>=length)
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
if(wrk[perm[I]]==1)
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
wrk[perm[I]]=1;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amsperm1_perm_to_mindex(int *perm, int *mindex, int *wrk, int length)
|
||||
{
|
||||
int ret = amsperm1_failure;
|
||||
int I,J,K,L;
|
||||
|
||||
if(!amsperm1_perm_valid(perm,wrk,length))
|
||||
{
|
||||
for(I=0;I<length;I++) mindex[I] = -1;
|
||||
ret = amsperm1_failure;
|
||||
return ret;
|
||||
}
|
||||
|
||||
for(I=0;I<length;I++) wrk[I]=0;
|
||||
for(I=0;I<length;I++)
|
||||
{
|
||||
J = perm[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 amsperm1_index_to_perm(int index, int *perm, int *mindex, int *wrk, int length)
|
||||
{
|
||||
int ret = amsperm1_failure;
|
||||
|
||||
}; //end namespace perm
|
||||
}; //end namespace ams
|
||||
if(index<0 || index>=amsperm1_factorial(length))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
amsperm1_index_to_mindex(index,mindex,length);
|
||||
amsperm1_mindex_to_perm(mindex,perm,wrk,length);
|
||||
ret = amsperm1_success;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int amsperm1_perm_to_index(int *perm, int *mindex, int *wrk, int length)
|
||||
{
|
||||
int ret = -1;
|
||||
if(!amsperm1_perm_valid(perm,wrk,length))
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
amsperm1_perm_to_mindex(perm,mindex,wrk,length);
|
||||
ret = amsperm1_mindex_to_index(mindex,length);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void _intl_print_array(int *array, int length)
|
||||
{
|
||||
int I;
|
||||
printf("{");
|
||||
for(I=0;I<length-1;I++)
|
||||
{
|
||||
printf("%d,",array[I]);
|
||||
}
|
||||
printf("%d}",array[length-1]);
|
||||
return;
|
||||
}
|
||||
|
||||
void amsperm1_test_basicperm1()
|
||||
{
|
||||
int I,J;
|
||||
int length = 4;
|
||||
int *perm1 = NULL;
|
||||
int *perm2 = NULL;
|
||||
int *mind1 = NULL;
|
||||
int *mind2 = NULL;
|
||||
int *wrk = NULL;
|
||||
|
||||
|
||||
perm1 = new(std::nothrow) int[length];
|
||||
perm2 = new(std::nothrow) int[length];
|
||||
mind1 = new(std::nothrow) int[length];
|
||||
mind2 = new(std::nothrow) int[length];
|
||||
wrk = new(std::nothrow) int[length];
|
||||
|
||||
printf("Tests of basic permutation and multi-index operations..\n");
|
||||
for(I=-1;I<amsperm1_factorial(length)+1;I++)
|
||||
{
|
||||
amsperm1_index_to_mindex(I,mind1,length);
|
||||
J = amsperm1_mindex_to_index(mind1,length);
|
||||
amsperm1_mindex_to_perm(mind1,perm1,wrk,length);
|
||||
amsperm1_perm_to_mindex(perm1,mind2,wrk,length);
|
||||
printf("%d\t",I);
|
||||
_intl_print_array(mind1,length); printf("\t");
|
||||
_intl_print_array(perm1,length); printf("\t");
|
||||
_intl_print_array(mind2,length); printf("\t");
|
||||
printf("%d\n",J);
|
||||
}
|
||||
|
||||
|
||||
delete[] perm1;
|
||||
delete[] perm2;
|
||||
delete[] mind1;
|
||||
delete[] mind2;
|
||||
delete[] wrk;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
}; //end extern "C"
|
@ -3,7 +3,8 @@
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
printf("ams c++ project template tests.\n");
|
||||
|
||||
printf("ams c++ permutation library tests.\n");
|
||||
//amsperm1_test_basicperm1();
|
||||
//ams::perm::test_ipermutation1();
|
||||
return ret;
|
||||
}
|
Reference in New Issue
Block a user