|
@@ -12,7 +12,12 @@ |
|
|
// Complex numbers |
|
|
// Complex numbers |
|
|
static const npy_complex128 complex_one = {.real=1, .imag=0}; |
|
|
static const npy_complex128 complex_one = {.real=1, .imag=0}; |
|
|
static const npy_complex128 complex_zero = {.real=0, .imag=0}; |
|
|
static const npy_complex128 complex_zero = {.real=0, .imag=0}; |
|
|
static void complex_inc(npy_complex128 a, npy_complex128 b) { a.real+=b.real; a.imag+=b.imag;} |
|
|
|
|
|
|
|
|
static npy_complex128 complex_add(npy_complex128 a, npy_complex128 b) { |
|
|
|
|
|
npy_complex128 x; |
|
|
|
|
|
x.real = a.real+b.real; |
|
|
|
|
|
x.imag = a.imag+b.imag; |
|
|
|
|
|
return x; |
|
|
|
|
|
} |
|
|
static npy_complex128 complex_prod(npy_complex128 a, npy_complex128 b) { |
|
|
static npy_complex128 complex_prod(npy_complex128 a, npy_complex128 b) { |
|
|
npy_complex128 x; |
|
|
npy_complex128 x; |
|
|
x.real = a.real*b.real+a.imag*b.imag; |
|
|
x.real = a.real*b.real+a.imag*b.imag; |
|
@@ -31,6 +36,7 @@ PyMODINIT_FUNC initpermanent(void) { // Module initia |
|
|
import_array(); |
|
|
import_array(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Ryser's algorithm |
|
|
// Ryser's algorithm |
|
|
static npy_complex128 perm_ryser(PyArrayObject *submatrix) { |
|
|
static npy_complex128 perm_ryser(PyArrayObject *submatrix) { |
|
|
int n = (int) PyArray_DIM(submatrix, 0); |
|
|
int n = (int) PyArray_DIM(submatrix, 0); |
|
@@ -39,27 +45,23 @@ static npy_complex128 perm_ryser(PyArrayObject *submatrix) { |
|
|
npy_complex128 perm = complex_zero; |
|
|
npy_complex128 perm = complex_zero; |
|
|
npy_complex128 sum = complex_zero; |
|
|
npy_complex128 sum = complex_zero; |
|
|
int exp = 1 << n; |
|
|
int exp = 1 << n; |
|
|
printf("2^%d = %d\n", n, exp); |
|
|
|
|
|
|
|
|
|
|
|
// Iterate over exponentially many index strings |
|
|
// Iterate over exponentially many index strings |
|
|
for (i=0; i<exp; ++i) { |
|
|
for (i=0; i<exp; ++i) { |
|
|
prod = complex_one; |
|
|
prod = complex_one; |
|
|
printf("prod %.3f %.3f \n", prod.real, prod.imag); |
|
|
|
|
|
for (y=0; y<n; ++y) { // Rows |
|
|
for (y=0; y<n; ++y) { // Rows |
|
|
sum = complex_zero; |
|
|
sum = complex_zero; |
|
|
for (z=0; z<n; ++z) { // Columns |
|
|
for (z=0; z<n; ++z) { // Columns |
|
|
printf("element %.3f %.3f \n", SM(z,y).real, SM(z,y).imag); |
|
|
|
|
|
// Below is a suspicious line |
|
|
|
|
|
if ((i & (1 << z)) > 0) { complex_inc(sum, SM(z,y)); } |
|
|
|
|
|
printf("sum %.3f %.3f \n", sum.real, sum.imag); |
|
|
|
|
|
|
|
|
if ((i & (1 << z)) > 0) { |
|
|
|
|
|
sum = complex_add(sum, SM(z,y)); |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
prod = complex_prod(prod, sum); |
|
|
prod = complex_prod(prod, sum); |
|
|
} |
|
|
} |
|
|
printf("prod %.3f %.3f \n", prod.real, prod.imag); |
|
|
|
|
|
if (i%2 == 0) {prod.real*=-1; prod.imag*=-1;} |
|
|
|
|
|
complex_inc(perm, prod); |
|
|
|
|
|
|
|
|
/*if (i%2 == 0) {prod.real*=-1; prod.imag*=-1;}*/ |
|
|
|
|
|
perm = complex_add(perm, prod); |
|
|
} |
|
|
} |
|
|
if (i%2 == 0) {perm.real*=-1; perm.imag*=-1;} |
|
|
|
|
|
|
|
|
/*if (i%2 == 0) {perm.real*=-1; perm.imag*=-1;}*/ |
|
|
return perm; |
|
|
return perm; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|