Skip to content

Commit

Permalink
Port contact_matrix_no_pbc to cython
Browse files Browse the repository at this point in the history
Simple Cython implementation. Instead of the other functions in
distances.pyx I have used pure cython for clarity. The loop is converted
to pure C except for saving the sparse matrix element.
  • Loading branch information
kain88-de committed Jul 30, 2015
1 parent bd5f775 commit 841be3d
Show file tree
Hide file tree
Showing 3 changed files with 16,194 additions and 1,193 deletions.
46 changes: 1 addition & 45 deletions package/MDAnalysis/analysis/distances.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
from scipy.weave import converters

from MDAnalysis.lib.distances import distance_array, self_distance_array
from MDAnalysis.lib._distances import contact_matrix_no_pbc
from MDAnalysis.lib.KDTree.NeighborSearch import AtomNeighborSearch

import logging
Expand Down Expand Up @@ -150,51 +151,6 @@ def contact_matrix_pbc(coord, sparse_contacts, box, cutoff, progress_meter_freq,
type_converters=converters.blitz)


def contact_matrix_no_pbc(coord, sparse_contacts, cutoff, progress_meter_freq, quiet):
"""Contact matrix calculation without periodic boundary conditions.
You don't have to call this function explicitly; just set *box* =
``None`` when calling :func:`contact_matrix`, which will then call
this function.
This function uses `python.weave`_.
.. _`python.weave`: http://github.com/scipy/scipy/tree/master/scipy/weave/examples
"""
_quiet = 1 if quiet else 0 # weave does not like Python True/False and does not convert to bool

c_code = """
#include <math.h>
int rows = Ncoord[0];
float cutoff2 = powf(cutoff, 2.);
py::tuple args(2);
bool b = 1;
args[1] = b;
for (int i=0; i < rows; i++) {
// Print progress meter
if (! _quiet && (i % progress_meter_freq == 0)) {
printf("%.1f percent done \\n", (100.0 * i / rows));
}
for (int j=0; j < rows; j++) {
float x = coord(i,0) - coord(j,0);
float y = coord(i,1) - coord(j,1);
float z = coord(i,2) - coord(j,2);
float dist = powf(x, 2.) + powf(y, 2.) + powf(z, 2.);
if (dist != 0.0 && dist < cutoff2) {
py::tuple idx(2);
idx[0] = i;
idx[1] = j;
args[0] = idx;
sparse_contacts.mcall("__setitem__",args);
}
}
}
"""
weave.inline(c_code, ['coord', 'sparse_contacts', 'cutoff', 'progress_meter_freq', '_quiet'],
type_converters=converters.blitz)


def dist(A, B, offset=0):
"""Return distance between atoms in two atom groups.
Expand Down
Loading

0 comments on commit 841be3d

Please sign in to comment.