YasiiKB's picture
initial commit
97aa5af verified
""" sinc(t) := sin(t) / t """
import torch
from torch import sin, cos
def sinc1(t):
""" sinc1: t -> sin(t)/t """
e = 0.01
r = torch.zeros_like(t)
a = torch.abs(t)
s = a < e
c = (s == 0)
t2 = t[s] ** 2
r[s] = 1 - t2/6*(1 - t2/20*(1 - t2/42)) # Taylor series O(t^8)
r[c] = sin(t[c]) / t[c]
return r
def sinc1_dt(t):
""" d/dt(sinc1) """
e = 0.01
r = torch.zeros_like(t)
a = torch.abs(t)
s = a < e
c = (s == 0)
t2 = t ** 2
r[s] = -t[s]/3*(1 - t2[s]/10*(1 - t2[s]/28*(1 - t2[s]/54))) # Taylor series O(t^8)
r[c] = cos(t[c])/t[c] - sin(t[c])/t2[c]
return r
def sinc1_dt_rt(t):
""" d/dt(sinc1) / t """
e = 0.01
r = torch.zeros_like(t)
a = torch.abs(t)
s = a < e
c = (s == 0)
t2 = t ** 2
r[s] = -1/3*(1 - t2[s]/10*(1 - t2[s]/28*(1 - t2[s]/54))) # Taylor series O(t^8)
r[c] = (cos(t[c]) / t[c] - sin(t[c]) / t2[c]) / t[c]
return r
def rsinc1(t):
""" rsinc1: t -> t/sinc1(t) """
e = 0.01
r = torch.zeros_like(t)
a = torch.abs(t)
s = a < e
c = (s == 0)
t2 = t[s] ** 2
r[s] = (((31*t2)/42 + 7)*t2/60 + 1)*t2/6 + 1 # Taylor series O(t^8)
r[c] = t[c] / sin(t[c])
return r
def rsinc1_dt(t):
""" d/dt(rsinc1) """
e = 0.01
r = torch.zeros_like(t)
a = torch.abs(t)
s = a < e
c = (s == 0)
t2 = t[s] ** 2
r[s] = ((((127*t2)/30 + 31)*t2/28 + 7)*t2/30 + 1)*t[s]/3 # Taylor series O(t^8)
r[c] = 1/sin(t[c]) - (t[c]*cos(t[c]))/(sin(t[c])*sin(t[c]))
return r
def rsinc1_dt_csc(t):
""" d/dt(rsinc1) / sin(t) """
e = 0.01
r = torch.zeros_like(t)
a = torch.abs(t)
s = a < e
c = (s == 0)
t2 = t[s] ** 2
r[s] = t2*(t2*((4*t2)/675 + 2/63) + 2/15) + 1/3 # Taylor series O(t^8)
r[c] = (1/sin(t[c]) - (t[c]*cos(t[c]))/(sin(t[c])*sin(t[c]))) / sin(t[c])
return r
def sinc2(t):
""" sinc2: t -> (1 - cos(t)) / (t**2) """
e = 0.01
r = torch.zeros_like(t)
a = torch.abs(t)
s = a < e
c = (s == 0)
t2 = t ** 2
r[s] = 1/2*(1-t2[s]/12*(1-t2[s]/30*(1-t2[s]/56))) # Taylor series O(t^8)
r[c] = (1-cos(t[c]))/t2[c]
return r
def sinc2_dt(t):
""" d/dt(sinc2) """
e = 0.01
r = torch.zeros_like(t)
a = torch.abs(t)
s = a < e
c = (s == 0)
t2 = t ** 2
r[s] = -t[s]/12*(1 - t2[s]/5*(1.0/3 - t2[s]/56*(1.0/2 - t2[s]/135))) # Taylor series O(t^8)
r[c] = sin(t[c])/t2[c] - 2*(1-cos(t[c]))/(t2[c]*t[c])
return r
def sinc3(t):
""" sinc3: t -> (t - sin(t)) / (t**3) """
e = 0.01
r = torch.zeros_like(t)
a = torch.abs(t)
s = a < e
c = (s == 0)
t2 = t[s] ** 2
r[s] = 1/6*(1-t2/20*(1-t2/42*(1-t2/72))) # Taylor series O(t^8)
r[c] = (t[c]-sin(t[c]))/(t[c]**3)
return r
def sinc3_dt(t):
""" d/dt(sinc3) """
e = 0.01
r = torch.zeros_like(t)
a = torch.abs(t)
s = a < e
c = (s == 0)
t2 = t[s] ** 2
r[s] = -t[s]/60*(1 - t2/21*(1 - t2/24*(1.0/2 - t2/165))) # Taylor series O(t^8)
r[c] = (3*sin(t[c]) - t[c]*(cos(t[c]) + 2))/(t[c]**4)
return r
def sinc4(t):
""" sinc4: t -> 1/t^2 * (1/2 - sinc2(t))
= 1/t^2 * (1/2 - (1 - cos(t))/t^2)
"""
e = 0.01
r = torch.zeros_like(t)
a = torch.abs(t)
s = a < e
c = (s == 0)
t2 = t ** 2
r[s] = 1/24*(1-t2/30*(1-t2/56*(1-t2/90))) # Taylor series O(t^8)
r[c] = (0.5 - (1 - cos(t))/t2) / t2
class Sinc1_autograd(torch.autograd.Function):
@staticmethod
def forward(ctx, theta):
ctx.save_for_backward(theta)
return sinc1(theta)
@staticmethod
def backward(ctx, grad_output):
theta, = ctx.saved_tensors
grad_theta = None
if ctx.needs_input_grad[0]:
grad_theta = grad_output * sinc1_dt(theta).to(grad_output)
return grad_theta
Sinc1 = Sinc1_autograd.apply
class RSinc1_autograd(torch.autograd.Function):
@staticmethod
def forward(ctx, theta):
ctx.save_for_backward(theta)
return rsinc1(theta)
@staticmethod
def backward(ctx, grad_output):
theta, = ctx.saved_tensors
grad_theta = None
if ctx.needs_input_grad[0]:
grad_theta = grad_output * rsinc1_dt(theta).to(grad_output)
return grad_theta
RSinc1 = RSinc1_autograd.apply
class Sinc2_autograd(torch.autograd.Function):
@staticmethod
def forward(ctx, theta):
ctx.save_for_backward(theta)
return sinc2(theta)
@staticmethod
def backward(ctx, grad_output):
theta, = ctx.saved_tensors
grad_theta = None
if ctx.needs_input_grad[0]:
grad_theta = grad_output * sinc2_dt(theta).to(grad_output)
return grad_theta
Sinc2 = Sinc2_autograd.apply
class Sinc3_autograd(torch.autograd.Function):
@staticmethod
def forward(ctx, theta):
ctx.save_for_backward(theta)
return sinc3(theta)
@staticmethod
def backward(ctx, grad_output):
theta, = ctx.saved_tensors
grad_theta = None
if ctx.needs_input_grad[0]:
grad_theta = grad_output * sinc3_dt(theta).to(grad_output)
return grad_theta
Sinc3 = Sinc3_autograd.apply
#EOF