Skip to content

Commit b230208

Browse files
committed
BUG: fix null-space normalization w/r to round-offs
When finding the smallest non-zero value in a null space row, ignore differences that are within round-off errors. This should prevent self-reference in a position formulas, e.g., `{'x': '-x', 'y': 'x +1', 'z': 'x +1'}`.
1 parent 4108d85 commit b230208

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

src/diffpy/structure/symmetryutilities.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -387,11 +387,19 @@ def _findNullSpace(self):
387387
self.null_space = self.null_space[order[::-1]]
388388
# rationalize by the smallest element larger than cutoff
389389
cutoff = 1.0/32
390-
for i in range(len(self.null_space)):
391-
row = self.null_space[i]
392-
small = numpy.fabs(row[numpy.fabs(row) > cutoff]).min()
393-
signedsmall = row[numpy.fabs(row) == small][0]
394-
self.null_space[i] = self.null_space[i] / signedsmall
390+
for row in self.null_space:
391+
abrow = numpy.abs(row)
392+
sgrow = numpy.sign(row)
393+
# equalize items with round-off-equal absolute value
394+
ii = abrow.argsort()
395+
delta = 1e-8 * abrow[ii[-1]]
396+
for k in ii[1:]:
397+
if abrow[k] - abrow[k - 1] < delta:
398+
abrow[k] = abrow[k - 1]
399+
# find the smallest nonzero absolute element
400+
jnz = numpy.flatnonzero(abrow > cutoff)
401+
idx = jnz[abrow[jnz].argmin()]
402+
row[:] = (sgrow * abrow) / sgrow[idx] / abrow[idx]
395403
return
396404

397405

src/diffpy/structure/tests/testsymmetryutilities.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ def test_positionFormula(self):
246246
return
247247

248248

249-
@unittest.expectedFailure
250249
def test_positionFormula_sg209(self):
251250
"""check positionFormula at [x, 1-x, -x] site or F432 space group.
252251
"""
@@ -255,6 +254,8 @@ def test_positionFormula_sg209(self):
255254
g209e = GeneratorSite(sg209, xyz)
256255
pfm = g209e.positionFormula(xyz)
257256
self.assertEqual('x', pfm['x'])
257+
self.assertEqual('-x+1', pfm['y'].replace(' ', ''))
258+
self.assertEqual('-x+1', pfm['z'].replace(' ', ''))
258259
return
259260

260261

0 commit comments

Comments
 (0)