def __call__(self, x):
            '''Interpolate at point [x].  Returns a 3-tuple: (y, mask) where [y]
         is the interpolated point, and [mask] is a boolean array with the same
         shape as [x] and is True where interpolated and False where extrapolated'''
            if not self.setup:
                self._setup()

            if len(num.shape(x)) < 1:
                scalar = True
            else:
                scalar = False

            x = num.atleast_1d(x)
            if self.realization:
                evm = num.atleast_1d(evalsp(x, self.realization))
                mask = num.greater_equal(x, self.realization[0][0])*\
                       num.less_equal(x,self.realization[0][-1])
            else:
                evm = num.atleast_1d(evalsp(x, self.tck))
                mask = num.greater_equal(x, self.tck[0][0]) * num.less_equal(
                    x, self.tck[0][-1])

            if scalar:
                return evm[0], mask[0]
            else:
                return evm, mask
示例#2
0
    def __call__(self, x):
       '''Interpolate at point [x].  Returns a 3-tuple: (y, mask) where [y]
       is the interpolated point, and [mask] is a boolean array with the same
       shape as [x] and is True where interpolated and False where extrapolated'''
       if not self.setup:
          self._setup()
 
       if len(num.shape(x)) < 1:
          scalar = True
       else:
          scalar = False
 
       x = num.atleast_1d(x)
       if self.realization:
          evm = num.atleast_1d(evalsp(x, self.realization))
          mask = num.greater_equal(x, self.realization[0][0])*\
                 num.less_equal(x,self.realization[0][-1])
       else:
          evm = num.atleast_1d(evalsp(x, self.tck))
          mask = num.greater_equal(x, self.tck[0][0])*num.less_equal(x,self.tck[0][-1])
 
       if scalar:
          return evm[0],mask[0]
       else:
          return evm,mask
示例#3
0
    def deriv(self, x, n=1):
       '''Returns the nth derivative of the function at x.'''
       if self.realization:
          tck = self.realization
       else:
          tck = self.tck
       if len(num.shape(x)) < 1:
          scalar = True
       else:
          scalar = False
       x = num.atleast_1d(x)
       if self.realization:
          evm = num.atleast_1d(evalsp(x, self.realization, deriv=n))
       else:
          evm = num.atleast_1d(evalsp(x, self.tck, deriv=n))
 
       if scalar:
          return evm[0]
       else:
          return evm
        def deriv(self, x, n=1):
            '''Returns the nth derivative of the function at x.'''
            if self.realization:
                tck = self.realization
            else:
                tck = self.tck
            if len(num.shape(x)) < 1:
                scalar = True
            else:
                scalar = False
            x = num.atleast_1d(x)
            if self.realization:
                evm = num.atleast_1d(evalsp(x, self.realization, deriv=n))
            else:
                evm = num.atleast_1d(evalsp(x, self.tck, deriv=n))

            if scalar:
                return evm[0]
            else:
                return evm
示例#5
0
def test_spline2(spdata):
   x,y,tck = spdata
   yeval = spline2.evalsp(x, tck)
   assert alltrue(absolute(yeval-y) < 0.01)
