Skip to content

Commit 96c6cb4

Browse files
committed
Added ramp, sinusoid, circle, stat sawbridge
1 parent aaedec8 commit 96c6cb4

File tree

4 files changed

+278
-0
lines changed

4 files changed

+278
-0
lines changed

models/toy_sources/circle.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import tensorflow as tf
2+
import tensorflow_probability as tfp
3+
import numpy as np
4+
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.
10+
dtype: Data type of returned realization. Defaults to tf.float32.
11+
validate_args: required by tensoflow Distribution class but unused.
12+
allow_nan_stats: required by tensorflow Distribution class but unused.
13+
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+
reparameterization_type=tfp.distributions.NOT_REPARAMETERIZED,
20+
validate_args = validate_args,
21+
allow_nan_stats = allow_nan_stats,
22+
parameters = parameters,
23+
name=name)
24+
@property
25+
def width(self):
26+
return self._width
27+
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
47+
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])

models/toy_sources/ramp.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import tensorflow as tf
2+
import tensorflow_probability as tfp
3+
4+
class Ramp(tfp.distributions.Distribution):
5+
"""The "ramp": Y(t) = (t+V)mod1 - 0.5, where V is uniform over [0,1]. """
6+
def __init__(self,index_points,phase=None,dtype=tf.float32,validate_args=False,allow_nan_stats=True,name='ramp'):
7+
"""
8+
Args:
9+
index_points: 1-D Tensor representing the locations at which to evaluate the process.
10+
phase: Float in [0,1]. Specifies a realization of V.
11+
dtype: Data type of the returned realization. Defaults to tf.flaot32.
12+
validate_args: required by tensorflow Distribution class but not used.
13+
allow_nan_stats: required by tensorflow Distribution class but not used.
14+
name: String. Name of the created object.
15+
"""
16+
parameters = dict(locals())
17+
with tf.name_scope(name) as name:
18+
self._index_points = tf.convert_to_tensor(index_points,dtype_hint= dtype,name='index_points')
19+
self._phase = phase
20+
super().__init__(
21+
dtype=dtype,
22+
reparameterization_type = tfp.distributions.NOT_REPARAMETERIZED,
23+
validate_args = validate_args,
24+
allow_nan_stats = allow_nan_stats,
25+
parameters = parameters,
26+
name=name,)
27+
@property
28+
def index_points(self):
29+
return self._index_points
30+
31+
@property
32+
def phase(self):
33+
return self._phase
34+
35+
def _batch_shape_tensor(self):
36+
return tf.constant([],dtype=tf.int32)
37+
38+
def _batch_shape(self):
39+
return tf.TensorShape([])
40+
41+
def _event_shape(self):
42+
return self.index_points.shape
43+
44+
def _event_shape_tensor(self):
45+
return tf.shape(self.index_points)
46+
47+
def _sample_n(self,n,seed=None):
48+
ind = self.index_points
49+
if self._phase is None:
50+
ind += tf.random.uniform ((n,1),seed=seed,dtype=self.dtype)
51+
ind %= 1
52+
else:
53+
phase = tf.repeat(self._phase,repeats=n,axis=0)
54+
phase = tf.reshape(phase,[n,1])
55+
ind += phase
56+
ind %= 1
57+
return ind - 0.5

models/toy_sources/sinusoid.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import tensorflow as tf
2+
import numpy as np
3+
import tensorflow_probability as tfp
4+
5+
class Sinusoid(tfp.distributions.Distribution):
6+
"""The "sinusoid": P(t) = sin(2pi(t+V)), where V is uniform over [0,1]"""
7+
def __init__(self,index_points,phase=None,dtype=tf.float32,validate_args=False,allow_nan_stats=True,name='ramp'):
8+
"""
9+
Args:
10+
index_points: 1-D `Tensor` representing the locations at which to evaluate
11+
the process. The intent is that all locations are in [0,1], but the
12+
process has a natural extrapolation outside this range so no error is
13+
thrown.
14+
phase: Float in [0,1]. Specifies realization of V.
15+
dtype: Data type of the returned realization at each timestep. Defaults to
16+
tf.float32.
17+
validate_args: required by tensorflow Distribution class but unused.
18+
allow_nan_stats: required by tensorflow Distribution class but unused.
19+
name: String. Name of the created object.
20+
"""
21+
22+
parameters = dict(locals())
23+
with tf.name_scope(name) as name:
24+
self._index_points = tf.convert_to_tensor(index_points,dtype_hint= dtype,name='index_points')
25+
self._phase = phase
26+
super().__init__(
27+
dtype=dtype,
28+
reparameterization_type = tfp.distributions.NOT_REPARAMETERIZED,
29+
validate_args = validate_args,
30+
allow_nan_stats = allow_nan_stats,
31+
parameters = parameters,
32+
name=name,)
33+
@property
34+
def index_points(self):
35+
return self._index_points
36+
37+
@property
38+
def phase(self):
39+
return self._phase
40+
41+
def _batch_shape_tensor(self):
42+
return tf.constant([],dtype=tf.int32)
43+
44+
def _batch_shape(self):
45+
return tf.TensorShape([])
46+
47+
def _event_shape(self):
48+
return self.index_points.shape
49+
50+
def _event_shape_tensor(self):
51+
return tf.shape(self.index_points)
52+
53+
def _sample_n(self,n,seed=None):
54+
ind = self.index_points
55+
if self._phase is None:
56+
ind = tf.sin(2*np.pi*(ind+tf.random.uniform((n,1),seed=seed,dtype=self.dtype)))
57+
else:
58+
phase = tf.repeat(self._phase,repeats=n,axis=0)
59+
phase = tf.reshape(phase,[n,1])
60+
ind = tf.sin(2*np.pi(ind+phase))
61+
return ind

