def test_evaluate_failure(self): c = [1.0, 1.0] p = tl.MVP2D(c) with self.assertRaises(tl.TriangularException): p.evaluate(0.0, 0.0) c = [1.0, 1.0, 1.0, 0.0] p = tl.MVP2D(c) with self.assertRaises(tl.TriangularException): p.evaluate(-42.6733, -27.0083) c = [1.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0] p = tl.MVP2D(c) with self.assertRaises(tl.TriangularException): p.evaluate(-42.6733, -27.0083)
def test_augmented_line_integral_4(self): '''MVP2D.augmented_line_integral: parabollic prism with pos and neg integrate to zero''' for trial in range(100): # generate coefs of parabolic prism that ensure positve and negative regions a0 = np.random.uniform(-10, 10) a3 = np.random.uniform(-10, 10) a3 = -a3 if np.sign(a3) == np.sign(a0) else a3 # randomly assign prism along x or y axis if np.random.rand() > 0.5: coefs = np.array([a0, 0.0, 0.0, a3, 0.0, 0]) else: coefs = np.array([a0, 0.0, 0.0, a3, 0.0, 0]) mvp = tl.MVP2D(coefs) # form square region of integration b = np.sqrt(-3.0 * a0 / a3) verts = [(-b, -b), (b, -b), (b, b), (-b, b)] # perform integral and test it is approximately 0 I = 0.0 for i, _ in enumerate(verts[:-1]): I += mvp.augmented_line_integral(verts[i], verts[i + 1]) I += mvp.augmented_line_integral(verts[-1], verts[0]) self.assertAlmostEqual(I, 0.0)
def test_evaluate_3(self): # polynomial = 1 c = [1.0] p = tl.MVP2D(c) self.assertAlmostEqual(p.evaluate(0.0, 0.0), 1.0) self.assertAlmostEqual(p.evaluate(1.0, 0.0), 1.0) self.assertAlmostEqual(p.evaluate(-1.0, 1.0), 1.0) self.assertAlmostEqual(p.evaluate(0.0, 1.0), 1.0) self.assertAlmostEqual(p.evaluate(-42.6733, -27.0083), 1.0)
def test_evaluate_2(self): # polynomial = 1 + x + y + x^2 + x*y + y^2 c = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0] p = tl.MVP2D(c) self.assertAlmostEqual(p.evaluate(0.0, 0.0), 1.0) self.assertAlmostEqual(p.evaluate(1.0, 0.0), 3.0) self.assertAlmostEqual(p.evaluate(-1.0, 1.0), 2.0) self.assertAlmostEqual(p.evaluate(0.0, 1.0), 3.0) self.assertAlmostEqual(p.evaluate(-42.6733, -27.0083), 3634.310490169999)
def test_evaluate_1(self): # polynomial = x^2 + y^2 c = [0.0, 0.0, 0.0, 1.0, 0.0, 1.0] p = tl.MVP2D(c) self.assertAlmostEqual(p.evaluate(0.0, 0.0), 0.0) self.assertAlmostEqual(p.evaluate(1.0, 0.0), 1.0) self.assertAlmostEqual(p.evaluate(-1.0, 1.0), 2.0) self.assertAlmostEqual(p.evaluate(0.0, 1.0), 1.0) self.assertAlmostEqual(p.evaluate(-42.6733, -27.0083), 2550.4588017799997)
def test_augmented_line_integral_2(self): '''MVP2D.augmented_line_integral: square region under parabolic dome''' coefs = np.array([1.0, 0.0, 0.0, -1.0, 0.0, -1.0]) mvp = tl.MVP2D(coefs) b = np.sqrt(2.0) / 2.0 verts = [(-b, -b), (b, -b), (b, b), (-b, b)] expected_integral = 4.0 * b**2 - 8.0 / 3.0 * b**4 I = 0.0 for i, _ in enumerate(verts[:-1]): I += mvp.augmented_line_integral(verts[i], verts[i + 1]) I += mvp.augmented_line_integral(verts[-1], verts[0]) self.assertAlmostEqual(I, expected_integral)
def test_evaluate_4(self): # polynomial = (randomly generated coefs) c = [ 4.9888785066963, -2.6072258560952, 2.6480911731013, 1.9870246909498, 4.6454780151348, 2.2809308451977, -9.5205873062464, 0.850583925308, 9.0531745362343, -9.9005566723182 ] p = tl.MVP2D(c) self.assertAlmostEqual(p.evaluate(0.0, 0.0), 4.9888785066963) self.assertAlmostEqual(p.evaluate(1.0, 0.0), -5.1519099646955) self.assertAlmostEqual(p.evaluate(-1.0, 1.0), 1.2841130799074048) self.assertAlmostEqual(p.evaluate(0.0, 1.0), 0.017343852677100813) self.assertAlmostEqual(p.evaluate(-42.6733, -27.0083), 621923.6139074472)
def test_convex_hull_integral_2(self): '''MVP2D.convex_hull_integral: integral over parabolic dome with random internal points''' coefs = np.array([1.0, 0.0, 0.0, -1.0, 0.0, -1.0]) mvp = tl.MVP2D(coefs) b = np.sqrt(2.0) / 2.0 ext_verts = np.asarray([(-b, -b), (b, -b), (b, b), (-b, b)]) expected_integral = 4.0 * b**2 - 8.0 / 3.0 * b**4 for trial in range(100): points = np.concatenate( (ext_verts, np.random.rand(30, 2) * 2 * b - b)) np.random.shuffle(points) I = mvp.convex_hull_integral(points) self.assertAlmostEqual(I, expected_integral)
def test_convex_hull_integral_3(self): '''MVP2D.convex_hull_integral: integral over degenerate hull with random mvp''' for trial in range(100): coefs = np.random.rand(6) * 10.0 - 5.0 mvp = tl.MVP2D(coefs) rand_vert_0 = tuple(np.random.rand(2) * 20.0 - 10.0) rand_vert_1 = tuple(np.random.rand(2) * 20.0 - 10.0) collinear_vert = tuple( np.random.rand(1) * 10.0 * np.array([ rand_vert_1[0] - rand_vert_0[0], rand_vert_1[1] - rand_vert_0[1] ]) + rand_vert_0) points = np.array([rand_vert_0, rand_vert_1, collinear_vert]) np.random.shuffle(points) I = mvp.convex_hull_integral(points) self.assertAlmostEqual(I, 0.0)
def test_convex_hull_integral_1(self): '''MVP2D.convex_hull_integral: integral over unit cube with shuffled vertices''' points = [(0, 0), (1, 0), (1, 1), (0, 1)] for trial in range(100): random.shuffle(points) # generate random heigh of uniform curce a0 = np.random.uniform(-10, 10) # generate random length coefficient mvp coef_len = random.choice([1, 3, 6, 10, 15, 21]) coefs = np.concatenate(([a0], np.zeros(coef_len - 1))) mvp = tl.MVP2D(coefs) I = mvp.convex_hull_integral(points) self.assertAlmostEqual(I, a0)
def test_augmented_line_integral_3(self): '''MVP2D.augmented_line_integral: ramp through origin integrates to zero over symmetric bounds''' for trial in range(100): # generate coefs of 2D ramp through origin a1 = np.random.uniform(-10, 10) a2 = np.random.uniform(-10, 10) coefs = np.array([0.0, a1, a2]) mvp = tl.MVP2D(coefs) # form rectangular region centered on zero xc = np.random.uniform(0, 10) yc = np.random.uniform(0, 10) verts = [(-xc, -yc), (xc, -yc), (xc, yc), (-xc, yc)] # perform integral and test it is approximately 0 I = 0.0 for i, _ in enumerate(verts[:-1]): I += mvp.augmented_line_integral(verts[i], verts[i + 1]) I += mvp.augmented_line_integral(verts[-1], verts[0]) self.assertAlmostEqual(I, 0.0)
def test_augmented_line_integral_1(self): '''MVP2D.augmented_line_integral: test integral of unit cube''' c = [1.0] mvp = tl.MVP2D(c) # test full cube verts = [(0, 0), (1, 0), (1, 1), (0, 1)] I = 0.0 for i, _ in enumerate(verts[:-1]): I += mvp.augmented_line_integral(verts[i], verts[i + 1]) I += mvp.augmented_line_integral(verts[-1], verts[0]) self.assertAlmostEqual(I, 1.0) # test half cube verts = [(0, 0), (1, 0), (1, 1)] I = 0.0 for i, _ in enumerate(verts[:-1]): I += mvp.augmented_line_integral(verts[i], verts[i + 1]) I += mvp.augmented_line_integral(verts[-1], verts[0]) self.assertAlmostEqual(I, 0.5)
def test_augmented_line_integral_5(self): '''MVP2D.augmented_line_integral: random triangular region under uniform curve with random length coeffs''' for trial in range(100): # generate random heigh of uniform curce a0 = np.random.uniform(-10, 10) # generate random length coefficient mvp coef_len = random.choice([1, 3, 6, 10, 15, 21]) coefs = np.concatenate(([a0], np.zeros(coef_len - 1))) mvp = tl.MVP2D(coefs) # form random triangular path with positive orientation p1 = np.random.uniform(-10, 10, 2) p2 = np.random.uniform(-10, 10, 2) p3 = np.random.uniform(-10, 10, 2) verts = [p1, p2, p3] if tl.vertex_orientation_2d(verts)[0] < 0: verts = [p1, p3, p2] # find area of triangle region v12 = p2 - p1 v13 = p3 - p1 l12 = np.linalg.norm(v12) l13 = np.linalg.norm(v13) gamma = np.arccos(np.dot(v12, v13) / (l12 * l13)) height = l13 * np.sin(gamma) area = 0.5 * l12 * height # perform integral and test it is approximately area * a0 I = 0.0 for i, _ in enumerate(verts[:-1]): I += mvp.augmented_line_integral(verts[i], verts[i + 1]) I += mvp.augmented_line_integral(verts[-1], verts[0]) self.assertAlmostEqual(I, a0 * area)