示例#6
0
def make_spline2(t, m, e_m, k=3, fitflux=0, zpt=0, tmin=-10, tmax=100, adaptive=0, max_curv_fac=10, **args):
    """A wrapper around spline2 that makes sure the independent variable is
   monotonic and non-repeating.  Required arguments:  time (t), magnitudes
   (m) and errors (e_m).  k is the spline order (default 3)  If fitflux
   is nonzero, convert magnitudes to flux (using provided zpt).  tmin and tmax should
   be set to the limits of the spline."""
    # first, we make sure that t is monotonically increasing with no repeated
    # elements
    sids = num.argsort(t)
    tt = num.take(t, sids)
    mm = num.take(m, sids)
    ee_m = num.take(e_m, sids)

    # here's some Numeric magic.  first, find where we have repeating x-values
    Nmatrix = num.equal(tt[:, num.newaxis], tt[num.newaxis, :])
    # val_matrix = mm[:,num.newaxis]*num.ones((len(mm),len(mm)))
    # e_matrix = ee_m[:,num.newaxis]*num.ones((len(mm),len(mm)))
    val_matrix = mm[:, num.newaxis] * Nmatrix
    e_matrix = ee_m[:, num.newaxis] * Nmatrix

    average = sum(val_matrix) / sum(Nmatrix)
    e_average = sum(e_matrix) / sum(Nmatrix)

    # at this point, average is the original data, but with repeating data points
    # replaced with their average.  Now, we just pick out the unique x's and
    # the first of any repeating points:
    gids = num.concatenate([[True], num.greater(tt[1:] - tt[:-1], 0.0)])
    tt = tt[gids]  # num.compress(gids, tt)
    mm = average[gids]  # num.compress(gids, average)
    ee_m = e_average[gids]  # num.compress(gids, e_average)

    # Now get rid of any data that's outside [tmin,tmax]
    gids = num.less_equal(tt, tmax) * num.greater_equal(tt, tmin)
    tt = tt[gids]  # num.compress(gids,tt)
    mm = mm[gids]  # num.compress(gids,mm)
    ee_m = ee_m[gids]  # num.compress(gids,ee_m)
    ee_m = num.where(num.less(ee_m, 0.001), 0.001, ee_m)

    # Now convert to flux if requested:
    if fitflux:
        mm = num.power(10, -0.4 * (mm - zpt))
        ee_m = mm * ee_m / 1.087

    # Okay, now make the spline representation
    if not adaptive:
        tck = spline2.spline2(tt, mm, w=1.0 / ee_m, degree=k, **args)
        fp = num.sum(num.power((mm - spline2.evalsp(tt, tck)) / ee_m, 2))
        ier = 0
        msg = "not much"
        return (tck, fp, ier, msg)

    # Do an adaptive (much slower) search for the best fit, subject
    #  to curvature constraints (right now, just a cap).
    if "lopt" in args:
        del args["lopt"]
    Ks = []
    chisqs = []
    lopts = range(2, int(0.8 * len(tt) - 1))
    for l in lopts:
        tck = spline2.spline2(tt, mm, w=1.0 / ee_m, degree=k, lopt=l, **args)
        fp = num.sum(num.power((mm - spline2.evalsp(tt, tck)) / ee_m, 2))
        K = quad(K2, tck[0][0], tck[0][-1], args=(tck,), epsrel=0.01)[0]
        chisqs.append(fp)
        Ks.append(K)

    chisqs = num.array(chisqs)
    Ks = num.array(Ks)
    chisqs = num.where(num.less(Ks, Ks.min() * max_curv_fac), chisqs, num.Inf)
    id = num.argmin(chisqs)

    ier = lopts[id]
    tck = spline2.spline2(tt, mm, w=1.0 / ee_m, degree=k, lopt=ier, **args)
    fp = num.sum(num.power((mm - spline2.evalsp(tt, tck)) / ee_m, 2))
    return (tck, fp, ier, "Optimized lopt = %d" % ier)
示例#7
0
def K2(x, tck):
    """compute the square curvature of a spline2 at point x"""
    yp = num.power(spline2.evalsp(x, tck, 1), 2)
    ypp = num.power(spline2.evalsp(x, tck, 2), 2)
    return ypp / num.power(1 + yp, 3)
