From 915d84a7ea8b958c38dd28098af4969c2e40bdac Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Sun, 28 Aug 2022 12:28:19 -0400 Subject: [PATCH 01/11] spline3.cabal: update to v1.0.1. --- spline3.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spline3.cabal b/spline3.cabal index 41de985..e49fe39 100644 --- a/spline3.cabal +++ b/spline3.cabal @@ -1,6 +1,6 @@ cabal-version: 3.0 name: spline3 -version: 1.0.0 +version: 1.0.1 author: Michael Orlitzky maintainer: Michael Orlitzky homepage: http://michael.orlitzky.com/code/spline3.xhtml -- 2.43.2 From d47fe5a8e167d8bdc0b4edf2899eee351615ccf8 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 25 Apr 2024 18:50:24 -0400 Subject: [PATCH 02/11] makefile: disable -Wmissing-kind-signatures This needs a GHC extension to fix it. --- makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/makefile b/makefile index 12779b2..9fdfc33 100644 --- a/makefile +++ b/makefile @@ -17,6 +17,7 @@ HCFLAGS += -Weverything \ -Wno-prepositive-qualified-module \ -Wno-missing-safe-haskell-mode \ -Wno-missing-deriving-strategies \ + -Wno-missing-kind-signatures \ -rtsopts \ -threaded -- 2.43.2 From 0696fc4f3e428d2156f0be4ca40728abf2e35abe Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 25 Apr 2024 19:03:11 -0400 Subject: [PATCH 03/11] src/*.hs: fix all -Woperator-whitespace warnings This is stupid. --- src/Cardinal.hs | 28 ++++----- src/Cube.hs | 80 ++++++++++++------------ src/Examples.hs | 2 +- src/Face.hs | 2 +- src/FunctionValues.hs | 52 ++++++++-------- src/Grid.hs | 48 +++++++-------- src/Point.hs | 4 +- src/RealFunction.hs | 2 +- src/Tetrahedron.hs | 140 +++++++++++++++++++++--------------------- src/Volumetric.hs | 2 +- 10 files changed, 180 insertions(+), 180 deletions(-) diff --git a/src/Cardinal.hs b/src/Cardinal.hs index 74a729f..d3a76b6 100644 --- a/src/Cardinal.hs +++ b/src/Cardinal.hs @@ -270,22 +270,22 @@ test_c_tilde_2100_rotation_correct = assertEqual "auto-rotate equals manual rotate" ((ccwz . ccwz . cwy) expr1) expr2 where expr1 = - (3/8)*I + - (1/12)*(T + R + L + D) + - (1/64)*(FT + FR + FL + FD) + - (7/48)*F + - (1/48)*B + - (1/96)*(RT + LD + LT + RD) + - (1/192)*(BT + BR + BL + BD) + (3 / 8)*I + + (1 / 12)*(T + R + L + D) + + (1 / 64)*(FT + FR + FL + FD) + + (7 / 48)*F + + (1 / 48)*B + + (1 / 96)*(RT + LD + LT + RD) + + (1 / 192)*(BT + BR + BL + BD) expr2 = - (3/8)*I + - (1/12)*(F + L + R + B) + - (1/64)*(FT + LT + RT + BT) + - (7/48)*T + - (1/48)*D + - (1/96)*(FL + BR + FR + BL) + - (1/192)*(FD + LD + RD + BD) + (3 / 8)*I + + (1 / 12)*(F + L + R + B) + + (1 / 64)*(FT + LT + RT + BT) + + (7 / 48)*T + + (1 / 48)*D + + (1 / 96)*(FL + BR + FR + BL) + + (1 / 192)*(FD + LD + RD + BD) -- | A list of all directions, sans the interior and composite types. all_directions :: [Cardinal] diff --git a/src/Cube.hs b/src/Cube.hs index 4992851..026f4e9 100644 --- a/src/Cube.hs +++ b/src/Cube.hs @@ -113,42 +113,42 @@ instance Show Cube where -- | The left-side boundary of the cube. See Sorokina and Zeilfelder, -- p. 76. xmin :: Cube -> Double -xmin cube = (i' - 1/2) +xmin cube = (i' - 1 / 2) where i' = fromIntegral (i cube) :: Double -- | The right-side boundary of the cube. See Sorokina and Zeilfelder, -- p. 76. xmax :: Cube -> Double -xmax cube = (i' + 1/2) +xmax cube = (i' + 1 / 2) where i' = fromIntegral (i cube) :: Double -- | The front boundary of the cube. See Sorokina and Zeilfelder, -- p. 76. ymin :: Cube -> Double -ymin cube = (j' - 1/2) +ymin cube = (j' - 1 / 2) where j' = fromIntegral (j cube) :: Double -- | The back boundary of the cube. See Sorokina and Zeilfelder, -- p. 76. ymax :: Cube -> Double -ymax cube = (j' + 1/2) +ymax cube = (j' + 1 / 2) where j' = fromIntegral (j cube) :: Double -- | The bottom boundary of the cube. See Sorokina and Zeilfelder, -- p. 76. zmin :: Cube -> Double -zmin cube = (k' - 1/2) +zmin cube = (k' - 1 / 2) where k' = fromIntegral (k cube) :: Double -- | The top boundary of the cube. See Sorokina and Zeilfelder, -- p. 76. zmax :: Cube -> Double -zmax cube = (k' + 1/2) +zmax cube = (k' + 1 / 2) where k' = fromIntegral (k cube) :: Double @@ -170,7 +170,7 @@ center cube = top_face :: Cube -> Face.Face top_face cube = Face.Face v0' v1' v2' v3' where - delta = (1/2) :: Double + delta = (1 / 2) :: Double cc = center cube v0' = cc + ( Point delta (-delta) delta ) v1' = cc + ( Point delta delta delta ) @@ -183,7 +183,7 @@ top_face cube = Face.Face v0' v1' v2' v3' back_face :: Cube -> Face.Face back_face cube = Face.Face v0' v1' v2' v3' where - delta = (1/2) :: Double + delta = (1 / 2) :: Double cc = center cube v0' = cc + ( Point delta (-delta) (-delta) ) v1' = cc + ( Point delta delta (-delta) ) @@ -195,7 +195,7 @@ back_face cube = Face.Face v0' v1' v2' v3' down_face :: Cube -> Face.Face down_face cube = Face.Face v0' v1' v2' v3' where - delta = (1/2) :: Double + delta = (1 / 2) :: Double cc = center cube v0' = cc + ( Point (-delta) (-delta) (-delta) ) v1' = cc + ( Point (-delta) delta (-delta) ) @@ -208,7 +208,7 @@ down_face cube = Face.Face v0' v1' v2' v3' front_face :: Cube -> Face.Face front_face cube = Face.Face v0' v1' v2' v3' where - delta = (1/2) :: Double + delta = (1 / 2) :: Double cc = center cube v0' = cc + ( Point (-delta) (-delta) delta ) v1' = cc + ( Point (-delta) delta delta ) @@ -219,7 +219,7 @@ front_face cube = Face.Face v0' v1' v2' v3' left_face :: Cube -> Face.Face left_face cube = Face.Face v0' v1' v2' v3' where - delta = (1/2) :: Double + delta = (1 / 2) :: Double cc = center cube v0' = cc + ( Point delta (-delta) delta ) v1' = cc + ( Point (-delta) (-delta) delta ) @@ -231,7 +231,7 @@ left_face cube = Face.Face v0' v1' v2' v3' right_face :: Cube -> Face.Face right_face cube = Face.Face v0' v1' v2' v3' where - delta = (1/2) :: Double + delta = (1 / 2) :: Double cc = center cube v0' = cc + ( Point (-delta) delta delta) v1' = cc + ( Point delta delta delta ) @@ -735,7 +735,7 @@ prop_all_volumes_positive cube = -- we'd expect the volume of each one to be 1/24. prop_all_volumes_exact :: Cube -> Bool prop_all_volumes_exact cube = - and [volume t ~~= 1/24 | t <- tetrahedra cube] + and [volume t ~~= 1 / 24 | t <- tetrahedra cube] -- | All tetrahedron should have their v0 located at the center of the -- cube. @@ -940,7 +940,7 @@ prop_c2100_identity2 cube = prop_c3000_identity :: Cube -> Bool prop_c3000_identity cube = c t0 3 0 0 0 ~= c t0 2 1 0 0 + c t6 2 1 0 0 - - ((c t0 2 0 1 0 + c t0 2 0 0 1)/ 2) + - ((c t0 2 0 1 0 + c t0 2 0 0 1) / 2) where t0 = tetrahedron cube 0 t6 = tetrahedron cube 6 @@ -951,7 +951,7 @@ prop_c3000_identity cube = prop_c2010_identity :: Cube -> Bool prop_c2010_identity cube = c t0 2 0 1 0 ~= c t0 1 1 1 0 + c t6 1 1 0 1 - - ((c t0 1 0 2 0 + c t0 1 0 1 1)/ 2) + - ((c t0 1 0 2 0 + c t0 1 0 1 1) / 2) where t0 = tetrahedron cube 0 t6 = tetrahedron cube 6 @@ -962,7 +962,7 @@ prop_c2010_identity cube = prop_c2001_identity :: Cube -> Bool prop_c2001_identity cube = c t0 2 0 0 1 ~= c t0 1 1 0 1 + c t6 1 1 1 0 - - ((c t0 1 0 0 2 + c t0 1 0 1 1)/ 2) + - ((c t0 1 0 0 2 + c t0 1 0 1 1) / 2) where t0 = tetrahedron cube 0 t6 = tetrahedron cube 6 @@ -973,7 +973,7 @@ prop_c2001_identity cube = prop_c1020_identity :: Cube -> Bool prop_c1020_identity cube = c t0 1 0 2 0 ~= c t0 0 1 2 0 + c t6 0 1 0 2 - - ((c t0 0 0 3 0 + c t0 0 0 2 1)/ 2) + - ((c t0 0 0 3 0 + c t0 0 0 2 1) / 2) where t0 = tetrahedron cube 0 t6 = tetrahedron cube 6 @@ -984,7 +984,7 @@ prop_c1020_identity cube = prop_c1002_identity :: Cube -> Bool prop_c1002_identity cube = c t0 1 0 0 2 ~= c t0 0 1 0 2 + c t6 0 1 2 0 - - ((c t0 0 0 0 3 + c t0 0 0 1 2)/ 2) + - ((c t0 0 0 0 3 + c t0 0 0 1 2) / 2) where t0 = tetrahedron cube 0 t6 = tetrahedron cube 6 @@ -995,7 +995,7 @@ prop_c1002_identity cube = prop_c1011_identity :: Cube -> Bool prop_c1011_identity cube = c t0 1 0 1 1 ~= c t0 0 1 1 1 + c t6 0 1 1 1 - - ((c t0 0 0 1 2 + c t0 0 0 2 1)/ 2) + ((c t0 0 0 1 2 + c t0 0 0 2 1) / 2) where t0 = tetrahedron cube 0 t6 = tetrahedron cube 6 @@ -1019,23 +1019,23 @@ prop_c_tilde_2100_rotation_correct cube = -- What gets computed for c2100 of t6. expr1 = eval (function_values t6) $ - (3/8)*I + - (1/12)*(T + R + L + D) + - (1/64)*(FT + FR + FL + FD) + - (7/48)*F + - (1/48)*B + - (1/96)*(RT + LD + LT + RD) + - (1/192)*(BT + BR + BL + BD) + (3 / 8)*I + + (1 / 12)*(T + R + L + D) + + (1 / 64)*(FT + FR + FL + FD) + + (7 / 48)*F + + (1 / 48)*B + + (1 / 96)*(RT + LD + LT + RD) + + (1 / 192)*(BT + BR + BL + BD) -- What should be computed for c2100 of t6. expr2 = eval (function_values t0) $ - (3/8)*I + - (1/12)*(F + R + L + B) + - (1/64)*(FT + RT + LT + BT) + - (7/48)*T + - (1/48)*D + - (1/96)*(FR + FL + BR + BL) + - (1/192)*(FD + RD + LD + BD) + (3 / 8)*I + + (1 / 12)*(F + R + L + B) + + (1 / 64)*(FT + RT + LT + BT) + + (7 / 48)*T + + (1 / 48)*D + + (1 / 96)*(FR + FL + BR + BL) + + (1 / 192)*(FD + RD + LD + BD) -- | We know what (c t6 2 1 0 0) should be from Sorokina and @@ -1052,13 +1052,13 @@ prop_c_tilde_2100_correct cube = t6 = tetrahedron cube 6 fvs = function_values t0 expected = eval fvs $ - (3/8)*I + - (1/12)*(F + R + L + B) + - (1/64)*(FT + RT + LT + BT) + - (7/48)*T + - (1/48)*D + - (1/96)*(FR + FL + BR + BL) + - (1/192)*(FD + RD + LD + BD) + (3 / 8)*I + + (1 / 12)*(F + R + L + B) + + (1 / 64)*(FT + RT + LT + BT) + + (7 / 48)*T + + (1 / 48)*D + + (1 / 96)*(FR + FL + BR + BL) + + (1 / 192)*(FD + RD + LD + BD) -- Tests to check that the correct edges are incidental. diff --git a/src/Examples.hs b/src/Examples.hs index 350829a..93a7cbf 100644 --- a/src/Examples.hs +++ b/src/Examples.hs @@ -46,7 +46,7 @@ trilinear = fromListUnboxed (n_cube 3) $ -- points (hi, hj, jk) with h = 0.5. We should be able to reproduce -- this from splines based on the 3x3x3 trilinear. trilinear_zoom_2_list :: [[[Double]]] -trilinear_zoom_2_list = [[[1, 3/2, 2, 5/2, 3], [1, 7/4, 5/2, 13/4, 4], [1, 2, 3, 4, 5], [1, 9/4, 7/2, 19/4, 6], [1, 5/2, 4, 11/2, 7]], [[1, 3/2, 2, 5/2, 3], [1, 15/8, 11/4, 29/8, 9/2], [1, 9/4, 7/2, 19/4, 6], [1, 21/8, 17/4, 47/8, 15/2], [1, 3, 5, 7, 9]], [[1, 3/2, 2, 5/2, 3], [1, 2, 3, 4, 5], [1, 5/2, 4, 11/2, 7], [1, 3, 5, 7, 9], [1, 7/2, 6, 17/2, 11]], [[1, 3/2, 2, 5/2, 3], [1, 17/8, 13/4, 35/8, 11/2], [1, 11/4, 9/2, 25/4, 8], [1, 27/8, 23/4, 65/8, 21/2], [1, 4, 7, 10, 13]], [[1, 3/2, 2, 5/2, 3], [1, 9/4, 7/2, 19/4, 6], [1, 3, 5, 7, 9], [1, 15/4, 13/2, 37/4, 12], [1, 9/2, 8, 23/2, 15]]] +trilinear_zoom_2_list = [[[1, 3 / 2, 2, 5 / 2, 3], [1, 7 / 4, 5 / 2, 13 / 4, 4], [1, 2, 3, 4, 5], [1, 9 / 4, 7 / 2, 19 / 4, 6], [1, 5 / 2, 4, 11 / 2, 7]], [[1, 3 / 2, 2, 5 / 2, 3], [1, 15 / 8, 11 / 4, 29 / 8, 9 / 2], [1, 9 / 4, 7 / 2, 19 / 4, 6], [1, 21 / 8, 17 / 4, 47 / 8, 15 / 2], [1, 3, 5, 7, 9]], [[1, 3 / 2, 2, 5 / 2, 3], [1, 2, 3, 4, 5], [1, 5 / 2, 4, 11 / 2, 7], [1, 3, 5, 7, 9], [1, 7 / 2, 6, 17 / 2, 11]], [[1, 3 / 2, 2, 5 / 2, 3], [1, 17 / 8, 13 / 4, 35 / 8, 11 / 2], [1, 11 / 4, 9 / 2, 25 / 4, 8], [1, 27 / 8, 23 / 4, 65 / 8, 21 / 2], [1, 4, 7, 10, 13]], [[1, 3 / 2, 2, 5 / 2, 3], [1, 9 / 4, 7 / 2, 19 / 4, 6], [1, 3, 5, 7, 9], [1, 15 / 4, 13 / 2, 37 / 4, 12], [1, 9 / 2, 8, 23 / 2, 15]]] trilinear_zoom_2 :: Values3D trilinear_zoom_2 = fromListUnboxed (n_cube 6) $ diff --git a/src/Face.hs b/src/Face.hs index de24a43..ce4a5d5 100644 --- a/src/Face.hs +++ b/src/Face.hs @@ -28,4 +28,4 @@ instance Show Face where -- tetrahedron. center :: Face -> Point center (Face v0' v1' v2' v3') = - (v0' + v1' + v2' + v3') `scale` (1/4) + (v0' + v1' + v2' + v3') `scale` (1 / 4) diff --git a/src/FunctionValues.hs b/src/FunctionValues.hs index 62b861c..bc14146 100644 --- a/src/FunctionValues.hs +++ b/src/FunctionValues.hs @@ -290,32 +290,32 @@ value_at v3d !i !j !k -- object centered at (i,j,k) make_values :: Values3D -> Int -> Int -> Int -> FunctionValues make_values values !i !j !k = - empty_values { front = value_at values (i-1) j k, - back = value_at values (i+1) j k, - left = value_at values i (j-1) k, - right = value_at values i (j+1) k, - down = value_at values i j (k-1), - top = value_at values i j (k+1), - front_left = value_at values (i-1) (j-1) k, - front_right = value_at values (i-1) (j+1) k, - front_down =value_at values (i-1) j (k-1), - front_top = value_at values (i-1) j (k+1), - back_left = value_at values (i+1) (j-1) k, - back_right = value_at values (i+1) (j+1) k, - back_down = value_at values (i+1) j (k-1), - back_top = value_at values (i+1) j (k+1), - left_down = value_at values i (j-1) (k-1), - left_top = value_at values i (j-1) (k+1), - right_down = value_at values i (j+1) (k-1), - right_top = value_at values i (j+1) (k+1), - front_left_down = value_at values (i-1) (j-1) (k-1), - front_left_top = value_at values (i-1) (j-1) (k+1), - front_right_down = value_at values (i-1) (j+1) (k-1), - front_right_top = value_at values (i-1) (j+1) (k+1), - back_left_down = value_at values (i+1) (j-1) (k-1), - back_left_top = value_at values (i+1) (j-1) (k+1), - back_right_down = value_at values (i+1) (j+1) (k-1), - back_right_top = value_at values (i+1) (j+1) (k+1), + empty_values { front = value_at values (i - 1) j k, + back = value_at values (i + 1) j k, + left = value_at values i (j - 1) k, + right = value_at values i (j + 1) k, + down = value_at values i j (k - 1), + top = value_at values i j (k + 1), + front_left = value_at values (i - 1) (j - 1) k, + front_right = value_at values (i - 1) (j + 1) k, + front_down =value_at values (i - 1) j (k - 1), + front_top = value_at values (i - 1) j (k + 1), + back_left = value_at values (i + 1) (j - 1) k, + back_right = value_at values (i + 1) (j + 1) k, + back_down = value_at values (i + 1) j (k - 1), + back_top = value_at values (i + 1) j (k + 1), + left_down = value_at values i (j - 1) (k - 1), + left_top = value_at values i (j - 1) (k + 1), + right_down = value_at values i (j + 1) (k - 1), + right_top = value_at values i (j + 1) (k + 1), + front_left_down = value_at values (i - 1) (j - 1) (k - 1), + front_left_top = value_at values (i - 1) (j - 1) (k + 1), + front_right_down = value_at values (i - 1) (j + 1) (k - 1), + front_right_top = value_at values (i - 1) (j + 1) (k + 1), + back_left_down = value_at values (i + 1) (j - 1) (k - 1), + back_left_top = value_at values (i + 1) (j - 1) (k + 1), + back_right_down = value_at values (i + 1) (j + 1) (k - 1), + back_right_top = value_at values (i + 1) (j + 1) (k + 1), interior = value_at values i j k } -- | Takes a 'FunctionValues' and a function that transforms one diff --git a/src/Grid.hs b/src/Grid.hs index 43e60ef..d98bda1 100644 --- a/src/Grid.hs +++ b/src/Grid.hs @@ -77,7 +77,7 @@ cube_at !g !i !j !k = where fvs = function_values g fvs' = make_values fvs i j k - tet_vol = (1/24) :: Double + tet_vol = (1 / 24) :: Double -- The first cube along any axis covers (-1/2, 1/2). The second @@ -96,7 +96,7 @@ calculate_containing_cube_coordinate g coord | otherwise = (ceiling (coord + offset)) - 1 where (xsize, ysize, zsize) = dims (function_values g) - offset = (1/2) :: Double + offset = (1 / 2) :: Double -- | Takes a 'Grid', and returns a 'Cube' containing the given 'Point'. @@ -121,7 +121,7 @@ zoom_result v3d (sfx, sfy, sfz) (Z :. m :. n :. o) = f p where g = Grid v3d - offset = (1/2) :: Double + offset = (1 / 2) :: Double m' = (fromIntegral m) / (fromIntegral sfx) - offset n' = (fromIntegral n) / (fromIntegral sfy) - offset o' = (fromIntegral o) / (fromIntegral sfz) - offset @@ -191,63 +191,63 @@ trilinear_c0_t0_tests = test_trilinear_c0030 :: Assertion test_trilinear_c0030 = - assertAlmostEqual "c0030 is correct" (c t 0 0 3 0) (17/8) + assertAlmostEqual "c0030 is correct" (c t 0 0 3 0) (17 / 8) test_trilinear_c0003 :: Assertion test_trilinear_c0003 = - assertAlmostEqual "c0003 is correct" (c t 0 0 0 3) (27/8) + assertAlmostEqual "c0003 is correct" (c t 0 0 0 3) (27 / 8) test_trilinear_c0021 :: Assertion test_trilinear_c0021 = - assertAlmostEqual "c0021 is correct" (c t 0 0 2 1) (61/24) + assertAlmostEqual "c0021 is correct" (c t 0 0 2 1) (61 / 24) test_trilinear_c0012 :: Assertion test_trilinear_c0012 = - assertAlmostEqual "c0012 is correct" (c t 0 0 1 2) (71/24) + assertAlmostEqual "c0012 is correct" (c t 0 0 1 2) (71 / 24) test_trilinear_c0120 :: Assertion test_trilinear_c0120 = - assertAlmostEqual "c0120 is correct" (c t 0 1 2 0) (55/24) + assertAlmostEqual "c0120 is correct" (c t 0 1 2 0) (55 / 24) test_trilinear_c0102 :: Assertion test_trilinear_c0102 = - assertAlmostEqual "c0102 is correct" (c t 0 1 0 2) (73/24) + assertAlmostEqual "c0102 is correct" (c t 0 1 0 2) (73 / 24) test_trilinear_c0111 :: Assertion test_trilinear_c0111 = - assertAlmostEqual "c0111 is correct" (c t 0 1 1 1) (8/3) + assertAlmostEqual "c0111 is correct" (c t 0 1 1 1) (8 / 3) test_trilinear_c0210 :: Assertion test_trilinear_c0210 = - assertAlmostEqual "c0210 is correct" (c t 0 2 1 0) (29/12) + assertAlmostEqual "c0210 is correct" (c t 0 2 1 0) (29 / 12) test_trilinear_c0201 :: Assertion test_trilinear_c0201 = - assertAlmostEqual "c0201 is correct" (c t 0 2 0 1) (11/4) + assertAlmostEqual "c0201 is correct" (c t 0 2 0 1) (11 / 4) test_trilinear_c0300 :: Assertion test_trilinear_c0300 = - assertAlmostEqual "c0300 is correct" (c t 0 3 0 0) (5/2) + assertAlmostEqual "c0300 is correct" (c t 0 3 0 0) (5 / 2) test_trilinear_c1020 :: Assertion test_trilinear_c1020 = - assertAlmostEqual "c1020 is correct" (c t 1 0 2 0) (8/3) + assertAlmostEqual "c1020 is correct" (c t 1 0 2 0) (8 / 3) test_trilinear_c1002 :: Assertion test_trilinear_c1002 = - assertAlmostEqual "c1002 is correct" (c t 1 0 0 2) (23/6) + assertAlmostEqual "c1002 is correct" (c t 1 0 0 2) (23 / 6) test_trilinear_c1011 :: Assertion test_trilinear_c1011 = - assertAlmostEqual "c1011 is correct" (c t 1 0 1 1) (13/4) + assertAlmostEqual "c1011 is correct" (c t 1 0 1 1) (13 / 4) test_trilinear_c1110 :: Assertion test_trilinear_c1110 = - assertAlmostEqual "c1110 is correct" (c t 1 1 1 0) (23/8) + assertAlmostEqual "c1110 is correct" (c t 1 1 1 0) (23 / 8) test_trilinear_c1101 :: Assertion test_trilinear_c1101 = - assertAlmostEqual "c1101 is correct" (c t 1 1 0 1) (27/8) + assertAlmostEqual "c1101 is correct" (c t 1 1 0 1) (27 / 8) test_trilinear_c1200 :: Assertion test_trilinear_c1200 = @@ -255,7 +255,7 @@ trilinear_c0_t0_tests = test_trilinear_c2010 :: Assertion test_trilinear_c2010 = - assertAlmostEqual "c2010 is correct" (c t 2 0 1 0) (10/3) + assertAlmostEqual "c2010 is correct" (c t 2 0 1 0) (10 / 3) test_trilinear_c2001 :: Assertion test_trilinear_c2001 = @@ -263,7 +263,7 @@ trilinear_c0_t0_tests = test_trilinear_c2100 :: Assertion test_trilinear_c2100 = - assertAlmostEqual "c2100 is correct" (c t 2 1 0 0) (7/2) + assertAlmostEqual "c2100 is correct" (c t 2 1 0 0) (7 / 2) test_trilinear_c3000 :: Assertion test_trilinear_c3000 = @@ -344,12 +344,12 @@ test_trilinear9x9x9_reproduced = prop_cube_indices_never_go_out_of_bounds :: Grid -> Gen Bool prop_cube_indices_never_go_out_of_bounds g = do - let coordmin = negate (1/2) :: Double + let coordmin = negate (1 / 2) :: Double let (xsize, ysize, zsize) = dims $ function_values g - let xmax = (fromIntegral xsize) - (1/2) :: Double - let ymax = (fromIntegral ysize) - (1/2) :: Double - let zmax = (fromIntegral zsize) - (1/2) :: Double + let xmax = (fromIntegral xsize) - (1 / 2) :: Double + let ymax = (fromIntegral ysize) - (1 / 2) :: Double + let zmax = (fromIntegral zsize) - (1 / 2) :: Double x <- choose (coordmin, xmax) y <- choose (coordmin, ymax) diff --git a/src/Point.hs b/src/Point.hs index 004b2e4..d8b8dd8 100644 --- a/src/Point.hs +++ b/src/Point.hs @@ -24,7 +24,7 @@ instance Arbitrary Point where instance Num Point where - (Point x1 y1 z1) + (Point x2 y2 z2) = Point (x1+x2) (y1+y2) (z1+z2) + (Point x1 y1 z1) + (Point x2 y2 z2) = Point (x1 + x2) (y1 + y2) (z1 + z2) (Point x1 y1 z1) - (Point x2 y2 z2) = Point (x1-x2) (y1-y2) (z1-z2) (Point x1 y1 z1) * (Point x2 y2 z2) = Point (x1*x2) (y1*y2) (z1*z2) abs (Point x y z) = Point (abs x) (abs y) (abs z) @@ -44,4 +44,4 @@ scale (Point x y z) d = Point (x*d) (y*d) (z*d) {-# INLINE dot #-} dot :: Point -> Point -> Double dot (Point x1 y1 z1) (Point x2 y2 z2) = - (x2 - x1)^(2::Int) + (y2 - y1)^(2::Int) + (z2 - z1)^(2::Int) + (x2 - x1) ^ (2::Int) + (y2 - y1) ^ (2::Int) + (z2 - z1) ^ (2::Int) diff --git a/src/RealFunction.hs b/src/RealFunction.hs index 37babf6..f6d0482 100644 --- a/src/RealFunction.hs +++ b/src/RealFunction.hs @@ -74,4 +74,4 @@ cmult coeff f = (*coeff) . f fexp :: (RealFunction a) -> Int -> (RealFunction a) fexp f n | n == 0 = const 1 - | otherwise = \x -> (f x)^n + | otherwise = \x -> (f x) ^ n diff --git a/src/Tetrahedron.hs b/src/Tetrahedron.hs index 87bfd5e..9a3e495 100644 --- a/src/Tetrahedron.hs +++ b/src/Tetrahedron.hs @@ -80,7 +80,7 @@ instance Show Tetrahedron where -- We just average the four vertices. barycenter :: Tetrahedron -> Point barycenter (Tetrahedron _ v0' v1' v2' v3' _) = - (v0' + v1' + v2' + v3') `scale` (1/4) + (v0' + v1' + v2' + v3') `scale` (1 / 4) @@ -160,102 +160,102 @@ c !t !i !j !k !l = coefficient :: Int -> Int -> Int -> Int -> Double coefficient 0 0 3 0 = - (1/8) * (i' + f + l' + t' + lt + fl + ft + flt) + (1 / 8) * (i' + f + l' + t' + lt + fl + ft + flt) coefficient 0 0 0 3 = - (1/8) * (i' + f + r + t' + rt + fr + ft + frt) + (1 / 8) * (i' + f + r + t' + rt + fr + ft + frt) coefficient 0 0 2 1 = - (5/24)*(i' + f + t' + ft) + (1/24)*(l' + fl + lt + flt) + (5 / 24)*(i' + f + t' + ft) + (1 / 24)*(l' + fl + lt + flt) coefficient 0 0 1 2 = - (5/24)*(i' + f + t' + ft) + (1/24)*(r + fr + rt + frt) + (5 / 24)*(i' + f + t' + ft) + (1 / 24)*(r + fr + rt + frt) coefficient 0 1 2 0 = - (5/24)*(i' + f) + (1/8)*(l' + t' + fl + ft) - + (1/24)*(lt + flt) + (5 / 24)*(i' + f) + (1 / 8)*(l' + t' + fl + ft) + + (1 / 24)*(lt + flt) coefficient 0 1 0 2 = - (5/24)*(i' + f) + (1/8)*(r + t' + fr + ft) - + (1/24)*(rt + frt) + (5 / 24)*(i' + f) + (1 / 8)*(r + t' + fr + ft) + + (1 / 24)*(rt + frt) coefficient 0 1 1 1 = - (13/48)*(i' + f) + (7/48)*(t' + ft) - + (1/32)*(l' + r + fl + fr) - + (1/96)*(lt + rt + flt + frt) + (13 / 48)*(i' + f) + (7 / 48)*(t' + ft) + + (1 / 32)*(l' + r + fl + fr) + + (1 / 96)*(lt + rt + flt + frt) coefficient 0 2 1 0 = - (13/48)*(i' + f) + (17/192)*(l' + t' + fl + ft) - + (1/96)*(lt + flt) - + (1/64)*(r + d + fr + fd) - + (1/192)*(rt + ld + frt + fld) + (13 / 48)*(i' + f) + (17 / 192)*(l' + t' + fl + ft) + + (1 / 96)*(lt + flt) + + (1 / 64)*(r + d + fr + fd) + + (1 / 192)*(rt + ld + frt + fld) coefficient 0 2 0 1 = - (13/48)*(i' + f) + (17/192)*(r + t' + fr + ft) - + (1/96)*(rt + frt) - + (1/64)*(l' + d + fl + fd) - + (1/192)*(rd + lt + flt + frd) + (13 / 48)*(i' + f) + (17 / 192)*(r + t' + fr + ft) + + (1 / 96)*(rt + frt) + + (1 / 64)*(l' + d + fl + fd) + + (1 / 192)*(rd + lt + flt + frd) coefficient 0 3 0 0 = - (13/48)*(i' + f) + (5/96)*(l' + r + t' + d + fl + fr + ft + fd) - + (1/192)*(rt + rd + lt + ld + frt + frd + flt + fld) + (13 / 48)*(i' + f) + (5 / 96)*(l' + r + t' + d + fl + fr + ft + fd) + + (1 / 192)*(rt + rd + lt + ld + frt + frd + flt + fld) coefficient 1 0 2 0 = - (1/4)*i' + (1/6)*(f + l' + t') - + (1/12)*(lt + fl + ft) + (1 / 4)*i' + (1 / 6)*(f + l' + t') + + (1 / 12)*(lt + fl + ft) coefficient 1 0 0 2 = - (1/4)*i' + (1/6)*(f + r + t') - + (1/12)*(rt + fr + ft) + (1 / 4)*i' + (1 / 6)*(f + r + t') + + (1 / 12)*(rt + fr + ft) coefficient 1 0 1 1 = - (1/3)*i' + (5/24)*(f + t') - + (1/12)*ft - + (1/24)*(l' + r) - + (1/48)*(lt + rt + fl + fr) + (1 / 3)*i' + (5 / 24)*(f + t') + + (1 / 12)*ft + + (1 / 24)*(l' + r) + + (1 / 48)*(lt + rt + fl + fr) coefficient 1 1 1 0 = - (1/3)*i' + (5/24)*f - + (1/8)*(l' + t') - + (5/96)*(fl + ft) - + (1/48)*(d + r + lt) - + (1/96)*(fd + ld + rt + fr) + (1 / 3)*i' + (5 / 24)*f + + (1 / 8)*(l' + t') + + (5 / 96)*(fl + ft) + + (1 / 48)*(d + r + lt) + + (1 / 96)*(fd + ld + rt + fr) coefficient 1 1 0 1 = - (1/3)*i' + (5/24)*f - + (1/8)*(r + t') - + (5/96)*(fr + ft) - + (1/48)*(d + l' + rt) - + (1/96)*(fd + lt + rd + fl) + (1 / 3)*i' + (5 / 24)*f + + (1 / 8)*(r + t') + + (5 / 96)*(fr + ft) + + (1 / 48)*(d + l' + rt) + + (1 / 96)*(fd + lt + rd + fl) coefficient 1 2 0 0 = - (1/3)*i' + (5/24)*f - + (7/96)*(l' + r + t' + d) - + (1/32)*(fl + fr + ft + fd) - + (1/96)*(rt + rd + lt + ld) + (1 / 3)*i' + (5 / 24)*f + + (7 / 96)*(l' + r + t' + d) + + (1 / 32)*(fl + fr + ft + fd) + + (1 / 96)*(rt + rd + lt + ld) coefficient 2 0 1 0 = - (3/8)*i' + (7/48)*(f + t' + l') - + (1/48)*(r + d + b + lt + fl + ft) - + (1/96)*(rt + bt + fr + fd + ld + bl) + (3 / 8)*i' + (7 / 48)*(f + t' + l') + + (1 / 48)*(r + d + b + lt + fl + ft) + + (1 / 96)*(rt + bt + fr + fd + ld + bl) coefficient 2 0 0 1 = - (3/8)*i' + (7/48)*(f + t' + r) - + (1/48)*(l' + d + b + rt + fr + ft) - + (1/96)*(lt + bt + fl + fd + rd + br) + (3 / 8)*i' + (7 / 48)*(f + t' + r) + + (1 / 48)*(l' + d + b + rt + fr + ft) + + (1 / 96)*(lt + bt + fl + fd + rd + br) coefficient 2 1 0 0 = - (3/8)*i' + (1/12)*(t' + r + l' + d) - + (1/64)*(ft + fr + fl + fd) - + (7/48)*f - + (1/48)*b - + (1/96)*(rt + ld + lt + rd) - + (1/192)*(bt + br + bl + bd) + (3 / 8)*i' + (1 / 12)*(t' + r + l' + d) + + (1 / 64)*(ft + fr + fl + fd) + + (7 / 48)*f + + (1 / 48)*b + + (1 / 96)*(rt + ld + lt + rd) + + (1 / 192)*(bt + br + bl + bd) coefficient 3 0 0 0 = - (3/8)*i' + (1/12)*(t' + f + l' + r + d + b) - + (1/96)*(lt + fl + ft + rt + bt + fr) - + (1/96)*(fd + ld + bd + br + rd + bl) + (3 / 8)*i' + (1 / 12)*(t' + f + l' + r + d + b) + + (1 / 96)*(lt + fl + ft + rt + bt + fr) + + (1 / 96)*(fd + ld + bd + br + rd + bl) @@ -295,7 +295,7 @@ det p0 p1 p2 p3 = {-# INLINE volume #-} volume :: Tetrahedron -> Double volume (Tetrahedron _ v0' v1' v2' v3' _) = - (1/6)*(det v0' v1' v2' v3') + (1 / 6)*(det v0' v1' v2' v3') -- | The barycentric coordinates of a point with respect to v0. {-# INLINE b0 #-} @@ -352,7 +352,7 @@ tetrahedron1_geometry_tests = volume1 :: Assertion volume1 = - assertEqual "volume is correct" True (vol ~= (-1/3)) + assertEqual "volume is correct" True (vol ~= (-1 / 3)) where vol = volume t @@ -377,7 +377,7 @@ tetrahedron2_geometry_tests = precomputed_volume = 0 } volume1 :: Assertion - volume1 = assertEqual "volume1 is correct" True (vol ~= (1/3)) + volume1 = assertEqual "volume1 is correct" True (vol ~= (1 / 3)) where vol = volume t @@ -525,7 +525,7 @@ p78_24_properties = -- | Returns the domain point of t with indices i,j,k,l. domain_point :: Tetrahedron -> Int -> Int -> Int -> Int -> Point domain_point t i j k l = - weighted_sum `scale` (1/3) + weighted_sum `scale` (1 / 3) where v0' = (v0 t) `scale` (fromIntegral i) v1' = (v1 t) `scale` (fromIntegral j) @@ -551,10 +551,10 @@ p78_24_properties = (volume t) > 0 ==> c t 2 1 0 0 ~= (term1 - term2 + term3 - term4) where - term1 = (1/3)*(p t 0 3 0 0) - term2 = (5/6)*(p t 3 0 0 0) + term1 = (1 / 3)*(p t 0 3 0 0) + term2 = (5 / 6)*(p t 3 0 0 0) term3 = 3*(p t 2 1 0 0) - term4 = (3/2)*(p t 1 2 0 0) + term4 = (3 / 2)*(p t 1 2 0 0) -- | Given in Sorokina and Zeilfelder, p. 78. prop_c1110_identity :: Tetrahedron -> Property @@ -562,10 +562,10 @@ p78_24_properties = (volume t) > 0 ==> c t 1 1 1 0 ~= (term1 + term2 - term3 - term4) where - term1 = (1/3)*((p t 3 0 0 0) + (p t 0 3 0 0) + (p t 0 0 3 0)) - term2 = (9/2)*(p t 1 1 1 0) - term3 = (3/4)*((p t 2 1 0 0) + (p t 1 2 0 0) + (p t 2 0 1 0)) - term4 = (3/4)*((p t 1 0 2 0) + (p t 0 2 1 0) + (p t 0 1 2 0)) + term1 = (1 / 3)*((p t 3 0 0 0) + (p t 0 3 0 0) + (p t 0 0 3 0)) + term2 = (9 / 2)*(p t 1 1 1 0) + term3 = (3 / 4)*((p t 2 1 0 0) + (p t 1 2 0 0) + (p t 2 0 1 0)) + term4 = (3 / 4)*((p t 1 0 2 0) + (p t 0 2 1 0) + (p t 0 1 2 0)) diff --git a/src/Volumetric.hs b/src/Volumetric.hs index 0d1dfaa..f9e8d54 100644 --- a/src/Volumetric.hs +++ b/src/Volumetric.hs @@ -73,7 +73,7 @@ bracket lower_threshold upper_threshold x where numerator = x - lower_threshold denominator = upper_threshold - lower_threshold - r = numerator/denominator + r = numerator / denominator flip16 :: Word16 -> Word16 -- 2.43.2 From 16f16e8407c31330f1c29118b06925722da56282 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 25 Apr 2024 19:04:31 -0400 Subject: [PATCH 04/11] spline3.cabal: http -> https --- spline3.cabal | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spline3.cabal b/spline3.cabal index e49fe39..bf17185 100644 --- a/spline3.cabal +++ b/spline3.cabal @@ -3,7 +3,7 @@ name: spline3 version: 1.0.1 author: Michael Orlitzky maintainer: Michael Orlitzky -homepage: http://michael.orlitzky.com/code/spline3.xhtml +homepage: https://michael.orlitzky.com/code/spline3.xhtml category: Math license: AGPL-3.0-only license-file: doc/LICENSE @@ -14,10 +14,10 @@ description: Interpolate volumetric data according to "Local quasi-interpolation by cubic C^1 splines on type-6 tetrahedral partitions." The defaults are tailored to the MRI data contained in data/mri.bin from the - Stanford volume data archive at . + Stanford volume data archive at . For more information and examples, please see the project homepage at - . + . build-type: Simple extra-source-files: @@ -125,5 +125,5 @@ test-suite testsuite source-repository head type: git - location: http://gitweb.michael.orlitzky.com/spline3.git + location: https://gitweb.michael.orlitzky.com/spline3.git branch: master -- 2.43.2 From e06f4e17a48eff63f5438e4df2d2bb1eb3ee278c Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 25 Apr 2024 19:04:45 -0400 Subject: [PATCH 05/11] spline3.cabal: indent "maintainer" field with spaces --- spline3.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spline3.cabal b/spline3.cabal index bf17185..b632557 100644 --- a/spline3.cabal +++ b/spline3.cabal @@ -2,7 +2,7 @@ cabal-version: 3.0 name: spline3 version: 1.0.1 author: Michael Orlitzky -maintainer: Michael Orlitzky +maintainer: Michael Orlitzky homepage: https://michael.orlitzky.com/code/spline3.xhtml category: Math license: AGPL-3.0-only -- 2.43.2 From a5ee753e566191affbd31518d71246141d9897b6 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 25 Apr 2024 19:05:10 -0400 Subject: [PATCH 06/11] spline3.cabal: tweak synopsis --- spline3.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spline3.cabal b/spline3.cabal index b632557..69365e7 100644 --- a/spline3.cabal +++ b/spline3.cabal @@ -9,7 +9,7 @@ license: AGPL-3.0-only license-file: doc/LICENSE bug-reports: mailto:michael@orlitzky.com synopsis: - A parallel implementation of the Sorokina/Zeilfelder spline scheme. + Parallel implementation of the Sorokina/Zeilfelder spline scheme description: Interpolate volumetric data according to "Local quasi-interpolation by cubic C^1 splines on type-6 tetrahedral partitions." The defaults -- 2.43.2 From 5d0d5b1bab7e2a6ffb260094e302a1a31bd9f842 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 25 Apr 2024 19:06:17 -0400 Subject: [PATCH 07/11] doc/COPYING,spline3.cabal: use AGPL-3+, ship COPYING --- doc/COPYING | 15 +++++++++++++++ spline3.cabal | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 doc/COPYING diff --git a/doc/COPYING b/doc/COPYING new file mode 100644 index 0000000..0ea6556 --- /dev/null +++ b/doc/COPYING @@ -0,0 +1,15 @@ +spline3: parallel implementation of the Sorokina/Zeilfelder spline scheme +Copyright (C) 2024 Michael Orlitzky + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see . diff --git a/spline3.cabal b/spline3.cabal index 69365e7..99eef77 100644 --- a/spline3.cabal +++ b/spline3.cabal @@ -5,7 +5,7 @@ author: Michael Orlitzky maintainer: Michael Orlitzky homepage: https://michael.orlitzky.com/code/spline3.xhtml category: Math -license: AGPL-3.0-only +license: AGPL-3.0-or-later license-file: doc/LICENSE bug-reports: mailto:michael@orlitzky.com synopsis: @@ -24,6 +24,7 @@ extra-source-files: data/mri.bin data/mri.info data/announcement.txt + doc/COPYING doc/README -- Don't ship the references for copyright reasons. --doc/references/*.pdf -- 2.43.2 From 6ff35da034db2b51e0667eb2c470dd3b4e7aa461 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 25 Apr 2024 19:06:57 -0400 Subject: [PATCH 08/11] spline3.cabal: rewrap description --- spline3.cabal | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/spline3.cabal b/spline3.cabal index 99eef77..6d58326 100644 --- a/spline3.cabal +++ b/spline3.cabal @@ -11,10 +11,11 @@ bug-reports: mailto:michael@orlitzky.com synopsis: Parallel implementation of the Sorokina/Zeilfelder spline scheme description: - Interpolate volumetric data according to "Local quasi-interpolation - by cubic C^1 splines on type-6 tetrahedral partitions." The defaults - are tailored to the MRI data contained in data/mri.bin from the - Stanford volume data archive at . + Interpolate volumetric data according to "Local + quasi-interpolation by cubic C^1 splines on type-6 tetrahedral + partitions." The defaults are tailored to the MRI data contained in + data/mri.bin from the Stanford volume data archive at + . For more information and examples, please see the project homepage at . -- 2.43.2 From 42830c416e147bfe828863b2eb7fa12940ca2ad5 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Mon, 29 Apr 2024 21:15:28 -0400 Subject: [PATCH 09/11] util/view-mri-data.py: update for python3 --- util/view-mri-data.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/view-mri-data.py b/util/view-mri-data.py index 96fbfa5..62ae9b7 100755 --- a/util/view-mri-data.py +++ b/util/view-mri-data.py @@ -1,4 +1,4 @@ -#!/usr/bin/python2 +#!/usr/bin/python3 """ Display volumetric data from the Stanford Volume Data Archive. The @@ -11,7 +11,7 @@ import sys def usage(): binary = sys.argv[0] - print "Usage:", binary, "" + print(f"Usage: {binary} ") if len(sys.argv) < 2: usage() @@ -34,7 +34,7 @@ import numpy as np data = np.fromfile(sys.argv[1], dtype='>u2') original_data_length = 7143424 -multiplier = cube_root(len(data) / original_data_length) +multiplier = cube_root(len(data) // original_data_length) data.shape = (109*multiplier, 256*multiplier, 256*multiplier) data = data.T -- 2.43.2 From b306f322ec05410a45155be3139d6824824aadca Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Mon, 29 Apr 2024 21:30:24 -0400 Subject: [PATCH 10/11] util/view-mri-data.py: minor tweaks --- util/view-mri-data.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/util/view-mri-data.py b/util/view-mri-data.py index 62ae9b7..01bddbd 100755 --- a/util/view-mri-data.py +++ b/util/view-mri-data.py @@ -33,18 +33,19 @@ def cube_root(n): import numpy as np data = np.fromfile(sys.argv[1], dtype='>u2') -original_data_length = 7143424 +original_data_length = 109*256*256 multiplier = cube_root(len(data) // original_data_length) data.shape = (109*multiplier, 256*multiplier, 256*multiplier) data = data.T # Display the data -mlab.figure(bgcolor=(0, 0, 0), size=(1000, 1000)) +mlab.figure( bgcolor=(0,0,0), size=(1000,1000) ) +# Our data is scalar (grayscale), but not equally spaced in all +# directions. src = mlab.pipeline.scalar_field(data) - -# Our data is not equally spaced in all directions: src.spacing = [1, 1, 1.5] src.update_image_data = True -v = mlab.pipeline.volume(src, vmax=2500, vmin=1400) + +mlab.pipeline.volume(src, vmin=1400, vmax=2500) mlab.show() -- 2.43.2 From 3a564c16360e72cf89d3569e6e35aad0fa042e90 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 30 Apr 2024 07:14:46 -0400 Subject: [PATCH 11/11] spline3.cabal: bump version to 1.0.2 --- spline3.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spline3.cabal b/spline3.cabal index 6d58326..7e99e13 100644 --- a/spline3.cabal +++ b/spline3.cabal @@ -1,6 +1,6 @@ cabal-version: 3.0 name: spline3 -version: 1.0.1 +version: 1.0.2 author: Michael Orlitzky maintainer: Michael Orlitzky homepage: https://michael.orlitzky.com/code/spline3.xhtml -- 2.43.2