def init_ecg_for_2d_rect_mesh(self, cells_x, cells_y): """Init edges conflict graph for 2d rectangular mesh. Parameters ---------- cells_x : int Cells count along OX axis. cells_y : int Cells count along OY axis. """ self.clear() for xi in range(cells_x): for yi in range(cells_y): # Process one cell (xi, xi + 1) * (yi, yi + 1) # First create vertices in centers. l = self.find_or_new_vertex(geom.Vector(xi, yi + 0.5, 0.0)) r = self.find_or_new_vertex( geom.Vector(xi + 1.0, yi + 0.5, 0.0)) d = self.find_or_new_vertex(geom.Vector(xi + 0.5, yi, 0.0)) u = self.find_or_new_vertex( geom.Vector(xi + 0.5, yi + 1.0, 0.0)) # Now add conflicts. for (v0, v1) in itertools.combinations([l, r, d, u], 2): self.new_edge(v0, v1)
def test_vecneg(): cases = ((0.0, ), (1, ), (-2, -3.0), (34.5, -22, 130)) expected = ((0.0, ), (-1, ), (2, 3.0), (-34.5, 22, -130)) for cv, ce in zip(cases, expected): v = geom.Vector(cv) e = geom.Vector(ce) assert (e == -v)
def test_vecdot(): A = ((0, ), (1, ), (0.003, 0.004), (4123213.0, 12093201, 3298928)) B = ((30, ), (0.5, ), (-0.008, 0.006), (2, 3.3, 4.01)) expected = (0, 0.5, 0, 61382690.58) for a, b, e in zip(A, B, expected): v = geom.Vector(a) assert (abs((v @ b) - e) < 0.001) assert (abs((b @ v) - e) < 0.001) assert (abs(v.dot(b) - e) < 0.001) A = ((1, ), (1, 1), (1, 1, 1)) BT = (("zero", ), ((1, 2), (3, 4)), (True, 0, "False")) tests = ("{0} @ {1}", "{1} @ {0}", "{0}.dot({1})") for a, bt in zip(A, BT): av = geom.Vector(a) for test in tests: with pytest.raises(TypeError): eval(test.format('av', 'bt')) A = ((1, ), (1, 1, 1)) b = (1, 1) for a in A: av = geom.Vector(a) for test in tests: with pytest.raises(ValueError): eval(test.format('av', 'b'))
def test_transitive(): """Test that vector equality is transitive""" a = geom.Vector([1, 1, 1, 1]) b = geom.Vector([1, 1, 1, 1]) c = geom.Vector([1, 1, 1, 1]) assert a == b assert b == c assert a == c
def test_vecmul(): C = ((0, ), (133333, ), (3, -4.5), (-2.0, -1.5, -1.0)) E = ((0, ), (-266666, ), (0, 0), (66.6, 49.95, 33.3)) M = (30, -2, 0, -33.3) EPSILON = 10**-6 for c, e, m in zip(C, E, M): v = geom.Vector(c) mv = geom.Vector(c) mv.mulBy(m) diff = m * v - e assert diff.magSq() < EPSILON diff = v * m - e assert diff.magSq() < EPSILON diff = v.mul(m) - e assert diff.magSq() < EPSILON dif = mv - e assert diff.magSq() < EPSILON E = ((0, ), (1.0, ), (-6, 9), (-0.5, -0.375, -0.25)) D = (1, 133333, -0.5, 4) for c, e, d in zip(C, E, D): v = geom.Vector(c) dv = geom.Vector(c) dv.divBy(d) diff = (v / d) - e assert diff.magSq() < EPSILON diff = v.div(d) - e assert diff.magSq() < EPSILON diff = dv - e assert diff.magSq() < EPSILON v = geom.Vector(range(1, 4)) tests = ("v * %s", "%s * v", "v.add(%s)", "v.addOn(%s)", "v / %s", "v.div(%s)", "v.divBy(%s)") bad = ("'3'", 'True', 'None', (3, 4)) for bt in bad: for test in tests: with pytest.raises(TypeError): eval(test % bt) tests = ("v / %s", "v.div(%s)", "v.divBy(%s)") for test in tests: with pytest.raises(ZeroDivisionError): eval(test % '0')
def test_vecinit(): vc = object.__new__(geom.Vector) vc._components = [1, 2, 3] cases = [(1, 2, 3), [1.0, 2.0, 3.0], {1, 2, 3.0}, range(1, 4), vc] expected = [1, 2, 3] for v in cases: assert (geom.Vector(v)._components == expected) with pytest.raises(ValueError): geom.Vector(()) with pytest.raises(TypeError): geom.Vector(('1', 2.0, 3)) with pytest.raises(TypeError): geom.Vector(1)
def test_circmoved(): center = (23.4, -99) circle = geom.Circle(center, 34.09) posv = ((0, 0), (-12003032, 0.00012303)) for pos in posv: c = circle.moved_to(pos) assert (c.center == pos) vecv = ([0, 0], (1, 0), {0, -203}, geom.Vector((0.3213, 45.23))) posv = (center, (24.4, -99), (23.4, -302), (23.7213, -53.77)) for vec, pos in zip(vecv, posv): c = circle.moved_by(vec) assert (c.center == pos) vecv = (33, 1.203, ('2', 3, 0.4), True, '(3, 4, 5)', geom.Circle((1, 2), 3)) for vec in vecv: with pytest.raises(TypeError): circle.moved_to(vec) with pytest.raises(TypeError): circle.moved_by(vec) vecv = ((1.9, ), (-43, ), (203, -804.10, 0)) for vec in vecv: with pytest.raises(ValueError): circle.moved_to(vec) with pytest.raises(ValueError): circle.moved_by(vec)
def test_vecgetitem(): I = (0, 1, 2, 19) A = ('x', 'y', 'z') V = [[2 * i for i in range(n)] for n in range(1, 4)] V.append([3 * i for i in range(20)]) expected = { 'index': ((0, ), (0, 2), (0, 2, 4), (0, 3, 6, 57)), 'attr': ((0, ), (0, 2), (0, 2, 4), (0, 3, 6)) } for i, components in enumerate(V): v = geom.Vector(components) for j, index in enumerate(I): if j >= len(expected['index'][i]): with pytest.raises(IndexError): v[index] else: assert (v[index] == expected['index'][i][j]) for j, attr in enumerate(A): if j >= len(expected['attr'][i]): with pytest.raises(IndexError): getattr(v, attr) else: assert (getattr(v, attr) == expected['attr'][i][j])
def test_circinit(): centers = ((0, 0), (-0.0001, -0.00023), (3002.0002, -4003.2093)) radii = (0, 0.00032, 5.0021) for p, r in zip(centers, radii): c1 = object.__new__(geom.Circle) c1._center = geom.Vector(p) c1._radius = r c2 = geom.Circle(p, r) assert (c1.center == c2.center) assert (abs(c1.radius - c2.radius) < geom.EPSILON) with pytest.raises(TypeError): geom.Circle('{1, 2}', 3) class Test(object): __slots__ = ['components'] def __iter__(self): yield from self.components a = object.__new__(Test) a.components = [1, 2] with pytest.raises(AttributeError): geom.Circle(a, 3.00002) with pytest.raises(ValueError): geom.Circle((1, ), 30000) with pytest.raises(ValueError): geom.Circle((1, 1, 1), 0.0001) with pytest.raises(TypeError): geom.Circle((1, 2), '3') with pytest.raises(ValueError): geom.Circle((20, 30), -39)
def SetAdditionalData(self, g, idxs): """ Set additional data. Arguments: g -- grid, idxs -- indexes. """ (i, j, k) = idxs self.Idxs = idxs self.Center = geom.Vector((i + 0.5) * g.dx, (j + 0.5) * g.dy, (k + 0.5) * g.dz) self.LoCorner = geom.Vector(i * g.dx, j * g.dy, k * g.dz) self.HiCorner = geom.Vector((i + 1) * g.dx, (j + 1) * g.dy, (k + 1) * g.dz)
def test_vecmag(): cases = ((0, ), (1, ), (3, 4), (1.0, 1.0), (0.1, 4.0, 79.0)) expected = (0, 1, 5, 2**0.5, 79.1013) for components, e in zip(cases, expected): v = geom.Vector(components) assert (abs(v) - e < 0.0001) assert (v.mag() - e < 0.0001) assert (v.magSq() - (e**2) < 0.0001)
def test_vecnorm(): cases = ((1, ), (3, 4), (0.1, 10, 100)) for components in cases: v = geom.Vector(components) n1 = ~v n2 = v.norm() n3 = geom.Vector(components) n3.normalize() for n in (n1, n2, n3): assert n is not None assert (abs(abs(n) - 1.0) < 0.0001) m = v.x / n.x assert (m > 0) assert (False not in [abs(m - i / j) < 0.0001 for i, j in zip(v, n)]) with pytest.raises(ValueError): ~geom.Vector((0, 0))
def init_3d_rect_mesh(self, xn, yn, zn): """Init 3 dimensional mesh graph. Parameters ---------- xn : int Number of cells along x direction. yn : int Number of cells along y direction. zn : int Number of cells along z direction. """ self.clear() for xi in range(xn): for yi in range(yn): for zi in range(zn): ulf = self.find_or_new_vertex( geom.Vector(xi + 0.1 * zi, yi + 0.1 * zi, 0.0)) urf = self.find_or_new_vertex( geom.Vector(xi + 1.0 + 0.1 * zi, yi + 0.1 * zi, 0.0)) dlf = self.find_or_new_vertex( geom.Vector(xi + 0.1 * zi, yi + 1.0 + 0.1 * zi, 0.0)) drf = self.find_or_new_vertex( geom.Vector(xi + 1.0 + 0.1 * zi, yi + 1.0 + 0.1 * zi, 0.0)) ulb = self.find_or_new_vertex( geom.Vector(xi + 0.1 * (zi + 1), yi + 0.1 * (zi + 1), 0.0)) urb = self.find_or_new_vertex( geom.Vector(xi + 1.0 + 0.1 * (zi + 1), yi + 0.1 * (zi + 1), 0.0)) dlb = self.find_or_new_vertex( geom.Vector(xi + 0.1 * (zi + 1), yi + 1.0 + 0.1 * (zi + 1), 0.0)) drb = self.find_or_new_vertex( geom.Vector(xi + 1.0 + 0.1 * (zi + 1), yi + 1.0 + 0.1 * (zi + 1), 0.0)) self.find_or_new_edge(ulf, urf) self.find_or_new_edge(ulf, dlf) self.find_or_new_edge(urf, drf) self.find_or_new_edge(dlf, drf) self.find_or_new_edge(ulb, urb) self.find_or_new_edge(ulb, dlb) self.find_or_new_edge(urb, drb) self.find_or_new_edge(dlb, drb) self.find_or_new_edge(ulf, ulb) self.find_or_new_edge(urf, urb) self.find_or_new_edge(dlf, dlb) self.find_or_new_edge(drf, drb)
def get_center_point(self): """Get center point. Returns ------- Vector Center point. """ k = 1.0 / len(self.Vertices) return sum([v.P for v in self.Vertices], start=geom.Vector()) * k
def test_veccross(): A = ((0, 0, 0), (1.0, 0, 0), (-300000, 20003, -0.020012)) b = (3, 4, 5) expected = ((0, 0, 0), (0, -5.0, 4.0), (100015.08005, 1499999.939964, -1260009)) EPSILON = 0.001 for a, e in zip(A, expected): av = geom.Vector(a) ev = geom.Vector(e) diff = av * b - ev assert diff.magSq() < EPSILON diff = av.cross(b) - ev assert diff.magSq() < EPSILON bv = geom.Vector(b) assert (bv * A[1] != A[1] * bv) BT = ((True, True, 1.0), False, ("3.0", 4.2, 12), "{3.3, 1.0 5.9}", ((3, 4), (5, 6), (7, 8))) tests = ("{0} * {1}", "{1} * {0}", "{0}.cross({1})") for bt in BT: for test in tests: with pytest.raises(TypeError): eval(test.format('bv', 'bt')) BL = ((1, ), (1, 2), (1, 2, 3, 4)) for bl in BL: for test in tests: with pytest.raises(ValueError): eval(test.format('bv', 'bl')) BL2 = ((2, ), (3, 4), (5, 6, 7, 8)) for bl, bl2 in zip(BL, BL2): blv = geom.Vector(bl) for test in tests: with pytest.raises(ValueError): eval(test.format('blv', 'bl2'))
def load_dat_mesh(self, filename): """Load surface mesh from dat file. Parameters ---------- filename : str Name of file. """ self.clear() with open(filename, 'r') as f: # Variables info. vc = len(f.readline().split('=')[1].split()) # Zone. Ingore it - we work with one zone. f.readline() # Nodes. nc = int(f.readline().split('=')[1]) # Elements. ec = int(f.readline().split('=')[1]) # Datapacking, zonetype, varlocation. Ignore it. f.readline() f.readline() f.readline() # Read coordinates of nodes. xs = [float(x) for x in f.readline().split()] ys = [float(y) for y in f.readline().split()] zs = [float(z) for z in f.readline().split()] assert (len(xs) == nc) and (len(ys) == nc) and (len(zs) == nc) # Add nodes. for i in range(nc): self.new_vertex(geom.Vector(xs[i], ys[i], zs[i])) # Ignore extra variables. for _ in range(vc - 3): f.readline() # Read links. for _ in range(ec): link = f.readline().split() idxs = [int(link[i]) for i in range(3)] self.new_face([self.Vertices[idx - 1] for idx in idxs]) f.close()
def init_2d_rect_mesh(self, xn, yn): """Init 2 dimensional mesh graph. Parameters ---------- xn : int Number of cells along x direction. yn : int Number of cells along y direction. """ self.clear() for xi in range(xn): for yi in range(yn): ul = self.find_or_new_vertex(geom.Vector(xi, yi, 0.0)) ur = self.find_or_new_vertex(geom.Vector(xi + 1.0, yi, 0.0)) dl = self.find_or_new_vertex(geom.Vector(xi, yi + 1.0, 0.0)) dr = self.find_or_new_vertex( geom.Vector(xi + 1.0, yi + 1.0, 0.0)) self.find_or_new_edge(ul, ur) self.find_or_new_edge(ul, dl) self.find_or_new_edge(ur, dr) self.find_or_new_edge(dl, dr)
def load_dat_ecg(self, filename): """Load ECG graph from dat format. Parameters ---------- filename : str Name of file. """ self.clear() with open(filename, 'r') as f: # Read head. f.readline() # comment f.readline() # title f.readline() # variables f.readline() # zone ns = int(f.readline().split('=')[-1]) es = int(f.readline().split('=')[-1]) f.readline() # datapacking f.readline() # zonetype # Create vertices. for _ in range(ns): self.new_vertex(geom.Vector()) # Set coordinates and colors. xs = [float(xi) for xi in f.readline().split()] ys = [float(xi) for xi in f.readline().split()] zs = [float(xi) for xi in f.readline().split()] cs = [int(xi) for xi in f.readline().split()] for i in range(ns): v = self.Vertices[i] v.P.X, v.P.Y, v.P.Z, v.C = xs[i], ys[i], zs[i], cs[i] # Load data for edges. for _ in range(es): ds = [int(i) for i in f.readline().split()] self.new_edge(self.Vertices[ds[0] - 1], self.Vertices[ds[1] - 1]) f.close()
def create_and_init_grid(case): if case == Case_1D_X: g = Grid(1.0, 1.0, 1.0, 100, 1, 1) elif case == Case_1D_Y: g = Grid(1.0, 1.0, 1.0, 1, 100, 1) elif case == Case_1D_Z: g = Grid(1.0, 1.0, 1.0, 1, 1, 100) elif case == Case_2D_XY: g = Grid(1.0, 1.0, 1.0, 70, 70, 1) else: raise Exception('unknown case number') for i in range(g.CellsX): for j in range(g.CellsY): for k in range(g.CellsZ): c = g.Cells[i][j][k] if case == Case_1D_X: if c.Center.X < 0.5: c.D = DataD(10.0, 0.0, 0.0, 0.0, 10.0) else: c.D = DataD(1.0, 0.0, 0.0, 0.0, 1.0) if i == g.CellsX - 1: c.Borders[BorderR] = BorderHard elif case == Case_1D_Y: if c.Center.Y < 0.5: c.D = DataD(10.0, 0.0, 0.0, 0.0, 10.0) else: c.D = DataD(1.0, 0.0, 0.0, 0.0, 1.0) elif case == Case_1D_Z: if c.Center.Z < 0.5: c.D = DataD(10.0, 0.0, 0.0, 0.0, 10.0) else: c.D = DataD(1.0, 0.0, 0.0, 0.0, 1.0) elif case == Case_2D_XY: if c.Center.X < 0.1: c.D = DataD(10.0, 0.0, 0.0, 0.0, 10.0) else: c.D = DataD(1.0, 0.0, 0.0, 0.0, 1.0) else: raise Exception('unknown case number') if case == Case_2D_XY: # Ellipse equation. # (x - 0.6)^2 + (y - 0.5)^2 - 0.3^2 = 0 elfun = lambda x, y: (x - Sph.C.X)**2 + (y - Sph.C.Y)**2 - Sph.R**2 for i in range(g.CellsX): for j in range(g.CellsY): cell = g.Cells[i][j][0] x1, x2 = i * g.dx, (i + 1) * g.dx y1, y2 = j * g.dy, (j + 1) * g.dy f11, f12, f21, f22 = elfun(x1, y1), elfun(x1, y2), elfun( x2, y1), elfun(x2, y2) if abs(f11) < 1.0e-6: f11 = 0.0 if abs(f12) < 1.0e-6: f12 = 0.0 if abs(f21) < 1.0e-6: f21 = 0.0 if abs(f22) < 1.0e-6: f22 = 0.0 s11, s12, s21, s22 = mth.sign(f11), mth.sign(f12), mth.sign( f21), mth.sign(f22) ss = int(s11 + s12 + s21 + s22) if ss == -4: cell.Type = TypeInner elif ss == 4: cell.Type = TypeCommon else: # Ghost or border. xc, yc = (i + 0.5) * g.dx, (j + 0.5) * g.dy if elfun(xc, yc) < 0.0: cell.Type = TypeGhost else: cell.Type = TypeBorder for i in range(g.CellsX): for j in range(g.CellsY): for k in range(g.CellsZ): cell = g.Cells[i][j][k] if cell.Type == TypeBorder: if g.Cells[i - 1][j][k].Type == TypeInner: g.Cells[i - 1][j][k].Type = TypeGhost if g.Cells[i + 1][j][k].Type == TypeInner: g.Cells[i + 1][j][k].Type = TypeGhost if g.Cells[i][j - 1][k].Type == TypeInner: g.Cells[i][j - 1][k].Type = TypeGhost if g.Cells[i][j + 1][k].Type == TypeInner: g.Cells[i][j + 1][k].Type = TypeGhost for i in range(g.CellsX): for j in range(g.CellsY): for k in range(g.CellsZ): cell = g.Cells[i][j][k] if cell.Type == TypeGhost: if g.Cells[i - 1][j][k].IsTypeCalc(): continue if g.Cells[i + 1][j][k].IsTypeCalc(): continue if g.Cells[i][j - 1][k].IsTypeCalc(): continue if g.Cells[i][j + 1][k].IsTypeCalc(): continue cell.Type = TypeInner for i in range(g.CellsX): for j in range(g.CellsY): for k in range(g.CellsZ): cell = g.Cells[i][j][k] if cell.Type == TypeGhost: cell.BorderPoint = geom.Vector((i + 0.5) * g.dx, (j + 0.5) * g.dy, 0.0).NearestPoint(Sph) cell.BorderNormal = (cell.BorderPoint - Sph.C).Normalized() return g
def Draw(self, fun, is_draw_color_field=True, is_draw_cells=True, is_draw_patterns=True, is_draw_velocity_field=True): d = draw.Drawer(draw_area=(0.0, 0.0, self.SizeX, self.SizeY), pic_size=(800, 800)) """ Draw picture. Arguments: d -- drawer, pic_size -- picture size. """ (mn, mx) = self.FunInterval(fun) if is_draw_color_field: # Coloring. for i in range(self.CellsX): for j in range(self.CellsY): c = self.Cells[i][j][0] factor = 255 - int((fun(c) - mn) / (mx - mn) * 255) color = (factor, factor, factor) d.Rect(c.LoCorner.Tuple(2), c.HiCorner.Tuple(2), aggdraw.Pen(color, 1.0), aggdraw.Brush(color)) d.Rect((0.0, 0.0), (self.SizeX, self.SizeY), aggdraw.Pen('blue', 1.0)) # Draw ellipse. d.Ellipse(Sph.LoPoint().Tuple(2), Sph.HiPoint().Tuple(2), pen=aggdraw.Pen('black', 2.0)) if is_draw_cells: # Inner. pen = aggdraw.Pen('orange', 2.0) for i in range(self.CellsX): for j in range(self.CellsY): c = self.Cells[i][j][0] if c.Type == TypeInner: d.Rect(c.LoCorner.Tuple(2), c.HiCorner.Tuple(2), pen) # Ghost. pen = aggdraw.Pen('red', 2.0) for i in range(self.CellsX): for j in range(self.CellsY): c = self.Cells[i][j][0] if c.Type == TypeGhost: d.RectWithCenterPoint(c.LoCorner.Tuple(2), c.HiCorner.Tuple(2), 1, pen) # Border. pen = aggdraw.Pen('green', 2.0) for i in range(self.CellsX): for j in range(self.CellsY): c = self.Cells[i][j][0] if c.Type == TypeBorder: d.RectWithCenterPoint(c.LoCorner.Tuple(2), c.HiCorner.Tuple(2), 1, pen) if is_draw_patterns: # Draw shpere nearest points. pen = aggdraw.Pen('black', 2.0) for i in range(self.CellsX): for j in range(self.CellsY): c = self.Cells[i][j][0] if c.BorderPoint != None: d.Point(c.BorderPoint.Tuple(2), 1.0, pen) d.Line(c.BorderPoint.Tuple(2), (c.BorderPoint + 0.05 * c.BorderNormal).Tuple(2), pen) # Draw approximate patterns. pen = aggdraw.Pen('pink', 2.0) for i in range(self.CellsX): for j in range(self.CellsY): c = self.Cells[i][j][0] if (c.App1 != None) and (c.App2 != None): d.FullGraph([ c.BorderPoint.Tuple(2), c.App1.Tuple(2), c.App2.Tuple(2) ], pen) if is_draw_velocity_field: # Draw velocity speed. pen = aggdraw.Pen('steelblue', 1.0) for i in range(self.CellsX): for j in range(self.CellsY): c = self.Cells[i][j][0] if (c.Type == TypeCommon) or (c.Type == TypeBorder) or ( c.Type == TypeGhost): v = geom.Vector(c.D.u, c.D.v, 0.0) if v.Mod() < 0.001: d.Point(c.Center.Tuple(2), 1, pen) else: v.Normalize() v.Scale(0.4 * self.dx) d.Line((c.Center - v).Tuple(2), (c.Center + v).Tuple(2), pen) d.FSS()
import draw import aggdraw import mth import math import vis import time import geom import lst #--------------------------------------------------------------------------------------------------- # Constants. #--------------------------------------------------------------------------------------------------- Gamma = 1.4 Sph = geom.Sphere(geom.Vector(0.6, 0.5, 0.0), 0.3) #--------------------------------------------------------------------------------------------------- # Utilitiees. #--------------------------------------------------------------------------------------------------- def array_3d(x, y, z): arr = [None] * x for i in range(x): arr[i] = [None] * y for j in range(y): arr[i][j] = [None] * z return arr
def test_with_max_float(): """Test that equality works with max float values""" a = geom.Vector([sys.float_info.max, -sys.float_info.max]) b = geom.Vector([sys.float_info.max, -sys.float_info.max]) assert a == b
def test_same_value_different_types(): """Test that equality works with same value but different types.""" assert geom.Vector([3.0]) == geom.Vector([complex(3.0)])
def test_with_multiple_types(): """Test that equality works with multiple types.""" a = geom.Vector([1.0, -3, complex(0, 0.2)]) b = geom.Vector([1.0, -3, complex(0, 0.2)]) assert a == b
def test_with_complex_numbers(): """Test that equality works with complex numbers.""" a = geom.Vector([complex(1, 1), complex(-1, -1)]) b = geom.Vector([complex(1, 1), complex(-1, -1)]) assert a == b
def test_with_large_floats(): """Test that equality works with large floating point numbers.""" a = geom.Vector([123456.7, 891011.12]) b = geom.Vector([123456.7, 891011.12]) assert a == b
def test_with_small_floats(): """Test that equality works with small floating point numbers.""" a = geom.Vector([0.0001, 0.0002, -0.0003]) b = geom.Vector([0.0001, 0.0002, -0.0003]) assert a == b
def test_one_dimension(): """Test equality for vectors with one dimension""" assert geom.Vector([1]) == geom.Vector([1])
def test_with_floats(): """Test that equality works with floating point numbers.""" assert geom.Vector([1.2, 1.3]) == geom.Vector([1.2, 1.3])
def test_null_equality(): """Test that null equality is false""" assert not geom.Vector([0]) == None