Skip to content

Commit

Permalink
Implement a more robust rounding algorithm (no magic number)
Browse files Browse the repository at this point in the history
I have checked this on large designs and found this to work more robustly.
  • Loading branch information
basnijholt committed Jun 27, 2022
1 parent 6bb30ef commit e8be519
Showing 1 changed file with 8 additions and 7 deletions.
15 changes: 8 additions & 7 deletions phidl/device_layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@


import hashlib
import math
import warnings
from copy import deepcopy as _deepcopy

Expand Down Expand Up @@ -1856,18 +1857,12 @@ def hash_geometry(self, precision=1e-4):
layers = np.array(list(polygons_by_spec.keys()))
sorted_layers = layers[np.lexsort((layers[:, 0], layers[:, 1]))]

# A random offset which fixes common rounding errors intrinsic
# to floating point math. Example: with a precision of 0.1, the
# floating points 7.049999 and 7.050001 round to different values
# (7.0 and 7.1), but offset values (7.220485 and 7.220487) don't
magic_offset = 0.17048614

final_hash = hashlib.sha1()
for layer in sorted_layers:
layer_hash = hashlib.sha1(layer.astype(np.int64)).digest()
polygons = polygons_by_spec[tuple(layer)]
polygons = [
np.ascontiguousarray((p / precision) + magic_offset, dtype=np.int64)
_rnd(p, precision)
for p in polygons
]
polygon_hashes = np.sort([hashlib.sha1(p).digest() for p in polygons])
Expand All @@ -1878,6 +1873,12 @@ def hash_geometry(self, precision=1e-4):
return final_hash.hexdigest()


def _rnd(arr, precision=1e-4):
arr = np.ascontiguousarray(arr)
ndigits = round(-math.log10(precision))
return np.ascontiguousarray(arr.round(ndigits) / precision, dtype=np.int64)


class DeviceReference(gdspy.CellReference, _GeometryHelper):
"""Simple reference to an existing Device.
Expand Down

0 comments on commit e8be519

Please sign in to comment.