|
| 1 | +"""Circle process.""" |
| 2 | + |
1 | 3 | import tensorflow as tf
|
2 | 4 | import tensorflow_probability as tfp
|
3 | 5 | import numpy as np
|
| 6 | + |
4 | 7 | class Circle(tfp.distributions.Distribution):
|
5 |
| - """The "circle": [cos x, sin x] where x is uniform over [0,2pi]""" |
6 |
| - def __init__(self,width=0.,dtype=tf.float32,validate_args=False,allow_nan_stats=True,name='circle'): |
7 |
| - """ |
8 |
| - Args: |
9 |
| - width: Float in [0,1]. Allows for realizations to be uniformly distributed in a band between radius 1-width and 1+width. |
| 8 | + """The "circle": [cos x, sin x] where x is uniform over [0,2pi]""" |
| 9 | + def __init__(self,width=0.,dtype=tf.float32,validate_args=False, |
| 10 | + allow_nan_stats=True,name='circle'): |
| 11 | + """ |
| 12 | + Args: |
| 13 | + width: Float in [0,1]. Allows for realizations to be uniformly |
| 14 | + distributed in a band between radius 1-width and 1+width. |
10 | 15 | dtype: Data type of returned realization. Defaults to tf.float32.
|
11 | 16 | validate_args: required by tensoflow Distribution class but unused.
|
12 | 17 | allow_nan_stats: required by tensorflow Distribution class but unused.
|
13 | 18 | name: String. Name of the created object.
|
14 |
| - """ |
15 |
| - parameters = dict(locals()) |
16 |
| - with tf.name_scope(name) as name: |
17 |
| - self._width=width |
18 |
| - super().__init__(dtype=dtype, |
| 19 | + """ |
| 20 | + parameters = dict(locals()) |
| 21 | + with tf.name_scope(name) as name: |
| 22 | + self._width=width |
| 23 | + super().__init__(dtype=dtype, |
19 | 24 | reparameterization_type=tfp.distributions.NOT_REPARAMETERIZED,
|
20 | 25 | validate_args = validate_args,
|
21 | 26 | allow_nan_stats = allow_nan_stats,
|
22 | 27 | parameters = parameters,
|
23 | 28 | name=name)
|
24 |
| - @property |
25 |
| - def width(self): |
26 |
| - return self._width |
| 29 | + @property |
| 30 | + def width(self): |
| 31 | + return self._width |
27 | 32 |
|
28 |
| - def _batch_shape_tensor(self): |
29 |
| - return tf.constant([],dtype=tf.int32) |
30 |
| - def _batch_shape(self): |
31 |
| - return tf.TensorShape([]) |
32 |
| - def _event_shape(self): |
33 |
| - smp = tf.linspace(0.,1.,2) |
34 |
| - return smp.shape |
35 |
| - def _event_shape_tensor(self): |
36 |
| - smp = tf.linspace(0.,1.,2) |
37 |
| - return tf.shape(smp) |
38 |
| - def _sample_n(self,n,seed=None): |
39 |
| - angles = tf.random.uniform((1,n),minval = 0, maxval = 2*tf.constant(np.pi),seed=seed,dtype=self.dtype) |
40 |
| - sample = tf.convert_to_tensor([tf.math.cos(angles),tf.math.sin(angles)]) |
41 |
| - if self.width>0: |
42 |
| - dev = tf.random.uniform((1,n),minval = -(self.width)/2.0, maxval = (self.width)/2.0, seed=seed, dtype=self.dtype) |
43 |
| - sample = sample + dev*sample |
44 |
| - sample = tf.transpose(sample,[2,1,0]) |
45 |
| - sample = tf.reshape(sample,[n,2]) |
46 |
| - return sample |
| 33 | + def _batch_shape_tensor(self): |
| 34 | + return tf.constant([],dtype=tf.int32) |
| 35 | + def _batch_shape(self): |
| 36 | + return tf.TensorShape([]) |
| 37 | + def _event_shape(self): |
| 38 | + smp = tf.linspace(0.,1.,2) |
| 39 | + return smp.shape |
| 40 | + def _event_shape_tensor(self): |
| 41 | + smp = tf.linspace(0.,1.,2) |
| 42 | + return tf.shape(smp) |
| 43 | + def _sample_n(self,n,seed=None): |
| 44 | + angles = tf.random.uniform((1,n),minval = 0,maxval = 2*tf.constant(np.pi) |
| 45 | + ,seed=seed,dtype=self.dtype) |
| 46 | + sample = tf.convert_to_tensor([tf.math.cos(angles),tf.math.sin(angles)]) |
| 47 | + if self.width>0: |
| 48 | + dev = tf.random.uniform((1,n),minval = -(self.width)/2.0, |
| 49 | + maxval = (self.width)/2.0, seed=seed, |
| 50 | + dtype=self.dtype) |
| 51 | + sample = sample + dev*sample |
| 52 | + sample = tf.transpose(sample,[2,1,0]) |
| 53 | + sample = tf.reshape(sample,[n,2]) |
| 54 | + return sample |
47 | 55 |
|
48 |
| - def _prob(self, x): |
49 |
| - new_x = tf.reshape(x,[-1,tf.shape(x)[-1]]) |
50 |
| - flat_norm = tf.norm(new_x,axis=1) |
51 |
| - if self.width>0: |
52 |
| - prob = tf.where((flat_norm >= 1-self.width)&(flat_norm <= 1+self.width), |
53 |
| - 1.0/(2*tf.convert_to_tensor(np.pi)*self.width), |
54 |
| - 0. |
55 |
| - ) |
56 |
| - else: |
57 |
| - prob = tf.where(flat_norm==1, |
58 |
| - 1.0/(2*tf.convert_to_tensor(np.pi)), |
59 |
| - 0. |
60 |
| - ) |
61 |
| - return tf.reshape(prob,tf.shape(x)[:-1]) |
| 56 | + def _prob(self, x): |
| 57 | + new_x = tf.reshape(x,[-1,tf.shape(x)[-1]]) |
| 58 | + flat_norm = tf.norm(new_x,axis=1) |
| 59 | + if self.width>0: |
| 60 | + prob = tf.where((flat_norm >= 1-self.width)&(flat_norm <= 1+self.width), |
| 61 | + 1.0/(2*tf.convert_to_tensor(np.pi)*self.width),0.) |
| 62 | + else: |
| 63 | + prob = tf.where(flat_norm==1,1.0/(2*tf.convert_to_tensor(np.pi)),0.) |
| 64 | + return tf.reshape(prob,tf.shape(x)[:-1]) |
0 commit comments