4 import Control.Monad (unless)
9 import Cube (Cube(grid), cube_at, top)
18 import Grid (Grid(h), make_grid)
24 -- | An HUnit assertion that wraps the almost_equals function. Stolen
25 -- from the definition of assertEqual in Test/HUnit/Base.hs.
26 assertAlmostEqual :: String -> Double -> Double -> Assertion
27 assertAlmostEqual preface expected actual =
28 unless (actual ~= expected) (assertFailure msg)
29 where msg = (if null preface then "" else preface ++ "\n") ++
30 "expected: " ++ show expected ++ "\n but got: " ++ show actual
33 -- | Values of the function f(x,y,z) = 1 + x + xy + xyz taken at nine
34 -- points (hi, hj, jk) with h = 1. From example one in the paper.
35 -- Used in the next bunch of tests.
36 trilinear :: [[[Double]]]
37 trilinear = [ [ [ 1, 2, 3 ],
47 -- | Check the value of c0030 for any tetrahedron belonging to the
48 -- cube centered on (1,1,1) with a grid constructed from the
49 -- trilinear values. See example one in the paper.
50 test_trilinear_c0030 :: Test
51 test_trilinear_c0030 =
52 TestCase $ assertAlmostEqual "c0030 is correct" (c t 0 0 3 0) (17/8)
54 g = make_grid 1 trilinear
55 cube = cube_at g 1 1 1
56 t = head (tetrahedrons cube) -- Any one will do.
59 -- | Check the value of c0003 for any tetrahedron belonging to the
60 -- cube centered on (1,1,1) with a grid constructed from the
61 -- trilinear values. See example one in the paper.
62 test_trilinear_c0003 :: Test
63 test_trilinear_c0003 =
64 TestCase $ assertAlmostEqual "c0003 is correct" (c t 0 0 0 3) (27/8)
66 g = make_grid 1 trilinear
67 cube = cube_at g 1 1 1
68 t = head (tetrahedrons cube) -- Any one will do.
71 -- | Check the value of c0021 for any tetrahedron belonging to the
72 -- cube centered on (1,1,1) with a grid constructed from the
73 -- trilinear values. See example one in the paper.
74 test_trilinear_c0021 :: Test
75 test_trilinear_c0021 =
76 TestCase $ assertAlmostEqual "c0021 is correct" (c t 0 0 2 1) (61/24)
78 g = make_grid 1 trilinear
79 cube = cube_at g 1 1 1
80 t = head (tetrahedrons cube) -- Any one will do.
83 -- | Check the value of c0012 for any tetrahedron belonging to the
84 -- cube centered on (1,1,1) with a grid constructed from the
85 -- trilinear values. See example one in the paper.
86 test_trilinear_c0012 :: Test
87 test_trilinear_c0012 =
88 TestCase $ assertAlmostEqual "c0012 is correct" (c t 0 0 1 2) (71/24)
90 g = make_grid 1 trilinear
91 cube = cube_at g 1 1 1
92 t = head (tetrahedrons cube) -- Any one will do.
95 -- | Check the value of c0120 for any tetrahedron belonging to the
96 -- cube centered on (1,1,1) with a grid constructed from the
97 -- trilinear values. See example one in the paper.
98 test_trilinear_c0120 :: Test
99 test_trilinear_c0120 =
100 TestCase $ assertAlmostEqual "c0120 is correct" (c t 0 1 2 0) (55/24)
102 g = make_grid 1 trilinear
103 cube = cube_at g 1 1 1
104 t = head (tetrahedrons cube) -- Any one will do.
108 face_tests = [test_trilinear_c0030,
109 test_trilinear_c0003,
110 test_trilinear_c0021,
111 test_trilinear_c0012,
112 test_trilinear_c0120]
117 -- | Since the grid size is necessarily positive, all tetrahedrons
118 -- (which comprise cubes of positive volume) must have positive volume
120 prop_all_volumes_positive :: Cube -> Property
121 prop_all_volumes_positive c =
122 (delta > 0) ==> (null nonpositive_volumes)
126 volumes = map volume ts
127 nonpositive_volumes = filter (<= 0) volumes
130 -- | Given in Sorokina and Zeilfelder, p. 78.
131 prop_cijk1_identity :: Cube -> Bool
132 prop_cijk1_identity cube =
133 and [ c t0' i j k 1 ~= (c t1' (i+1) j k 0) * ((b0 t0') (v3 t1')) +
134 (c t1' i (j+1) k 0) * ((b1 t0') (v3 t1')) +
135 (c t1' i j (k+1) 0) * ((b2 t0') (v3 t1')) +
136 (c t1' i j k 1) * ((b3 t0') (v3 t1')) | i <- [0..2],
141 t0 = tetrahedron0 (face0 cube)
142 t1 = tetrahedron1 (face0 cube)
143 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
144 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
146 -- | Given in Sorokina and Zeilfelder, p. 79.
147 prop_c0120_identity1 :: Cube -> Bool
148 prop_c0120_identity1 cube =
149 c t0' 0 1 2 0 ~= (c t0' 0 0 2 1 + c t1' 0 0 2 1) / 2
151 t0 = tetrahedron0 (face0 cube)
152 t1 = tetrahedron1 (face0 cube)
153 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
154 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
157 -- | Given in Sorokina and Zeilfelder, p. 79.
158 prop_c0210_identity1 :: Cube -> Bool
159 prop_c0210_identity1 cube =
160 c t0' 0 2 1 0 ~= (c t0' 0 1 1 1 + c t1' 0 1 1 1) / 2
162 t0 = tetrahedron0 (face0 cube)
163 t1 = tetrahedron1 (face0 cube)
164 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
165 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
168 -- | Given in Sorokina and Zeilfelder, p. 79.
169 prop_c0300_identity1 :: Cube -> Bool
170 prop_c0300_identity1 cube =
171 c t0' 0 3 0 0 ~= (c t0' 0 2 0 1 + c t1' 0 2 0 1) / 2
173 t0 = tetrahedron0 (face0 cube)
174 t1 = tetrahedron1 (face0 cube)
175 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
176 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
178 -- | Given in Sorokina and Zeilfelder, p. 79.
179 prop_c1110_identity :: Cube -> Bool
180 prop_c1110_identity cube =
181 c t0' 1 1 1 0 ~= (c t0' 1 0 1 1 + c t1' 1 0 1 1) / 2
183 t0 = tetrahedron0 (face0 cube)
184 t1 = tetrahedron1 (face0 cube)
185 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
186 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
189 -- | Given in Sorokina and Zeilfelder, p. 79.
190 prop_c1200_identity1 :: Cube -> Bool
191 prop_c1200_identity1 cube =
192 c t0' 1 2 0 0 ~= (c t0' 1 1 0 1 + c t1' 1 1 0 1) / 2
194 t0 = tetrahedron0 (face0 cube)
195 t1 = tetrahedron1 (face0 cube)
196 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
197 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
200 -- | Given in Sorokina and Zeilfelder, p. 79.
201 prop_c2100_identity1 :: Cube -> Bool
202 prop_c2100_identity1 cube =
203 c t0' 2 1 0 0 ~= (c t0' 2 0 0 1 + c t1' 2 0 0 1) / 2
205 t0 = tetrahedron0 (face0 cube)
206 t1 = tetrahedron1 (face0 cube)
207 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
208 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
211 -- | Given in Sorokina and Zeilfelder, p. 79.
212 prop_c0102_identity1 :: Cube -> Bool
213 prop_c0102_identity1 cube =
214 c t0' 0 1 0 2 ~= (c t0' 0 0 1 2 + c t3' 0 0 1 2) / 2
216 t0 = tetrahedron0 (face0 cube)
217 t3 = tetrahedron3 (face0 cube)
218 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
219 t3' = Tetrahedron cube (v3 t3) (v2 t3) (v1 t3) (v0 t3)
222 -- | Given in Sorokina and Zeilfelder, p. 79.
223 prop_c0201_identity1 :: Cube -> Bool
224 prop_c0201_identity1 cube =
225 c t0' 0 2 0 1 ~= (c t0' 0 1 1 1 + c t3' 0 1 1 1) / 2
227 t0 = tetrahedron0 (face0 cube)
228 t3 = tetrahedron3 (face0 cube)
229 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
230 t3' = Tetrahedron cube (v3 t3) (v2 t3) (v1 t3) (v0 t3)
233 -- | Given in Sorokina and Zeilfelder, p. 79.
234 prop_c0300_identity2 :: Cube -> Bool
235 prop_c0300_identity2 cube =
236 c t0' 3 0 0 0 ~= (c t0' 0 2 1 0 + c t3' 0 2 1 0) / 2
238 t0 = tetrahedron0 (face0 cube)
239 t3 = tetrahedron3 (face0 cube)
240 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
241 t3' = Tetrahedron cube (v3 t3) (v2 t3) (v1 t3) (v0 t3)
243 -- | Given in Sorokina and Zeilfelder, p. 79.
244 prop_c1101_identity :: Cube -> Bool
245 prop_c1101_identity cube =
246 c t0' 1 1 0 1 ~= (c t0' 1 1 0 1 + c t3' 1 1 0 1) / 2
248 t0 = tetrahedron0 (face0 cube)
249 t3 = tetrahedron3 (face0 cube)
250 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
251 t3' = Tetrahedron cube (v3 t3) (v2 t3) (v1 t3) (v0 t3)
254 -- | Given in Sorokina and Zeilfelder, p. 79.
255 prop_c1200_identity2 :: Cube -> Bool
256 prop_c1200_identity2 cube =
257 c t0' 1 1 1 0 ~= (c t0' 1 1 1 0 + c t3' 1 1 1 0) / 2
259 t0 = tetrahedron0 (face0 cube)
260 t3 = tetrahedron3 (face0 cube)
261 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
262 t3' = Tetrahedron cube (v3 t3) (v2 t3) (v1 t3) (v0 t3)
265 -- | Given in Sorokina and Zeilfelder, p. 79.
266 prop_c2100_identity2 :: Cube -> Bool
267 prop_c2100_identity2 cube =
268 c t0' 2 1 0 0 ~= (c t0' 2 0 1 0 + c t3' 2 0 1 0) / 2
270 t0 = tetrahedron0 (face0 cube)
271 t3 = tetrahedron3 (face0 cube)
272 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
273 t3' = Tetrahedron cube (v3 t3) (v2 t3) (v1 t3) (v0 t3)
276 -- | Given in Sorokina and Zeilfelder, p. 79.
277 prop_c3000_identity :: Cube -> Bool
278 prop_c3000_identity cube =
279 c t0' 3 0 0 0 ~= c t0' 2 1 0 0 + c t2' 2 1 0 0 - ((c t0' 2 0 1 0 + c t0' 2 0 0 1)/ 2)
281 t0 = tetrahedron0 (face0 cube)
282 t2 = tetrahedron2 (face5 cube)
283 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
284 t2' = Tetrahedron cube (v3 t2) (v2 t2) (v1 t2) (v0 t2)
287 -- | Given in Sorokina and Zeilfelder, p. 79.
288 prop_c2010_identity :: Cube -> Bool
289 prop_c2010_identity cube =
290 c t0' 2 0 1 0 ~= c t0' 1 1 1 0 + c t2' 1 1 1 0 - ((c t0' 1 0 2 0 + c t0' 1 0 1 1)/ 2)
292 t0 = tetrahedron0 (face0 cube)
293 t2 = tetrahedron2 (face5 cube)
294 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
295 t2' = Tetrahedron cube (v3 t2) (v2 t2) (v1 t2) (v0 t2)
298 -- | Given in Sorokina and Zeilfelder, p. 79.
299 prop_c2001_identity :: Cube -> Bool
300 prop_c2001_identity cube =
301 c t0' 2 0 0 1 ~= c t0' 1 1 0 1 + c t2' 1 1 0 1 - ((c t0' 1 0 0 2 + c t0' 1 0 1 1)/ 2)
303 t0 = tetrahedron0 (face0 cube)
304 t2 = tetrahedron2 (face5 cube)
305 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
306 t2' = Tetrahedron cube (v3 t2) (v2 t2) (v1 t2) (v0 t2)
308 -- | Given in Sorokina and Zeilfelder, p. 79.
309 prop_c1020_identity :: Cube -> Bool
310 prop_c1020_identity cube =
311 c t0' 1 0 2 0 ~= c t0' 0 1 2 0 + c t2' 0 1 2 0 - ((c t0' 0 0 3 0 + c t0' 0 0 2 1)/ 2)
313 t0 = tetrahedron0 (face0 cube)
314 t2 = tetrahedron2 (face5 cube)
315 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
316 t2' = Tetrahedron cube (v3 t2) (v2 t2) (v1 t2) (v0 t2)
319 -- | Given in Sorokina and Zeilfelder, p. 79.
320 prop_c1002_identity :: Cube -> Bool
321 prop_c1002_identity cube =
322 c t0' 1 0 0 2 ~= c t0' 0 1 0 2 + c t2' 0 1 0 2 - ((c t0' 0 0 0 3 + c t0' 0 0 1 2)/ 2)
324 t0 = tetrahedron0 (face0 cube)
325 t2 = tetrahedron2 (face5 cube)
326 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
327 t2' = Tetrahedron cube (v3 t2) (v2 t2) (v1 t2) (v0 t2)
330 -- | Given in Sorokina and Zeilfelder, p. 79.
331 prop_c1011_identity :: Cube -> Bool
332 prop_c1011_identity cube =
333 c t0' 1 0 1 1 ~= c t0' 0 1 1 1 + c t2' 0 1 1 1 - ((c t0' 0 0 1 2 + c t0' 0 0 2 1)/ 2)
335 t0 = tetrahedron0 (face0 cube)
336 t2 = tetrahedron2 (face5 cube)
337 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
338 t2' = Tetrahedron cube (v3 t2) (v2 t2) (v1 t2) (v0 t2)
341 -- | Given in Sorokina and Zeilfelder, p. 80.
342 prop_c0120_identity2 :: Cube -> Bool
343 prop_c0120_identity2 cube =
344 c t0' 0 1 2 0 ~= (c t0' 1 0 2 0 + c t1' 1 0 2 0) / 2
346 t0 = tetrahedron0 (face0 cube)
347 t1 = tetrahedron0 (face2 (top cube))
348 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
349 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
352 -- | Given in Sorokina and Zeilfelder, p. 80.
353 prop_c0102_identity2 :: Cube -> Bool
354 prop_c0102_identity2 cube =
355 c t0' 0 1 0 2 ~= (c t0' 1 0 0 2 + c t1' 1 0 0 2) / 2
357 t0 = tetrahedron0 (face0 cube)
358 t1 = tetrahedron0 (face2 (top cube))
359 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
360 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
363 -- | Given in Sorokina and Zeilfelder, p. 80.
364 prop_c0111_identity :: Cube -> Bool
365 prop_c0111_identity cube =
366 c t0' 0 1 1 1 ~= (c t0' 1 0 1 1 + c t1' 1 0 1 1) / 2
368 t0 = tetrahedron0 (face0 cube)
369 t1 = tetrahedron0 (face2 (top cube))
370 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
371 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
374 -- | Given in Sorokina and Zeilfelder, p. 80.
375 prop_c0210_identity2 :: Cube -> Bool
376 prop_c0210_identity2 cube =
377 c t0 0 2 1 0 ~= (c t0 1 1 1 0 + c t1 1 1 1 0) / 2
379 t0 = tetrahedron0 (face0 cube)
380 t1 = tetrahedron0 (face2 (top cube))
381 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
382 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
385 -- | Given in Sorokina and Zeilfelder, p. 80.
386 prop_c0201_identity2 :: Cube -> Bool
387 prop_c0201_identity2 cube =
388 c t0 0 2 0 1 ~= (c t0 1 1 0 1 + c t1 1 1 0 1) / 2
390 t0 = tetrahedron0 (face0 cube)
391 t1 = tetrahedron0 (face2 (top cube))
392 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
393 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)
396 -- | Given in Sorokina and Zeilfelder, p. 80.
397 prop_c0300_identity3 :: Cube -> Bool
398 prop_c0300_identity3 cube =
399 c t0 0 3 0 0 ~= (c t0 1 2 0 0 + c t1 1 2 0 0) / 2
401 t0 = tetrahedron0 (face0 cube)
402 t1 = tetrahedron0 (face2 (top cube))
403 t0' = Tetrahedron cube (v3 t0) (v2 t0) (v1 t0) (v0 t0)
404 t1' = Tetrahedron cube (v3 t1) (v2 t1) (v0 t1) (v1 t1)