Source code for geometry.manifolds.torus01

from contracts import contract
import numpy as np

from .differentiable_manifold import DifferentiableManifold
from .differentiable_manifold import RandomManifold

__all__ = ['TorusW', 'TorusW', 'Ts', 'Ts1', 'Ts2', 'Ts3']


[docs]class TorusW(RandomManifold): """ This is a torus whose coordinates wrap around in [0, W). All points in R^n belong to the torus. """ @contract(widths='seq[N](>0)', normalize_bias='None|seq[N](number)') def __init__(self, widths, normalize_bias=None): """ :param bias: Only relevant for normalize(). If None, the normalization will be in [0,W[0]], [0,W[1]], etc. If given a bias, the normalization will be in [b[0],W[0]+b[0]], etc. """ self.widths = np.array(widths, dtype='float') self.n = self.widths.size if normalize_bias is None: normalize_bias = np.zeros(self.n) self.normalize_bias = normalize_bias DifferentiableManifold.__init__(self, dimension=self.n)
[docs] @contract(a='array[N]') def belongs(self, a): pass
[docs] @contract(a='belongs', b='belongs', returns='>=0') # returns='>=0,<0.8') def distance(self, a, b): _, vel = self.logmap(a, b) return np.linalg.norm(vel)
[docs] def logmap(self, base, p): a1 = self.normalize(base) b1 = self.normalize(p) # printm('a1', a1) # printm('b1', b1) vel = b1 - a1 # between -self.widths[i] and +self.widths[i] # if any component v is |v| > 0.5, then we can reach the same # point in the other direction more efficiently # by using v' = 1-v # eg: a=0.8, b=0 # vel = -0.8 # vel' = vel + 1 # eg: a=0, b=0.8 # vel = 0.8 # vel' = vel - 1 # eg: a=0, b=0.75 # vel = 0.75 # vel' = vel - 1 = -.25 for i in range(self.n): wi = self.widths[i] if vel[i] > +wi / 2.0: vel[i] = vel[i] - wi elif vel[i] < -wi / 2.0: vel[i] = vel[i] + wi return base, vel
[docs] @contract(bv='belongs_ts', returns='belongs') def expmap(self, bv): a, vel = bv # b = self.normalize(a + vel) b = a + vel return b
[docs] @contract(bv='tuple(belongs, *)') def project_ts(self, bv): return bv # XXX: more checks
[docs] @contract(returns='belongs') def sample_uniform(self): return (np.random.rand(self.n) - 0.5) * 10 * self.widths
[docs] @contract(returns='belongs_ts') def sample_velocity(self, a): # @UnusedVariable vel = np.random.randn(self.n) vel = vel / np.linalg.norm(vel) # XXX return vel
[docs] def normalize(self, a): q = (a - self.normalize_bias) / self.widths y = q - np.floor(q) return y * self.widths + self.normalize_bias
[docs] def friendly(self, a): return 'point(%s)' % a
[docs] @contract(returns='list(belongs)') def interesting_points(self): interesting = [] interesting.append(np.zeros(self.n)) for _ in range(2): interesting.append(self.sample_uniform()) return interesting
def __repr__(self): return 'Tn%s' % self.n
Ts1 = TorusW([2], [-1]) Ts2 = TorusW([2, 2], [-1, -1]) Ts3 = TorusW([2, 2, 2], [-1, -1, -1]) Ts = {1: Ts1, 2: Ts2, 3: Ts1}