Coverage for tests/test_spline.py: 21%
83 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-01-10 02:46 -0800
« prev ^ index » next coverage.py v6.5.0, created at 2023-01-10 02:46 -0800
1# This file is part of afw.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
22"""
23Tests for Splines
25Run with:
26 python test_spline.py
27or
28 pytest test_spline.py
29"""
30import math
31import unittest
33import lsst.utils.tests
34import lsst.afw.math as afwMath
37class SplineTestCase(unittest.TestCase):
38 """A test case for Image"""
40 def smooth(self, x, differentiate=False):
41 if differentiate:
42 return math.cos(x)
43 else:
44 return math.sin(x)
46 def noDerivative(self, x):
47 if False:
48 return math.sin(x)
49 else:
50 if x < 1:
51 return 1 - x
52 else:
53 return 0
55 def setUp(self):
56 x, x2, ySin, yND = [], [], [], []
57 for i in range(0, 40):
58 x.append(0.1*i)
59 for j in range(4):
60 x2.append(0.1*(i + 0.25*j))
62 ySin.append(self.smooth(x[i]))
63 yND.append(self.noDerivative(x[i]))
65 self.x = x
66 self.x2 = x2
67 self.yND = yND
68 self.ySin = ySin
70 def tearDown(self):
71 del self.x
72 del self.x2
73 del self.ySin
74 del self.yND
76 def testNaturalSpline1(self):
77 """Test fitting a natural spline to a smooth function"""
78 gamma = 0
79 sp = afwMath.TautSpline(self.x, self.ySin, gamma)
81 y2 = []
82 sp.interpolate(self.x2, y2)
84 for x, y in zip(self.x2, y2):
85 self.assertAlmostEqual(y, self.smooth(x), 1) # fails at 2 places!
87 def testNaturalSplineDerivative1(self):
88 """Test fitting a natural spline to a smooth function and finding its derivative"""
89 sp = afwMath.TautSpline(self.x, self.ySin)
91 y2 = []
92 sp.derivative(self.x2, y2)
94 for x, y in zip(self.x2, y2):
95 self.assertAlmostEqual(y, self.smooth(x, True), delta=1.5e-3)
97 def testNaturalSpline2(self):
98 """Test fitting a natural spline to a non-differentiable function (we basically fail)"""
99 gamma = 0
100 sp = afwMath.TautSpline(self.x, self.yND, gamma)
102 y2 = []
103 sp.interpolate(self.x2, y2)
105 for x, y in zip(self.x2, y2):
106 # fails at 2 places!
107 self.assertAlmostEqual(y, self.noDerivative(x), 1)
109 def testTautSpline1(self):
110 """Test fitting a taut spline to a smooth function"""
111 gamma = 2.5
112 sp = afwMath.TautSpline(self.x, self.ySin, gamma)
114 y2 = []
115 sp.interpolate(self.x2, y2)
117 for x, y in zip(self.x2, y2):
118 self.assertAlmostEqual(y, self.smooth(x), 4)
120 def testTautSpline2(self):
121 """Test fitting a taut spline to a non-differentiable function"""
122 gamma = 2.5
123 sp = afwMath.TautSpline(self.x, self.yND, gamma)
125 y2 = []
126 sp.interpolate(self.x2, y2)
128 for x, y in zip(self.x2, y2):
129 self.assertAlmostEqual(y, self.noDerivative(x))
131 def testRootFinding(self):
132 """Test finding roots of Spline = value"""
134 gamma = 2.5
135 sp = afwMath.TautSpline(self.x, self.yND, gamma)
137 for value in (0.1, 0.5):
138 self.assertEqual(
139 sp.roots(value, self.x[0], self.x[-1])[0], 1 - value)
141 if False:
142 y = []
143 sp.interpolate(self.x, y)
144 for x, y in zip(self.x, y):
145 print(x, y)
146 #
147 # Solve sin(x) = 0.5
148 #
149 sp = afwMath.TautSpline(self.x, self.ySin)
150 roots = [math.degrees(x) for x in sp.roots(0.5, self.x[0], self.x[-1])]
151 self.assertAlmostEqual(roots[0], 30, 5)
152 self.assertAlmostEqual(roots[1], 150, 5)
155class TestMemory(lsst.utils.tests.MemoryTestCase):
156 pass
159def setup_module(module):
160 lsst.utils.tests.init()
163if __name__ == "__main__": 163 ↛ 164line 163 didn't jump to line 164, because the condition on line 163 was never true
164 lsst.utils.tests.init()
165 unittest.main()