Pete Shadbolt 10 лет назад
Родитель
Сommit
3aff1903d6
6 измененных файлов: 13 добавлений и 78 удалений
  1. +1
    -0
      README.md
  2. +1
    -1
      lib/__init__.py
  3. +5
    -29
      run-tests.py
  4. +1
    -1
      run-tests.sh
  5. +1
    -1
      setup.py
  6. +4
    -46
      src/permanent.c

+ 1
- 0
README.md Просмотреть файл

@@ -1,3 +1,4 @@
# Fast functions for LOQC
- Permanent (hardcoded up to 4x4 and Ryser)
- Parallel permanent
- No Cython dependency

+ 1
- 1
lib/__init__.py Просмотреть файл

@@ -1 +1 @@
from permanent import permanent

+ 5
- 29
run-tests.py Просмотреть файл

@@ -4,32 +4,8 @@ import multiprocessing as mp
import numpy as np
import lib


def test_fn(perm_fn, name, dimension=6, steps=1000, dt=1e-3, bodies=101, threads=1):
# Test the speed of the evolution function.
sreal=np.random.uniform(0,1,(dimension, dimension))
scomp=np.random.uniform(0,1,(dimension, dimension))
submatrix=sreal+1j*scomp

t0 = time.time()
for i in range(steps):
p=perm_fn(submatrix)
t1 = time.time()

print "{0} ({1}): {2} steps/sec".format(name, threads, int(steps / (t1 - t0)))

if __name__ == "__main__":
d=4
steps=1000

# Test on one core
test_fn(lib.perm_python, "1 core, C", steps=steps, threads=1)

# Test on one core
test_fn(lib.perm_c, "1 core, C", steps=steps, threads=1)
# Test on four cores
test_fn(lib.perm_c, "All cores, C", steps=steps/threads, threads=threads)


dimension=8
real=np.random.uniform(0,1,(dimension, dimension))
imag=np.random.uniform(0,1,(dimension, dimension))
submatrix=real+1j*imag
print "OUTPUT: ", lib.permanent(submatrix)

+ 1
- 1
run-tests.sh Просмотреть файл

@@ -1,5 +1,5 @@
#!/bin/bash

rm lib/*.so
#rm lib/*.so
python ./setup.py build_ext --inplace &&
python ./run-tests.py

+ 1
- 1
setup.py Просмотреть файл

@@ -11,7 +11,7 @@ setup(name = "loqcmath",
url = "https://www.peteshadbolt.co.uk",
ext_modules = [
Extension(
'perm_c', ['src/perm_c'],
'permanent', ['src/permanent.c'],
extra_compile_args=["-Ofast", "-march=native"]),
],


+ 4
- 46
src/permanent.c Просмотреть файл

@@ -41,57 +41,14 @@ PyMODINIT_FUNC initpermanent(void) {
(x1) * PyArray_STRIDES(py_F)[1])))
#define F_shape(i) (py_F->dimensions[(i)])


/*****************************************************************************
* compute_F *
*****************************************************************************/
static inline void compute_F(npy_int64 N,
PyArrayObject *py_m,
PyArrayObject *py_r,
PyArrayObject *py_F) {
npy_int64 i, j;
npy_float64 sx, sy, Fx, Fy, s3, tmp;
// Set all forces to zero.
for(i = 0; i < N; ++i) {
F(i, 0) = F(i, 1) = 0;
}
// Compute forces between pairs of bodies.
for(i = 0; i < N; ++i) {
for(j = i + 1; j < N; ++j) {
sx = r(j, 0) - r(i, 0);
sy = r(j, 1) - r(i, 1);

s3 = sqrt(sx*sx + sy*sy);
s3 *= s3 * s3;

tmp = m(i) * m(j) / s3;
Fx = tmp * sx;
Fy = tmp * sy;

F(i, 0) += Fx;
F(i, 1) += Fy;

F(j, 0) -= Fx;
F(j, 1) -= Fy;
}
}
}

static PyObject *permanent(PyObject *self, PyObject *args) {
// Declare variables.
npy_int64 d, i, j;
npy_float64 output;
Py_complex sum;
PyArrayObject *submatrix;

// Parse variables.
if (!PyArg_ParseTuple(args, "ldllO!O!O!O!",
&threads,
&dt,
&steps,
&N,
&PyArray_Type, &submatrix)) {
if (!PyArg_ParseTuple(args, "O!", &PyArray_Type, &submatrix)) {
return NULL;
}

@@ -102,5 +59,6 @@ static PyObject *permanent(PyObject *self, PyObject *args) {
}
}

Py_RETURN_NONE;
PyObject *output=PyComplex_FromCComplex(sum);
return output;
}

Загрузка…
Отмена
Сохранить