def setup(self): self.phase1 = Angle(np.array([1000., 1001., 999., 1005, 1006.]), u.cycle)[:, np.newaxis] self.phase2 = Angle( 2.**(-53) * np.array([1, -1., 1., -1.]) + np.array([-0.5, 0., 0., 0.5]), u.cycle) self.phase = Phase(self.phase1, self.phase2) self.delta = Phase(0., self.phase2) self.im_phase = Phase(self.phase1 * 1j, self.phase2 * 1j)
def test_isnan(self): expected = np.zeros(self.phase.shape) assert_equal(np.isnan(self.phase), expected) # For older astropy, we set input to nan rather than Phase directly, # since setting of nan exposes a Quantity bug. phase2 = self.phase2.copy() phase2[1] = np.nan phase = Phase(self.phase1, phase2) expected[:, 1] = True assert_equal(np.isnan(phase), expected) trial = Phase(np.nan) assert np.isnan(trial)
def test_negative_with_out(self): out = 0 * self.phase result = np.negative(self.phase, out=out) assert result is out assert_equal(result, Phase(-self.phase1, -self.phase2)) # Also with regular Angle input. out2 = Phase(np.zeros_like(self.phase1)) result2 = np.negative(self.phase1, out=out2) assert result2 is out2 assert_equal(result2, Phase(-self.phase1)) # And for imaginary output result = np.negative(self.im_phase, out=out) assert result is out assert_equal(result, Phase(-1j * self.phase1, -1j * self.phase2))
def test_absolute_with_out(self): out = 0 * self.phase result = np.absolute(-self.phase, out=out) assert result is out assert_equal(result, self.phase) # Also with regular Angle input. out2 = Phase(np.zeros_like(self.phase1)) result2 = np.absolute(-self.phase1, out=out2) assert result2 is out2 assert_equal(result2, Phase(self.phase1)) # And with imaginary phase out3 = 0 * self.im_phase result3 = np.absolute(-self.im_phase, out=out3) assert result3 is out3 assert_equal(result3, self.phase)
def test_subtraction(self): double = Phase(self.phase1 * 2., self.phase2 * 2.) sub = double - self.phase assert_equal(sub, self.phase) t = self.phase2 * 2. - self.phase sub2 = self.phase1 * 2. + t assert_equal(sub2, sub) t = double - self.phase1.to(u.degree) sub3 = t - self.phase2 assert_equal(sub3, sub) sub4 = self.phase - 1. * u.cycle assert_equal(sub4, Phase(self.phase1 - 1 * u.cycle, self.phase2)) sub6 = self.phase - self.im_phase assert_equal(sub6, self.phase.cycle - self.im_phase.cycle)
def test_addition(self): add = self.phase + self.phase assert_equal(add, Phase(2. * self.phase1, 2. * self.phase2)) t = self.phase1 + self.phase add2 = self.phase2 + t assert_equal(add2, add) t = self.phase + self.phase1.to(u.degree) add3 = t + self.phase2.to(u.degree) assert_equal(add3, add) add4 = self.phase + 1. * u.cycle assert_equal(add4, Phase(self.phase1 + 1 * u.cycle, self.phase2)) add5 = 360. * u.deg + self.phase assert_equal(add5, add4) add6 = self.phase + self.im_phase assert_equal(add6, self.phase.cycle + self.im_phase.cycle)
def test_to_from_string_roundtrip(self, precision, alwayssign, imag): p_in = self.phase * 1j if imag else self.phase s = p_in.to_string(precision=precision, alwayssign=alwayssign) p = Phase.from_string(s) # We cannot get exact round-tripping, since we treat fractional # near 0 as if it is near 0.25. assert np.allclose((p - p_in).value, 0, atol=2**-53, rtol=0)
def test_inplace_addition_subtraction(self): add = self.phase.copy() link = add add += self.phase assert add is link assert_equal(add, Phase(2. * self.phase1, 2. * self.phase2)) result = np.subtract(add, self.phase, out=add) assert result is add assert_equal(result, self.phase) # Quantity output should work. out = self.phase.cycle out += self.phase assert_equal(out, 2 * self.phase.cycle) result2 = np.subtract(out, self.phase, out=out) assert result2 is out assert_equal(out, self.phase.cycle) with pytest.raises(TypeError): # array output is not OK. np.add(out, self.phase, out=out.value) with pytest.raises(TypeError): out += self.im_phase
def test_init(self, phase1, phase2): phase = Phase(phase1, phase2) assert isinstance(phase, Phase) assert_equal(phase['int'], Angle(phase1, u.cycle)) assert_equal(phase['frac'], FractionalPhase(phase2, u.cycle)) expected_cycle = Angle(phase1, u.cycle) + Angle(phase2, u.cycle) assert_equal(phase.cycle, expected_cycle)
def test_init_complex(self): phase = Phase(1j) assert isinstance(phase, Phase) assert phase.imaginary assert_equal(phase.int, Angle(1j, u.cycle)) assert_equal(phase.frac, Angle(0j, u.cycle)) assert_equal(phase.cycle, Angle(1j, u.cycle)) assert '1j cycle' in repr(phase) phase2 = Phase(1 + 0j) assert isinstance(phase2, Phase) assert not phase2.imaginary assert_equal(phase2, Phase(1)) assert '1j cycle' not in repr(phase2) with pytest.raises(ValueError): Phase(1., 0.0001j)
def test_trig(self, ufunc): d = np.arange(-177, 180, 10) * u.degree cycle = 1e10 * u.cycle expected = ufunc(d) assert not np.isclose( ufunc(cycle + d), expected, atol=1e-14, rtol=1.e-14).any() phase = Phase(cycle, d) assert np.isclose(ufunc(phase), expected, rtol=1e-14, atol=1e-14).all()
def test_spacing_with_out(self): out = u.Quantity(np.empty(self.phase.shape), u.cycle) result = np.spacing(self.phase, out=out) assert result is out assert_equal(out, u.Quantity(np.spacing(self.phase.frac))) out2 = 0 * self.phase result2 = np.spacing(self.phase, out=out2) assert result2 is out2 assert_equal(result2, Phase(result))
def test_unitless_division(self): div = self.phase / 0.5 assert_equal(div, Phase(self.phase1 * 2, self.phase2 * 2)) div2 = self.phase / (0.5 * u.dimensionless_unscaled) assert_equal(div2, div) div3 = self.phase / 0.5 / u.one assert_equal(div3, div) div4 = self.phase / np.full(self.phase.shape, 0.5) assert_equal(div4, div)
def test_rint_with_out(self): out = 0 * self.phase result = np.rint(self.phase, out=out) assert result is out assert_equal(result, Phase(self.phase.int)) out2 = np.empty(self.phase.shape) * u.cycle result2 = np.rint(self.phase, out=out2) assert result2 is out2 expected = u.Quantity(self.phase.int) assert_equal(result2, expected)
def test_unitless_multiplication(self): mul = self.phase * 2 assert_equal(mul, Phase(self.phase1 * 2, self.phase2 * 2)) mul2 = self.phase * (2. * u.dimensionless_unscaled) assert_equal(mul2, mul) mul3 = self.phase * 2. * u.one assert_equal(mul3, mul) mul4 = 2. * self.phase assert_equal(mul4, mul) mul5 = self.phase * np.full(self.phase.shape, 2.) assert_equal(mul5, mul)
def test_floor_division_mod(self): fd = self.phase // (1. * u.cycle) fd_exp = self.phase.int.copy() fd_exp[self.phase.frac < 0] -= 1 * u.cycle fd_exp = fd_exp / u.cycle assert_equal(fd, fd_exp) mod = self.phase % (1. * u.cycle) mod_exp = Phase(np.where(self.phase.frac >= 0., 0., 1.), self.phase.frac) assert_equal(mod, mod_exp) exp_cycle = Angle(self.phase.frac, copy=True) exp_cycle[exp_cycle < 0.] += 1. * u.cycle assert_equal(mod.cycle, exp_cycle) dm = divmod(self.phase, 1. * u.cycle) assert_equal(dm[0], fd_exp) assert_equal(dm[1], mod_exp) # fd2 = self.phase // (360. * u.degree) assert_equal(fd2, fd_exp) mod2 = self.phase % (360 * u.degree) assert_equal(mod2, mod_exp) dm2 = divmod(self.phase, 360 * u.degree) assert_equal(dm2[0], fd_exp) assert_equal(dm2[1], mod_exp) # fd3 = self.phase // (240. * u.hourangle) fd3_exp = fd_exp // 10 assert_equal(fd3, fd3_exp) mod3 = self.phase % (240. * u.hourangle) mod_int_exp = self.phase.int % (10 * u.cy) mod_int_exp[0][self.phase.frac[0] < 0] += 10. * u.cy mod3_exp = Phase(mod_int_exp, self.phase.frac) assert_equal(mod3, mod3_exp) dm3 = divmod(self.phase, 240. * u.hourangle) assert_equal(dm3[0], fd3_exp) assert_equal(dm3[1], mod3_exp) with pytest.raises(u.UnitsError): np.mod(self.phase, 1. * u.m)
def test_imaginary_scalings(self): mul = self.phase * 1j expected = Phase(self.phase1 * 1j, self.phase2 * 1j) assert_equal(mul, expected) mul2 = self.phase * 0.125j expected2 = expected * 0.125 assert_equal(mul2, expected2) div = self.phase / 8j expected3 = -expected2 assert_equal(div, expected3) mul4 = self.phase * (1 + 1j) expected4 = self.phase.cycle * (1 + 1j) assert_equal(mul4, expected4)
def test_inplace_unitless_multiplication_division(self): out = self.phase.copy() link = out out *= 2 assert out is link assert_equal(out, Phase(self.phase1 * 2, self.phase2 * 2)) out /= 2 assert out is link assert_equal(out, self.phase) out = np.multiply(self.phase, 2, out=out) assert out is link assert_equal(out, Phase(self.phase1 * 2, self.phase2 * 2)) out = np.divide(self.phase, 0.5, out=out) assert out is link assert_equal(out, Phase(self.phase1 * 2, self.phase2 * 2)) # Also for input angles. out = np.multiply(self.phase.cycle, 2, out=out) assert out is link assert_equal(out, Phase(2 * self.phase.cycle)) with pytest.raises(u.UnitsError): out *= 2 * u.m with pytest.raises(u.UnitsError): np.multiply(self.phase.cycle, 2 * u.m, out=out)
def test_init_with_phase(self): phase = Phase(1., 0.125) phase2 = Phase(phase) assert_equal(phase2, phase) assert phase2 is not phase assert not np.may_share_memory(phase2, phase) phase3 = Phase(phase, copy=False) assert phase3 is phase phase4 = Phase(phase, 0., copy=False) assert phase4 is not phase assert_equal(phase4, phase) phase5 = Phase(0., phase) assert phase5 is not phase assert_equal(phase5, phase) phase6 = Phase(phase, phase) assert_equal(phase6, Phase(2., 0.25))
def test_floor_division_mod_with_out(self): out1 = np.empty(self.phase.shape) * u.dimensionless_unscaled fd = np.floor_divide(self.phase, 1. * u.cycle, out=out1) assert fd is out1 fd_exp = self.phase // (1. * u.cycle) # checked above. assert_equal(fd, fd_exp) out2 = 0. * self.phase mod = np.mod(self.phase, 1. * u.cycle, out=out2) assert mod is out2 mod_exp = Phase(np.where(self.phase.frac >= 0., 0., 1.), self.phase.frac) assert_equal(mod, mod_exp) out1 *= 0 out2 *= 0 dm = np.divmod(self.phase, 1. * u.cycle, out=(out1, out2)) assert dm[0] is out1 assert dm[1] is out2 assert_equal(dm[0], fd_exp) assert_equal(dm[1], mod_exp) with pytest.raises(TypeError): np.floor_divide(self.phase, 1. * u.cycle, out=out2) with pytest.raises(TypeError): np.divmod(self.phase, 1. * u.cycle, out=(out2, out1))
def test_init_with_subclass(self): class MyPhase(Phase): pass my_phase = MyPhase(1., 0.25) assert type(my_phase) is MyPhase phase2 = Phase(my_phase) assert type(phase2) is Phase phase3 = Phase(my_phase, subok=True) assert type(phase3) is MyPhase assert phase3 is not my_phase assert not np.may_share_memory(phase3, my_phase) phase4 = Phase(my_phase, copy=False) assert type(phase4) is Phase assert np.may_share_memory(phase4, my_phase) phase5 = Phase(my_phase, copy=False, subok=True) assert phase5 is my_phase phase6 = Phase(my_phase, 0., copy=False, subok=True) assert type(phase6) is MyPhase assert not np.may_share_memory(phase6, my_phase) phase7 = Phase(my_phase, phase2, copy=False, subok=True) assert type(phase7) is MyPhase phase8 = Phase(phase2, my_phase, copy=False, subok=True) assert type(phase8) is MyPhase
def phase(self, t): return Phase(super().phase(t))
def test_init_basics(self): phase = Phase(1., 0.25) assert isinstance(phase, Phase) assert_equal(phase['int'], Angle(1. * u.cycle)) assert_equal(phase['frac'], FractionalPhase(0.25 * u.cycle)) assert_equal(phase.cycle, Angle(1.25 * u.cycle))
def test_from_string_invalid(self, item): with pytest.raises(ValueError): Phase.from_string(item)
def test_to_from_string_alwayssign(self): ph = Phase([[-10], [20]], [-0.4, 0.4]) s = ph.to_string(alwayssign=True) ph2 = Phase.from_string(s) # No worries about round-off, since fractions relatively large. assert np.all(ph == ph2)
def test_negative(self): neg = -self.phase assert_equal(neg, Phase(-self.phase1, -self.phase2)) neg2 = -self.im_phase assert_equal(neg2, Phase(-1j * self.phase1, -1j * self.phase2))
def test_from_string_with_exponents(self): p = Phase.from_string('9876543210.0123456789e-01') assert p == Phase(987654321, .00123456789) p = Phase.from_string('9876543210.0123456789D-01') assert p == Phase(987654321, .00123456789) # Check that we avoid round-off errors (in fractional phase). assert p != Phase(9876543210 * 1e-1, .0123456789 * 1e-1) p = Phase.from_string('9876543210.0123456789e-01j') assert p == Phase(987654321j, .00123456789j) p = Phase.from_string('9876543210.0123456789e1j') assert p == Phase(98765432100j, .123456789j) p = Phase.from_string('9876543210.0123456789e-12j') assert p == Phase(0j, .0098765432100123456789j) # Really not suited for large exponents... p = Phase.from_string('9876543210.0123456789e12j') assert p == Phase(9876543210012345678900j, 0j)
def test_from_string_basic(self): p = Phase.from_string('9876543210.0123456789') assert p == Phase(9876543210, .0123456789) p = Phase.from_string('9876543210.0123456789j') assert p == Phase(9876543210j, .0123456789j)
def test_to_string_corner_cases(self, count, frac, expected): ph = Phase(count, frac) s = ph.to_string() assert s == expected
def test_to_string_alwayssign(self): ph = Phase([[-10], [20]], [-0.4, 0.4]) s = ph.to_string(alwayssign=True) assert np.all(s == [['-10.4', '-9.6'], ['+19.6', '+20.4']]) for ph, expected in zip(ph.ravel(), s.ravel()): assert '{:+.1f}'.format(ph) == expected