def test29_asin(m): x = ek.linspace(m.Float, -.8, .8, 10) ek.enable_grad(x) y = ek.asin(x * x) ek.backward(y) asin_x = ek.asin(ek.sqr(ek.detach(x))) assert ek.allclose(y, asin_x) assert ek.allclose( ek.grad(x), m.Float(-2.08232, -1.3497, -0.906755, -0.534687, -0.177783, 0.177783, 0.534687, 0.906755, 1.3497, 2.08232))
def test09_trig(): for i in range(-5, 5): for j in range(-5, 5): a = ek.sin(C(i, j)) b = C(cmath.sin(complex(i, j))) assert ek.allclose(a, b) a = ek.cos(C(i, j)) b = C(cmath.cos(complex(i, j))) assert ek.allclose(a, b) sa, ca = ek.sincos(C(i, j)) sb = C(cmath.sin(complex(i, j))) cb = C(cmath.cos(complex(i, j))) assert ek.allclose(sa, sb) assert ek.allclose(ca, cb) # Python appears to handle the branch cuts # differently from Enoki, C, and Mathematica.. a = ek.asin(C(i, j + 0.1)) b = C(cmath.asin(complex(i, j + 0.1))) assert ek.allclose(a, b) a = ek.acos(C(i, j + 0.1)) b = C(cmath.acos(complex(i, j + 0.1))) assert ek.allclose(a, b) if abs(j) != 1 or i != 0: a = ek.atan(C(i, j)) b = C(cmath.atan(complex(i, j))) assert ek.allclose(a, b, atol=1e-7)
def quat_to_euler(q): name = _ek.detail.array_name('Array', q.Type, [3], q.IsScalar) module = _modules.get(q.__module__) Array3f = getattr(module, name) sinp = 2 * _ek.fmsub(q.w, q.y, q.z * q.x) gimbal_lock = _ek.abs(sinp) > (1.0 - 5e-8) # roll (x-axis rotation) q_y_2 = _ek.sqr(q.y) sinr_cosp = 2 * _ek.fmadd(q.w, q.x, q.y * q.z) cosr_cosp = _ek.fnmadd(2, _ek.fmadd(q.x, q.x, q_y_2), 1) roll = _ek.select(gimbal_lock, 2 * _ek.atan2(q.x, q.w), _ek.atan2(sinr_cosp, cosr_cosp)) # pitch (y-axis rotation) pitch = _ek.select(gimbal_lock, _ek.copysign(0.5 * _ek.Pi, sinp), _ek.asin(sinp)) # yaw (z-axis rotation) siny_cosp = 2 * _ek.fmadd(q.w, q.z, q.x * q.y) cosy_cosp = _ek.fnmadd(2, _ek.fmadd(q.z, q.z, q_y_2), 1) yaw = _ek.select(gimbal_lock, 0, _ek.atan2(siny_cosp, cosy_cosp)) return Array3f(roll, pitch, yaw)
def asin_(a0): if not a0.IsFloat: raise Exception("asin(): requires floating point operands!") ar, sr = _check1(a0) if not a0.IsSpecial: for i in range(sr): ar[i] = _ek.asin(a0[i]) elif a0.IsSpecial: tmp = _ek.log(type(a0)(-a0.imag, a0.real) + _ek.sqrt(1 - _ek.sqr(a0))) ar.real = tmp.imag ar.imag = -tmp.real else: raise Exception("asin(): unsupported array type!") return ar
def test06_phase_tir(variant_scalar_rgb): import numpy as np from mitsuba.render import fresnel_polarized eta = 1 / 1.5 # Check phase shift at critical angle (total internal reflection case) crit = ek.asin(eta) a_s, a_p, _, _, _ = fresnel_polarized(ek.cos(crit), eta) assert ek.allclose(ek.arg(a_s), 0.0) assert ek.allclose(ek.arg(a_p), ek.pi) or ek.allclose(ek.arg(a_p), -ek.pi) # Check phase shift at grazing angle (total internal reflection case) a_s, a_p, _, _, _ = fresnel_polarized(0.0, eta) assert ek.allclose(ek.arg(a_s), ek.pi) or ek.allclose(ek.arg(a_s), -ek.pi) assert ek.allclose(ek.arg(a_p), 0.0) # Location of minimum phase difference cos_theta_min = ek.sqrt((1 - eta**2) / (1 + eta**2)) phi_delta = 4 * ek.atan(eta) a_s, a_p, _, _, _ = fresnel_polarized(cos_theta_min, eta) assert ek.allclose(ek.arg(a_s) - ek.arg(a_p), phi_delta)
def quat_to_euler(q): q_y_2 = _ek.sqr(q.y) sinr_cosp = 2 * _ek.fmadd(q.w, q.x, q.y * q.z) cosr_cosp = _ek.fnmadd(2, _ek.fmadd(q.x, q.x, q_y_2), 1) roll = _ek.atan2(sinr_cosp, cosr_cosp) # pitch (y-axis rotation) sinp = 2 * _ek.fmsub(q.w, q.y, q.z * q.x) if (_ek.abs(sinp) >= 1.0): pitch = _ek.copysign(0.5 * _ek.Pi, sinp) else: pitch = _ek.asin(sinp) # yaw (z-axis rotation) siny_cosp = 2 * _ek.fmadd(q.w, q.z, q.x * q.y) cosy_cosp = _ek.fnmadd(2, _ek.fmadd(q.z, q.z, q_y_2), 1) yaw = _ek.atan2(siny_cosp, cosy_cosp) name = _ek.detail.array_name('Array', q.Type, [3], q.IsScalar) module = _modules.get(q.__module__) Array3f = getattr(module, name) return Array3f(roll, pitch, yaw)