def test_calc_phi(self):
     """Performs some rudimentary tests, asserting that phi is
     sane."""
     phi = self.sm._get_phi()
     self.assertLessEqual(phi.max(), 1)
     self.assertGreaterEqual(phi.min(), 0)
     self.assertEqual(np.count_nonzero(phi),
                      (len(self.sm.dataset) - 2) * \
                      (self.sm._degree + 1) + 2)
     bf = sp.bsplinebasis(self.sm.knots, 0, self.sm._degree)
     self.assertEqual(phi[0, 0], 1)
     self.assertEqual(phi[-1, 0], 0)
     self.assertEqual(phi[self.sm._degree + 2, 0], 0)
     basis = sp.bsplinebasis(self.sm.knots, 6, self.sm._degree)
     values = []
     for t_idx in [5, 6, 7, 8, 9]:
         knotrange = self.sm.knots[-1] - self.sm.knots[0]
         t = float(t_idx) / (len(self.sm.dataset) - 1) * knotrange
         self.assertEqual(phi[t_idx, 6], basis(t))
     self.assertTrue(np.any(phi[5:10, 6] > 0))
 def test_calc_phi(self):
     """Performs some rudimentary tests, asserting that phi is
     sane."""
     phi = self.sm._get_phi()
     self.assertLessEqual(phi.max(), 1)
     self.assertGreaterEqual(phi.min(), 0)
     self.assertEqual(np.count_nonzero(phi),
                      (len(self.sm.dataset) - 2) * \
                      (self.sm._degree + 1) + 2)
     bf = sp.bsplinebasis(self.sm.knots, 0, self.sm._degree)
     self.assertEqual(phi[0, 0], 1)
     self.assertEqual(phi[-1, 0], 0)
     self.assertEqual(phi[self.sm._degree+2, 0], 0)
     basis = sp.bsplinebasis(self.sm.knots, 6, self.sm._degree)
     values = []
     for t_idx in [5, 6, 7, 8, 9]:
         knotrange = self.sm.knots[-1] - self.sm.knots[0]
         t = float(t_idx) / (len(self.sm.dataset) - 1) * knotrange
         self.assertEqual(phi[t_idx, 6], basis(t))
     self.assertTrue(np.any(phi[5:10, 6] > 0))
Esempio n. 3
0
    def _get_roughness(self):
        """Calculate the "R" matrix analytically if the B-spline degree is 3,
        taking advantage of integration by parts and the fact that the 3rd
        derivative of a 3rd-degree B-spline is a constant. Further description
        in roughness.tex."""
        p = self._degree
        if p != 3:
            return BSplineBasicSmoother._get_roughness(self)
        k = self._get_num_coefficients()
        r = np.zeros((k, k))
        bases = [sp.bsplinebasis(self._knots, i, p) for i in range(k)]
        d1 = [sp.bsplinebasis_deriv(self._knots, i, p, 1) for i in range(k)]
        d2 = [sp.bsplinebasis_deriv(self._knots, i, p, 2) for i in range(k)]
        t = self._knots
        t_min = t[0]
        t_max = t[-1]
        for i in range(k):
            if t[i+1] > t[i]:
                c_0 = 6./((t[i+3] - t[i]) * (t[i+2] - t[i]) * (t[i+1] - t[i]))
            else:
                c_0 = 0

            div = ((t[i+3] - t[i])*(t[i+2] - t[i])) 
            l1 = 1. / div if div > 0 else 0
            div = ((t[i+3] - t[i])*(t[i+3] - t[i+1]))
            l2 = 1. / div if div > 0 else 0
            div = ((t[i+4] - t[i+1])*(t[i+3] - t[i+1]))
            l3 = 1. / div if div > 0 else 0
            c_1 = - 6./(t[i+2] - t[i+1]) * (l1 + l2 + l3) if t[i+2] > t[i+1] else 0

            div = ((t[i+3] - t[i])*(t[i+3] - t[i+1]))
            l1 = 1. / div if div > 0 else 0
            div = ((t[i+4] - t[i+1])*(t[i+3] - t[i+1]))
            l2 = 1. / div if div > 0 else 0
            div = ((t[i+4] - t[i+1])*(t[i+4] - t[i+2]))
            l3 = 1. / div if div > 0 else 0
            c_2 = 6./(t[i+3] - t[i+2]) * (l1 + l2 + l3) if t[i+3] > t[i+2] else 0

            if t[i+4] > t[i+3]:
                c_3 = - 6./((t[i+4] - t[i+1]) * (t[i+4] - t[i+2]) * (t[i+4] - t[i+3]))
            else:
                c_3 = 0
                
            jmin = max(0, i - self._degree)
            jmax = min(k, i + self._degree + 1)
            for j in range(jmin, jmax):
                phi = bases[j]
                r[i, j] = d2[i](t_max) * d1[j](t_max) - d2[i](t_min) * d1[j](t_min) \
                  - c_0 * (phi(t[i+1]) - phi(t[i])) \
                  - c_1 * (phi(t[i+2]) - phi(t[i+1])) \
                  - c_2 * (phi(t[i+3]) - phi(t[i+2])) \
                  - c_3 * (phi(t[i+4]) - phi(t[i+3]))
        return r
Esempio n. 4
0
 def _get_phi(self):
     """Calculate the n*k matrix where element i,j is the value at time i of
     the j'th b-spline basis function. Implements eq. 5 of Chen et al."""
     k = self._get_num_coefficients()
     n = len(self._dataset)
     phi = np.zeros((n, k))
     bases = [sp.bsplinebasis(self._knots, i, self._degree) \
              for i in range(k)]
     t_range = self._knots[-1] - self._knots[0]
     for i in range(n):
         for j in range(k):
             t = float(i) / (n - 1) * t_range
             phi[i, j] = bases[j](t)
     return phi