diff --git a/amscppperm1.code-workspace b/amscppperm1.code-workspace index 057f439..911b10b 100644 --- a/amscppperm1.code-workspace +++ b/amscppperm1.code-workspace @@ -3,14 +3,8 @@ { "path": "." }, - { - "path": "../../sourceprojs23/camsimglib3" - }, { "path": "../../sourceprojs23/amsmathutil2" - }, - { - "path": "../../sourceprojs23/amscppfilesys3" } ] -} \ No newline at end of file +} diff --git a/build/__pycache__/amsbuildlib4.cpython-39.pyc b/build/__pycache__/amsbuildlib4.cpython-39.pyc index 4620db4..04d72b0 100644 Binary files a/build/__pycache__/amsbuildlib4.cpython-39.pyc and b/build/__pycache__/amsbuildlib4.cpython-39.pyc differ diff --git a/build_linux64/libamscppperm1.linux64.a b/build_linux64/libamscppperm1.linux64.a index 1c16a9d..8a75a84 100644 Binary files a/build_linux64/libamscppperm1.linux64.a and b/build_linux64/libamscppperm1.linux64.a differ diff --git a/build_linux64/objstore/permutation.o b/build_linux64/objstore/permutation.o index 83ba333..34f5999 100644 Binary files a/build_linux64/objstore/permutation.o and b/build_linux64/objstore/permutation.o differ diff --git a/build_linux64/objstore/permutation_basic.o b/build_linux64/objstore/permutation_basic.o index 5828a9e..3f09deb 100644 Binary files a/build_linux64/objstore/permutation_basic.o and b/build_linux64/objstore/permutation_basic.o differ diff --git a/build_linux64/tests b/build_linux64/tests index 8f902fd..e2b682a 100644 Binary files a/build_linux64/tests and b/build_linux64/tests differ diff --git a/build_mingw64/libamscppperm1.mingw64.a b/build_mingw64/libamscppperm1.mingw64.a new file mode 100644 index 0000000..5b69569 Binary files /dev/null and b/build_mingw64/libamscppperm1.mingw64.a differ diff --git a/build_mingw64/objstore/amscppperm1.o b/build_mingw64/objstore/amscppperm1.o new file mode 100644 index 0000000..af9e11d Binary files /dev/null and b/build_mingw64/objstore/amscppperm1.o differ diff --git a/build_mingw64/objstore/permutation.o b/build_mingw64/objstore/permutation.o new file mode 100644 index 0000000..6e10a10 Binary files /dev/null and b/build_mingw64/objstore/permutation.o differ diff --git a/build_mingw64/objstore/permutation_basic.o b/build_mingw64/objstore/permutation_basic.o new file mode 100644 index 0000000..a00173a Binary files /dev/null and b/build_mingw64/objstore/permutation_basic.o differ diff --git a/build_mingw64/tests.exe b/build_mingw64/tests.exe new file mode 100644 index 0000000..1fc80cf Binary files /dev/null and b/build_mingw64/tests.exe differ diff --git a/build_msvc64/libamscppperm1.msvc64.lib b/build_msvc64/libamscppperm1.msvc64.lib new file mode 100644 index 0000000..c6e3e00 Binary files /dev/null and b/build_msvc64/libamscppperm1.msvc64.lib differ diff --git a/build_msvc64/objstore/amscppperm1.obj b/build_msvc64/objstore/amscppperm1.obj new file mode 100644 index 0000000..4d3ff0d Binary files /dev/null and b/build_msvc64/objstore/amscppperm1.obj differ diff --git a/build_msvc64/objstore/permutation.obj b/build_msvc64/objstore/permutation.obj new file mode 100644 index 0000000..2e24606 Binary files /dev/null and b/build_msvc64/objstore/permutation.obj differ diff --git a/build_msvc64/objstore/permutation_basic.obj b/build_msvc64/objstore/permutation_basic.obj new file mode 100644 index 0000000..1ebb30d Binary files /dev/null and b/build_msvc64/objstore/permutation_basic.obj differ diff --git a/build_msvc64/tests.exe b/build_msvc64/tests.exe new file mode 100644 index 0000000..f442b88 Binary files /dev/null and b/build_msvc64/tests.exe differ diff --git a/include/amscppperm1/amscppperm1.hpp b/include/amscppperm1/amscppperm1.hpp index eff8a01..0015203 100644 --- a/include/amscppperm1/amscppperm1.hpp +++ b/include/amscppperm1/amscppperm1.hpp @@ -4,6 +4,61 @@ #include #include #include +#include + +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); +//Iteratable Permutation Class +//Provides an object for iterating over permutations of low dimension +//These can be stepped along +class ipermutation +{ +public: + 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); -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); + ipermutation operator=(const ipermutation &other); + int& operator[](const int ind); + const int& operator[](const int ind) const; -bool perm_valid(int *perm, int ndim); + bool valid() const; + bool operator==(const ipermutation other) const; -bool mindex_valid(int *mindex, int ndim); + //pre-increment operator + ipermutation& operator++(); + ipermutation& operator--(); -void index_to_perm(int index, int *perm, int ndim); -int perm_to_index(int *perm, int ndim); + //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; -//Permutation class + void print(int style=0); + +}; + +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 dim; + public: + int length; int *data; - - permutation(); - permutation(int _dim); - ~permutation(); + + }; + }; //end namespace perm }; //end namespace ams diff --git a/src/amscppperm1/permutation.cpp b/src/amscppperm1/permutation.cpp index f23d40d..5970497 100644 --- a/src/amscppperm1/permutation.cpp +++ b/src/amscppperm1/permutation.cpp @@ -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; + } + + 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;Iresize(other.length); + if(res==perm_success) + { + for(I=0;Iperm[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;Iperm[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=0 && index+1=0 && index-1operator++(); + 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;Iprint(); 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 \ No newline at end of file diff --git a/src/amscppperm1/permutation_basic.cpp b/src/amscppperm1/permutation_basic.cpp index e18aa3a..ad04a48 100644 --- a/src/amscppperm1/permutation_basic.cpp +++ b/src/amscppperm1/permutation_basic.cpp @@ -1,16 +1,14 @@ #include -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;I12) + { + 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=0 && index=(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=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=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