def make_spline2(t,
                 m,
                 e_m,
                 k=3,
                 fitflux=0,
                 zpt=0,
                 tmin=-10,
                 tmax=100,
                 adaptive=0,
                 max_curv_fac=10,
                 **args):
    '''A wrapper around spline2 that makes sure the independent variable is
   monotonic and non-repeating.  Required arguments:  time (t), magnitudes
   (m) and errors (e_m).  k is the spline order (default 3)  If fitflux
   is nonzero, convert magnitudes to flux (using provided zpt).  tmin and tmax should
   be set to the limits of the spline.'''
    # first, we make sure that t is monotonically increasing with no repeated
    # elements
    sids = num.argsort(t)
    tt = num.take(t, sids)
    mm = num.take(m, sids)
    ee_m = num.take(e_m, sids)

    # here's some Numeric magic.  first, find where we have repeating x-values
    Nmatrix = num.equal(tt[:, num.newaxis], tt[num.newaxis, :])
    #val_matrix = mm[:,num.newaxis]*num.ones((len(mm),len(mm)))
    #e_matrix = ee_m[:,num.newaxis]*num.ones((len(mm),len(mm)))
    val_matrix = mm[:, num.newaxis] * Nmatrix
    e_matrix = ee_m[:, num.newaxis] * Nmatrix

    average = sum(val_matrix) / sum(Nmatrix)
    e_average = sum(e_matrix) / sum(Nmatrix)

    # at this point, average is the original data, but with repeating data points
    # replaced with their average.  Now, we just pick out the unique x's and
    # the first of any repeating points:
    gids = num.concatenate([[True], num.greater(tt[1:] - tt[:-1], 0.)])
    tt = tt[gids]  #num.compress(gids, tt)
    mm = average[gids]  # num.compress(gids, average)
    ee_m = e_average[gids]  #num.compress(gids, e_average)

    # Now get rid of any data that's outside [tmin,tmax]
    gids = num.less_equal(tt, tmax) * num.greater_equal(tt, tmin)
    tt = tt[gids]  #num.compress(gids,tt)
    mm = mm[gids]  # num.compress(gids,mm)
    ee_m = ee_m[gids]  #num.compress(gids,ee_m)
    ee_m = num.where(num.less(ee_m, 0.001), 0.001, ee_m)

    # Now convert to flux if requested:
    if fitflux:
        mm = num.power(10, -0.4 * (mm - zpt))
        ee_m = mm * ee_m / 1.087

    # Okay, now make the spline representation
    if not adaptive:
        tck = spline2.spline2(tt, mm, w=1.0 / ee_m, degree=k, **args)
        fp = num.sum(num.power((mm - spline2.evalsp(tt, tck)) / ee_m, 2))
        ier = 0
        msg = 'not much'
        return (tck, fp, ier, msg)

    # Do an adaptive (much slower) search for the best fit, subject
    #  to curvature constraints (right now, just a cap).
    if 'lopt' in args: del args['lopt']
    Ks = []
    chisqs = []
    lopts = range(2, int(0.8 * len(tt) - 1))
    for l in lopts:
        tck = spline2.spline2(tt, mm, w=1.0 / ee_m, degree=k, lopt=l, **args)
        fp = num.sum(num.power((mm - spline2.evalsp(tt, tck)) / ee_m, 2))
        K = quad(K2, tck[0][0], tck[0][-1], args=(tck, ), epsrel=0.01)[0]
        chisqs.append(fp)
        Ks.append(K)

    chisqs = num.array(chisqs)
    Ks = num.array(Ks)
    chisqs = num.where(num.less(Ks, Ks.min() * max_curv_fac), chisqs, num.Inf)
    id = num.argmin(chisqs)

    ier = lopts[id]
    tck = spline2.spline2(tt, mm, w=1.0 / ee_m, degree=k, lopt=ier, **args)
    fp = num.sum(num.power((mm - spline2.evalsp(tt, tck)) / ee_m, 2))
    return (tck, fp, ier, "Optimized lopt = %d" % ier)
def K2(x, tck):
    '''compute the square curvature of a spline2 at point x'''
    yp = num.power(spline2.evalsp(x, tck, 1), 2)
    ypp = num.power(spline2.evalsp(x, tck, 2), 2)
    return (ypp / num.power(1 + yp, 3))