models/toy_sources/stat_sawbridge.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
"""Sawbridge process."""
2+
3+
import tensorflow as tf
4+
import tensorflow_probability as tfp
5+
6+
7+
class Sawbridge(tfp.distributions.Distribution):
8+
"""The "stationary sawbridge": Y(t) = B(t+V mod 1) where B(t) = t - 1(t > Z), where Z,V are independent and uniform over [0,1]."""
9+
10+
def __init__(self, index_points, phase=None, drop=None, stationary=True, order=1,
11+
dtype=tf.float32, validate_args=False, allow_nan_stats=True,
12+
name="sawbridge"):
13+
"""Initializer.
14+
15+
Args:
16+
index_points: 1-D `Tensor` representing the locations at which to evaluate
17+
the process. The intent is that all locations are in [0,1], but the
18+
process has a natural extrapolation outside this range so no error is
19+
thrown.
20+
phase: Float in [0,1]. Specifies realization of V/
21+
drop: Float in [0,1]. Specifies realization of Z.
22+
stationary: Boolean. Whether or not to "scramble" phase.
23+
order: Integer >= 1. The resulting process is a linear combination of
24+
`order` sawbridges.
25+
dtype: Data type of the returned realization at each timestep. Defaults to
26+
tf.float32.
27+
validate_args: required by tensorflow Distribution class but unused.
28+
allow_nan_stats: required by tensorflow Distribution class but unused.
29+
name: String. Name of the created object.
30+
"""
31+
parameters = dict(locals())
32+
with tf.name_scope(name) as name:
33+
self._index_points = tf.convert_to_tensor(
34+
index_points, dtype_hint=dtype, name="index_points")
35+
self._stationary = bool(stationary)
36+
self._order = int(order)
37+
self._phase = phase
38+
self._drop = drop
39+
super().__init__(
40+
dtype=dtype,
41+
reparameterization_type=tfp.distributions.NOT_REPARAMETERIZED,
42+
validate_args=validate_args,
43+
allow_nan_stats=allow_nan_stats,
44+
parameters=parameters,
45+
name=name,
46+
)
47+
48+
@property
49+
def index_points(self):
50+
return self._index_points
51+
52+
@property
53+
def stationary(self):
54+
return self._stationary
55+
56+
@property
57+
def order(self):
58+
return self._order
59+
60+
@property
61+
def phase(self):
62+
return self._phase
63+
64+
@property
65+
def drop(self):
66+
return self._drop
67+
68+
def _batch_shape_tensor(self):
69+
return tf.constant([], dtype=tf.int32)
70+
71+
def _batch_shape(self):
72+
return tf.TensorShape([])
73+
74+
def _event_shape_tensor(self):
75+
return tf.shape(self.index_points)
76+
77+
def _event_shape(self):
78+
return self.index_points.shape
79+
80+
def _sample_n(self, n, seed=None):
81+
ind = self.index_points
82+
if self.drop is None:
83+
uniform = tf.random.uniform((self.order,n),seed=seed,dtype = self.dtype)
84+
else:
85+
uniform = tf.repeat(self.drop,repeats = n*self.order)
86+
uniform = tf.reshape(uniform,[self.order,n])
87+
uniform = tf.expand_dims(uniform,-1)
88+
if self.stationary:
89+
if self.phase is None:
90+
phase = tf.random.uniform((n,1),seed=seed,dtype=self.dtype)
91+
else:
92+
phase = tf.repeat(self.phase,repeats = n,axis=0)
93+
phase = tf.reshape(phase, [n,1])
94+
ind += phase
95+
ind %= 1.
96+
less = tf.less(uniform,ind)
97+
sample = ind - tf.reduce_sum(tf.cast(less, self.dtype), 0)
98+
sample *= self.order ** -.5
99+
return sample

0 commit comments

Comments
 (0)