Esempio n. 1
0
    def __init__(self,
                 order,
                 region=[-1., 1.],
                 rule='GaussLegendre',
                 uselongfloat=0):
        self.uselongfloat = uselongfloat

        if uselongfloat:
            region = [longfloat(region[0]), longfloat(region[1])]

        self.order = order
        self.region = region
        self.midpoint = (region[1] + region[0]) / 2.
        self.scale = (region[1] - region[0]) / 2.
        self.rule = rule

        if rule == 'GaussLegendre':
            x, w = self.__grule()
            for i in range(self.order):
                x[i] = x[i] * self.scale + self.midpoint
                w[i] = w[i] * self.scale
        elif rule == 'GaussHermite':
            raise "sorry this is not tested"
            x, w = self.__hrule()
        elif rule == 'GaussLaguerre':
            raise "sorry this is not tested"
            x, w = self.__lrule()
        else:
            raise "unknown rule", rule

        self.x = x
        self.w = w
Esempio n. 2
0
    def __hn(self, n, x):
        """
        Evaluate the renormalized Hermite polynomials Hn(x).

        Regular Hn
        p[0] = 1
        p[1] = 2*x
        p[i+1] = 2*x*p[i] - 2*i*p[i-1]

        Renormalized
        p[0] = 1/pi**(1/4)
        p[1] = sqrt(2)*x*p[0]
        p[i+1] = x*sqrt(2/(i+1))*p[i] - sqrt(j/(j+1))*p[j-1]
        
        """
        p = range(n + 1)
        p[0] = 1.0
        if self.uselongfloat:
            x = longfloat(x)
            p[0] = longfloat(1)
        if n == 0:
            return p
        p[1] = 2 * x
        for i in range(1, n):
            p[i + 1] = 2 * x * p[i] - 2 * i * p[i - 1]
        return p
Esempio n. 3
0
    def __hn(self, n, x):
        '''
        Evaluate the renormalized Hermite polynomials Hn(x).

        Regular Hn
        p[0] = 1
        p[1] = 2*x
        p[i+1] = 2*x*p[i] - 2*i*p[i-1]

        Renormalized
        p[0] = 1/pi**(1/4)
        p[1] = sqrt(2)*x*p[0]
        p[i+1] = x*sqrt(2/(i+1))*p[i] - sqrt(j/(j+1))*p[j-1]
        
        '''
        p = range(n + 1)
        p[0] = 1.0
        if self.uselongfloat:
            x = longfloat(x)
            p[0] = longfloat(1)
        if n == 0:
            return p
        p[1] = 2 * x
        for i in range(1, n):
            p[i + 1] = 2 * x * p[i] - 2 * i * p[i - 1]
        return p
Esempio n. 4
0
    def __init__(self, order, region=[-1.0, 1.0], rule="GaussLegendre", uselongfloat=0):
        self.uselongfloat = uselongfloat

        if uselongfloat:
            region = [longfloat(region[0]), longfloat(region[1])]

        self.order = order
        self.region = region
        self.midpoint = (region[1] + region[0]) / 2.0
        self.scale = (region[1] - region[0]) / 2.0
        self.rule = rule

        if rule == "GaussLegendre":
            x, w = self.__grule()
            for i in range(self.order):
                x[i] = x[i] * self.scale + self.midpoint
                w[i] = w[i] * self.scale
        elif rule == "GaussHermite":
            raise "sorry this is not tested"
            x, w = self.__hrule()
        elif rule == "GaussLaguerre":
            raise "sorry this is not tested"
            x, w = self.__lrule()
        else:
            raise "unknown rule", rule

        self.x = x
        self.w = w
Esempio n. 5
0
 def __ln(self, n, x):
     '''
     Laguerre polyn
     '''
     p = range(n + 1)
     p[0] = 1.0
     if self.uselongfloat:
         x = longfloat(x)
         p[0] = longfloat(1)
     if n == 0:
         return p
     p[1] = 1 - x
     for i in range(1, n):
         p[i + 1] = ((2 * i + 1 - x) * p[i] - i * p[i - 1]) / (i + 1)
     return p
Esempio n. 6
0
 def __ln(self, n, x):
     """
     Laguerre polyn
     """
     p = range(n + 1)
     p[0] = 1.0
     if self.uselongfloat:
         x = longfloat(x)
         p[0] = longfloat(1)
     if n == 0:
         return p
     p[1] = 1 - x
     for i in range(1, n):
         p[i + 1] = ((2 * i + 1 - x) * p[i] - i * p[i - 1]) / (i + 1)
     return p
Esempio n. 7
0
 def __factorial(self, n):
     f = 1.0
     if self.uselongfloat:
         f = longfloat(1.0)
     for i in range(1, n + 1):
         f = f * i
     return f
Esempio n. 8
0
def pnlong(x,order):
    '''
    USE LONGFLOATS
    
    Evaluate the Legendre polynomials up to the given order at x
    defined on [-1,1].
    '''
    p = range(order+1)
    p[0] = longfloat(1)
    x = longfloat(x)
    if order == 0:
        return p
    p[1] = x
    for n in range(1,order):
        p[n+1] = n*(x*p[n] - p[n-1])/(n+1) + x*p[n]
    return p
Esempio n. 9
0
def QuadratureTest2(uselongfloat=0):
    ''' Test the Gauss-Hermite quadrature on [-inf..inf] '''
    maxmaxerr = 0.0
    rootpi = sqrt(pi)
    two = 2.0
    if uselongfloat:
        two = longfloat(2)
        rootpi = two.pi().sqrt()

    for order in range(2, 24):
        q = Quadrature(order, rule="GaussHermite", uselongfloat=uselongfloat)
        maxerr = 0.0
        for power in range(0, 2 * order, 2):
            fstr = 'def __qtestf(x): return x**%d' % power
            exec(fstr)
            value = q.integrate(__qtestf)
            del (__qtestf)
            test = 0.5 * rootpi * 0.5**(power / 2)
            for i in range(power - 1, 0, -2):
                test = test * i
            maxerr = max(maxerr, abs(float(value - test) / test))
        print "order %d:  integrates powers up to %d with maxerr=%e" % \
              (order, 2*order-2, maxerr)
        maxmaxerr = max(maxmaxerr, maxerr)
    print(' Maximum error from all orders %9.1e' % float(maxmaxerr))
Esempio n. 10
0
def pnlong(x, order):
    '''
    USE LONGFLOATS
    
    Evaluate the Legendre polynomials up to the given order at x
    defined on [-1,1].
    '''
    p = range(order + 1)
    p[0] = longfloat(1)
    x = longfloat(x)
    if order == 0:
        return p
    p[1] = x
    for n in range(1, order):
        p[n + 1] = n * (x * p[n] - p[n - 1]) / (n + 1) + x * p[n]
    return p
Esempio n. 11
0
def philong(x,k):
    '''
    USE LONGFLOATS
    
    Evaluate the shifted normalized Legendre polynomials up to the
    given order at x defined on [0,1].

    These are also our scaling functions, phi_i(x) , i=0..k-1

    In addition to forming an orthonormal basis on [0,1] we have
    phi_j(1/2-x) = (-1)^j phi_j(1/2+x)

    (the wavelets are similar with phase (-1)^(j+k)).
    '''
    global phi_norms_long

    if len(phi_norms_long) == 0:
        for n in range(max(k+1,61)):
            phi_norms_long.append(longfloat(2*n+1).sqrt())
    if k > 60:
        raise "phi_norms_long too small"
    
    order = k-1
    p = pnlong(2*x-1,order)
    for n in range(k):
        p[n] = p[n]*phi_norms_long[n]  # sqrt(2*n+1)
    return p
Esempio n. 12
0
def philong(x, k):
    '''
    USE LONGFLOATS
    
    Evaluate the shifted normalized Legendre polynomials up to the
    given order at x defined on [0,1].

    These are also our scaling functions, phi_i(x) , i=0..k-1

    In addition to forming an orthonormal basis on [0,1] we have
    phi_j(1/2-x) = (-1)^j phi_j(1/2+x)

    (the wavelets are similar with phase (-1)^(j+k)).
    '''
    global phi_norms_long

    if len(phi_norms_long) == 0:
        for n in range(max(k + 1, 61)):
            phi_norms_long.append(longfloat(2 * n + 1).sqrt())
    if k > 60:
        raise "phi_norms_long too small"

    order = k - 1
    p = pnlong(2 * x - 1, order)
    for n in range(k):
        p[n] = p[n] * phi_norms_long[n]  # sqrt(2*n+1)
    return p
Esempio n. 13
0
 def __factorial(self, n):
     f = 1.0
     if self.uselongfloat:
         f = longfloat(1.0)
     for i in range(1, n + 1):
         f = f * i
     return f
Esempio n. 14
0
def h0h1(k):
    '''
    USE LONGFLOATS
    
    Compute the h0 & h1 two-scale coefficients

    h0_ij = sqrt(2)*int(phi_i(x)*phi_j(2x),x=0..1/2)
    h1_ij = sqrt(2)*int(phi_i(x)*phi_j(2x-1),x=1/2..1)

    but
    
    h1_ij = (-1)^(i+j) h0_ij from symmetry property of the phi

    The h0/h1 are useful because

    phi_i(x) = sqrt(2)*sum(j) h0_ij*phi_j(2x) + h1_ij*phi_j(2x-1)

    and
    
    phi_i(2x)   = (1/sqrt(2))*sum(j) h0_ji*phi_j(x) + g0_ji*psi(x)
    phi_i(2x-1) = (1/sqrt(2))*sum(j) h1_ji*phi_j(x) + g1_ji*psi(x)
    '''
    q = Quadrature(k, [longfloat(0), longfloat((-1, 1))], uselongfloat=1)
    x = q.points()
    w = q.weights()
    npt = len(x)
    twox = range(npt)
    for i in range(npt):
        twox[i] = x[i] + x[i]

    h0 = zeromatrix(k, k)
    h1 = zeromatrix(k, k)

    root2 = longfloat(2).sqrt()
    for t in range(npt):
        p = philong(x[t], k)
        p2 = philong(twox[t], k)
        for i in range(k):
            faci = p[i] * w[t] * root2
            for j in range(k):
                h0[i][j] = h0[i][j] + faci * p2[j]

    for i in range(k):
        for j in range(k):
            h1[i][j] = ((-1)**(i + j)) * h0[i][j]

    return (h0, h1)
Esempio n. 15
0
def h0h1(k):
    '''
    USE LONGFLOATS
    
    Compute the h0 & h1 two-scale coefficients

    h0_ij = sqrt(2)*int(phi_i(x)*phi_j(2x),x=0..1/2)
    h1_ij = sqrt(2)*int(phi_i(x)*phi_j(2x-1),x=1/2..1)

    but
    
    h1_ij = (-1)^(i+j) h0_ij from symmetry property of the phi

    The h0/h1 are useful because

    phi_i(x) = sqrt(2)*sum(j) h0_ij*phi_j(2x) + h1_ij*phi_j(2x-1)

    and
    
    phi_i(2x)   = (1/sqrt(2))*sum(j) h0_ji*phi_j(x) + g0_ji*psi(x)
    phi_i(2x-1) = (1/sqrt(2))*sum(j) h1_ji*phi_j(x) + g1_ji*psi(x)
    '''
    q = Quadrature(k,[longfloat(0),longfloat((-1,1))],uselongfloat=1)
    x = q.points()
    w = q.weights()
    npt = len(x)
    twox = range(npt)
    for i in range(npt):
        twox[i] = x[i] + x[i]

    h0 = zeromatrix(k,k)
    h1 = zeromatrix(k,k)
    
    root2 = longfloat(2).sqrt()
    for t in range(npt):
        p = philong(x[t],k)
        p2= philong(twox[t],k)
        for i in range(k):
            faci = p[i]*w[t]*root2
            for j in range(k):
                h0[i][j] = h0[i][j] + faci*p2[j]

    for i in range(k):
        for j in range(k):
            h1[i][j] = ((-1)**(i+j))*h0[i][j]

    return (h0, h1)
Esempio n. 16
0
    def __grule(self):
        ''' Return the Gauss Legendre quadrature weights. '''

        n = self.order

        nbits = 52
        if self.uselongfloat:
            nbits = longfloat.nbits
        acc = 0.5**(nbits / 3 + 10)
        if self.uselongfloat:
            acc = longfloat(acc)

        # References made to the equation numbers in Davis & Rabinowitz 2nd ed.
        roots = range(n)
        weights = range(n)
        for k in range(n):
            # Initial guess for the root using 2.7.3.3b
            #x = (1.0 - 1.0/(8*n*n) + 1.0/(8*n*n*n))*cos(((4*k+3.0)/(4*n+2))*pi)
            x = (1.0 - 1.0 / (8.0 * n * n) + 1.0 / (8.0 * n * n * n)) * cos(
                ((4 * k + 3.0) / (4 * n + 2)) * pi)
            if self.uselongfloat:
                x = longfloat(x)
            # Refine the initial guess using a 3rd-order Newton correction 2.7.3.9
            # Running this six times will ensure enough precision even if we're
            # requesting over 1500 significant decimal figures.
            for iter in range(7):
                p = self.__pn(n, x)
                p0 = p[n]  # Value
                p1 = n * (p[n - 1] - x * p[n]) / (
                    1 - x * x)  # First derivative ... 2.7.3.5
                p2 = (2 * x * p1 - n *
                      (n + 1) * p0) / (1 - x * x)  # Second derivative
                delta = -(p0 / p1) * (1 + (p0 * p2) / (2 * p1 * p1))
                x = x + delta
                if abs(delta) < acc:
                    break
            if iter >= 6:
                raise "netwon iteration for root failed"

            # Compute the weight using 2.7.3.8
            p = self.__pn(n, x)
            w = 2 * (1 - x * x) / (n * n * p[n - 1] * p[n - 1])

            roots[k] = x
            weights[k] = w

        return (roots, weights)
Esempio n. 17
0
    def __grule(self):
        """ Return the Gauss Legendre quadrature weights. """

        n = self.order

        nbits = 52
        if self.uselongfloat:
            nbits = longfloat.nbits
        acc = 0.5 ** (nbits / 3 + 10)
        if self.uselongfloat:
            acc = longfloat(acc)

        # References made to the equation numbers in Davis & Rabinowitz 2nd ed.
        roots = range(n)
        weights = range(n)
        for k in range(n):
            # Initial guess for the root using 2.7.3.3b
            # x = (1.0 - 1.0/(8*n*n) + 1.0/(8*n*n*n))*cos(((4*k+3.0)/(4*n+2))*pi)
            x = (1.0 - 1.0 / (8.0 * n * n) + 1.0 / (8.0 * n * n * n)) * cos(((4 * k + 3.0) / (4 * n + 2)) * pi)
            if self.uselongfloat:
                x = longfloat(x)
            # Refine the initial guess using a 3rd-order Newton correction 2.7.3.9
            # Running this six times will ensure enough precision even if we're
            # requesting over 1500 significant decimal figures.
            for iter in range(7):
                p = self.__pn(n, x)
                p0 = p[n]  # Value
                p1 = n * (p[n - 1] - x * p[n]) / (1 - x * x)  # First derivative ... 2.7.3.5
                p2 = (2 * x * p1 - n * (n + 1) * p0) / (1 - x * x)  # Second derivative
                delta = -(p0 / p1) * (1 + (p0 * p2) / (2 * p1 * p1))
                x = x + delta
                if abs(delta) < acc:
                    break
            if iter >= 6:
                raise "netwon iteration for root failed"

            # Compute the weight using 2.7.3.8
            p = self.__pn(n, x)
            w = 2 * (1 - x * x) / (n * n * p[n - 1] * p[n - 1])

            roots[k] = x
            weights[k] = w

        return (roots, weights)
Esempio n. 18
0
def QuadratureTest(uselongfloat=0):
    """ Test the Gauss-Legendre quadrature on [0.5,1] """
    maxmaxerr = 0.0
    for order in range(1, 20):
        q = Quadrature(order, [0.5, 1.0], uselongfloat=uselongfloat)
        maxerr = 0.0
        for power in range(2 * order):
            fstr = "def __qtestf(x): return x**%d" % power
            exec (fstr)
            value = q.integrate(__qtestf)
            del (__qtestf)
            if uselongfloat:
                test = (longfloat(1) - longfloat((-power - 1, 1))) / (power + 1.0)
            else:
                test = (1.0 - 0.5 ** (power + 1)) / (power + 1.0)
            maxerr = max(maxerr, abs(float(value - test)))
        print "order %d:  integrates powers up to %d with maxerr=%e" % (order, 2 * order - 1, maxerr)
        maxmaxerr = max(maxmaxerr, maxerr)
    print (" Maximum error from all orders %9.1e" % float(maxmaxerr))
Esempio n. 19
0
def QuadratureTest(uselongfloat=0):
    ''' Test the Gauss-Legendre quadrature on [0.5,1] '''
    maxmaxerr = 0.0
    for order in range(1, 20):
        q = Quadrature(order, [0.5, 1.0], uselongfloat=uselongfloat)
        maxerr = 0.0
        for power in range(2 * order):
            fstr = 'def __qtestf(x): return x**%d' % power
            exec(fstr)
            value = q.integrate(__qtestf)
            del (__qtestf)
            if uselongfloat:
                test = (longfloat(1) - longfloat(
                    (-power - 1, 1))) / (power + 1.0)
            else:
                test = (1.0 - 0.5**(power + 1)) / (power + 1.0)
            maxerr = max(maxerr, abs(float(value - test)))
        print "order %d:  integrates powers up to %d with maxerr=%e" % \
              (order, 2*order-1, maxerr)
        maxmaxerr = max(maxmaxerr, maxerr)
    print(' Maximum error from all orders %9.1e' % float(maxmaxerr))
Esempio n. 20
0
def half_moments(maxm,k):
    '''
    USE LONGFLOATS
    
    Compute the moments of the scaling functions computed
    over half over the interval.

    hmom1[p][j] = int(x^p * phi_j(2*x), x=0..1/2)
    hmom2[p][j] = int((x+0.5)^p * phi_j(2*x), x=0..1/2)

    hmom2 is made from hmom1 using the binomial expansion
    (x+a)^p = a^0*x^p + p*a^1*x^p-1 + p*(p-1)*a^2*x^p-2 / 2 + ... + a^p*x^0

    From Alpert, Beylkin, Gines and Vozovoi

    int(x^p phi_j(x),x=0..1) = sqrt(2*j+1)*(p!)^2 / ((p-j)!(p+j+1)!) p>=j

    Get an extra factor of (1/2)^(m+1) from the change of scale.

    For completeness also record here that
    
    int((x-1)^p phi_j(x),x=0..1) = (-1)^(j+p) *
    .                          sqrt(2*j+1)*(p!)^2 / ((p-j)!(p+j+1)!)

    Moments with p < j are zero due to orthogonality.
    '''

    hmom1 = zeromatrix(maxm+1,k)
    hmom2 = zeromatrix(maxm+1,k)

    factorial = range(maxm+1+k)
    pfac = longfloat(1)
    for p in range(maxm+1+k):
        factorial[p] = pfac
        pfac = pfac * (p+1)

    half = longfloat((-1,1))
    for p in range(maxm+1):
        pfac2 = factorial[p]*factorial[p]
        scale = longfloat(half)**(p+1)
        for j in range(k):
            if p < j:
                hmom1[p][j] = longfloat(0)
            else:
                hmom1[p][j] = scale*(longfloat(2*j+1).sqrt())*pfac2 / \
                             (factorial[p-j]*factorial[p+j+1])

    for p in range(maxm+1):
        for i in range(k):
            fac = longfloat(1)
            for q in range(p+1):
                hmom2[p][i] = hmom2[p][i] + fac*(half**(p-q))*hmom1[q][i]
                fac = fac * (p-q) / (q+1)
    return (hmom1, hmom2)
Esempio n. 21
0
def half_moments(maxm, k):
    '''
    USE LONGFLOATS
    
    Compute the moments of the scaling functions computed
    over half over the interval.

    hmom1[p][j] = int(x^p * phi_j(2*x), x=0..1/2)
    hmom2[p][j] = int((x+0.5)^p * phi_j(2*x), x=0..1/2)

    hmom2 is made from hmom1 using the binomial expansion
    (x+a)^p = a^0*x^p + p*a^1*x^p-1 + p*(p-1)*a^2*x^p-2 / 2 + ... + a^p*x^0

    From Alpert, Beylkin, Gines and Vozovoi

    int(x^p phi_j(x),x=0..1) = sqrt(2*j+1)*(p!)^2 / ((p-j)!(p+j+1)!) p>=j

    Get an extra factor of (1/2)^(m+1) from the change of scale.

    For completeness also record here that
    
    int((x-1)^p phi_j(x),x=0..1) = (-1)^(j+p) *
    .                          sqrt(2*j+1)*(p!)^2 / ((p-j)!(p+j+1)!)

    Moments with p < j are zero due to orthogonality.
    '''

    hmom1 = zeromatrix(maxm + 1, k)
    hmom2 = zeromatrix(maxm + 1, k)

    factorial = range(maxm + 1 + k)
    pfac = longfloat(1)
    for p in range(maxm + 1 + k):
        factorial[p] = pfac
        pfac = pfac * (p + 1)

    half = longfloat((-1, 1))
    for p in range(maxm + 1):
        pfac2 = factorial[p] * factorial[p]
        scale = longfloat(half)**(p + 1)
        for j in range(k):
            if p < j:
                hmom1[p][j] = longfloat(0)
            else:
                hmom1[p][j] = scale*(longfloat(2*j+1).sqrt())*pfac2 / \
                             (factorial[p-j]*factorial[p+j+1])

    for p in range(maxm + 1):
        for i in range(k):
            fac = longfloat(1)
            for q in range(p + 1):
                hmom2[p][i] = hmom2[p][i] + fac * (half**(p - q)) * hmom1[q][i]
                fac = fac * (p - q) / (q + 1)
    return (hmom1, hmom2)
Esempio n. 22
0
def QuadratureTest2(uselongfloat=0):
    """ Test the Gauss-Hermite quadrature on [-inf..inf] """
    maxmaxerr = 0.0
    rootpi = sqrt(pi)
    two = 2.0
    if uselongfloat:
        two = longfloat(2)
        rootpi = two.pi().sqrt()

    for order in range(2, 24):
        q = Quadrature(order, rule="GaussHermite", uselongfloat=uselongfloat)
        maxerr = 0.0
        for power in range(0, 2 * order, 2):
            fstr = "def __qtestf(x): return x**%d" % power
            exec (fstr)
            value = q.integrate(__qtestf)
            del (__qtestf)
            test = 0.5 * rootpi * 0.5 ** (power / 2)
            for i in range(power - 1, 0, -2):
                test = test * i
            maxerr = max(maxerr, abs(float(value - test) / test))
        print "order %d:  integrates powers up to %d with maxerr=%e" % (order, 2 * order - 2, maxerr)
        maxmaxerr = max(maxmaxerr, maxerr)
    print (" Maximum error from all orders %9.1e" % float(maxmaxerr))
Esempio n. 23
0
def g0g1(k):
    '''
    USE LONGFLOATS
    
    Compute the g0 & g1 two-scale coefficients which define the
    multi-wavelet in terms of the scaling functions at the finer
    level.

    psi_i(x) = sqrt(2)*sum(j) g0_ij*phi_j(2x) + g1_ij*phi_j(2x-1)

    Projection with sqrt(2)*phi_j(2x) and sqrt(2)*phi_j(2x-1), which
    are the normalized scaling functions on the finer level, yields 

    g0_ij = sqrt(2)*int(psi_i(x)*phi_j(2x),x=0..1/2)
    g1_ij = sqrt(2)*int(psi_i(x)*phi_j(2x-1),x=1/2..1)


    With the original Alpert conditions we have
    
    g1_ij = (-1)^(i+j+k) g0_ij from symmetry properties of the psi

    but you only get this if you impose the condition of additional
    vanishing moments.

    The projection of the additional moments is very numerically
    unstable and forces the use of higher precision for k >= 6.
    '''

    g0 = zeromatrix(k, k)
    g1 = zeromatrix(k, k)

    # Initialize the basis
    rroot2 = longfloat(2).rsqrt()
    for i in range(0, k):
        g0[i][i] = rroot2
        g1[i][i] = -rroot2

    (h0, h1) = h0h1(k)

    # Project out the moments == orthog to the scaling functions.
    # Need to use the two-scale relation for the scaling functions.
    for i in range(k):
        for attempt in range(1):  # was 2
            for m in range(k):
                dotim = dot(g0[i], h0[m]) + dot(g1[i], h1[m])
                for j in range(k):
                    g0[i][j] = g0[i][j] - dotim * h0[m][j]
                    g1[i][j] = g1[i][j] - dotim * h1[m][j]

    # Orthog to x^k, x^k+1, ... , x^2k-2
    first = 0
    root2 = longfloat(2).sqrt()
    (hmom1, hmom2) = half_moments(2 * k - 2, k)

    test = longfloat(1).eps().sqrt()
    for power in range(k, 2 * k - 1):
        # Transform to the wavelet basis
        overlap = zerovector(k)
        for i in range(k):
            for j in range(k):
                overlap[i] = overlap[i] + root2*\
                  (g0[i][j]*hmom1[power][j] + g1[i][j]*hmom2[power][j])

        # Put first function with non-zero overlap in front of the list
        for i in range(first, k):
            if abs(overlap[i]) > test:  # Is there a better test?
                (g0[first], g0[i]) = (g0[i], g0[first])
                (g1[first], g1[i]) = (g1[i], g1[first])
                (overlap[first], overlap[i]) = (overlap[i], overlap[first])
                break

        # Project out the first component as necessary.
        if abs(overlap[first]) > test:  # Is there a better test?
            for i in range(first + 1, k):
                scale = overlap[i] / overlap[first]
                for j in range(k):
                    g0[i][j] = g0[i][j] - scale * g0[first][j]
                    g1[i][j] = g1[i][j] - scale * g1[first][j]

        first = first + 1

    orthonormalize_wavelets(g0, g1, k)

    return (g0, g1)
Esempio n. 24
0
def zerovector(n):
    v = vector(n)
    for i in range(n):
        v[i] = longfloat(0)
    return v
Esempio n. 25
0
def g0g1(k):
    '''
    USE LONGFLOATS
    
    Compute the g0 & g1 two-scale coefficients which define the
    multi-wavelet in terms of the scaling functions at the finer
    level.

    psi_i(x) = sqrt(2)*sum(j) g0_ij*phi_j(2x) + g1_ij*phi_j(2x-1)

    Projection with sqrt(2)*phi_j(2x) and sqrt(2)*phi_j(2x-1), which
    are the normalized scaling functions on the finer level, yields 

    g0_ij = sqrt(2)*int(psi_i(x)*phi_j(2x),x=0..1/2)
    g1_ij = sqrt(2)*int(psi_i(x)*phi_j(2x-1),x=1/2..1)


    With the original Alpert conditions we have
    
    g1_ij = (-1)^(i+j+k) g0_ij from symmetry properties of the psi

    but you only get this if you impose the condition of additional
    vanishing moments.

    The projection of the additional moments is very numerically
    unstable and forces the use of higher precision for k >= 6.
    '''

    g0 = zeromatrix(k,k)
    g1 = zeromatrix(k,k)

    # Initialize the basis
    rroot2 = longfloat(2).rsqrt()
    for i in range(0,k):
        g0[i][i] =  rroot2
        g1[i][i] = -rroot2

    (h0, h1) = h0h1(k)

    # Project out the moments == orthog to the scaling functions.
    # Need to use the two-scale relation for the scaling functions.
    for i in range(k):
        for attempt in range(1): # was 2
            for m in range(k):
                dotim = dot(g0[i],h0[m])+dot(g1[i],h1[m])
                for j in range(k):
                    g0[i][j] = g0[i][j] - dotim*h0[m][j]
                    g1[i][j] = g1[i][j] - dotim*h1[m][j]

    # Orthog to x^k, x^k+1, ... , x^2k-2
    first = 0
    root2 = longfloat(2).sqrt()
    (hmom1,hmom2) = half_moments(2*k-2,k)

    test = longfloat(1).eps().sqrt()
    for power in range(k,2*k-1):
        # Transform to the wavelet basis
        overlap = zerovector(k)
        for i in range(k):
            for j in range(k):
                overlap[i] = overlap[i] + root2*\
                  (g0[i][j]*hmom1[power][j] + g1[i][j]*hmom2[power][j])

        # Put first function with non-zero overlap in front of the list
        for i in range(first,k):
            if abs(overlap[i]) > test:       # Is there a better test?
                (g0[first],g0[i]) = (g0[i],g0[first])
                (g1[first],g1[i]) = (g1[i],g1[first])
                (overlap[first],overlap[i]) = (overlap[i],overlap[first])
                break

        # Project out the first component as necessary.
        if abs(overlap[first]) > test:       # Is there a better test?
            for i in range(first+1,k):
                scale = overlap[i]/overlap[first]
                for j in range(k):
                    g0[i][j] = g0[i][j] - scale*g0[first][j]
                    g1[i][j] = g1[i][j] - scale*g1[first][j]

        first = first + 1
        
    orthonormalize_wavelets(g0,g1,k)
        
    return (g0, g1)
Esempio n. 26
0
    def __hrule(self):
        '''

        Gauss-Hermite rule on [0,inf]

        '''
        n = self.order

        nbits = 52
        rootpi = sqrt(pi)
        two = 2.0
        zero = 0.0
        if self.uselongfloat:
            two = longfloat(2)
            zero = longfloat(0)
            rootpi = longfloat(1).pi().sqrt()
            nbits = longfloat.nbits
        acc = 0.5**(nbits / 3 + 10)
        if self.uselongfloat:
            acc = longfloat(acc)

        # Find the points which are the zeros of Hn
        # dH[n]/dx = 2*n*H[n-1]

        npt = (n - 1) / 2 + 1
        roots = range(npt)
        weights = range(npt)
        nfound = 0
        if n % 2:
            p = self.__hn(n + 1, 0.0)
            roots[0] = zero
            weights[0] = two**(n + 1) * self.__factorial(n) * rootpi / p[n +
                                                                         1]**2
            # !!!! Since just doing [0,inf] need to halve this
            weights[0] = weights[0] / two
            nfound = nfound + 1

        guess = 0.01
        if self.uselongfloat:
            guess = longfloat(guess)
        while nfound != npt:

            # Stupid linear search forward for sign change
            x = guess
            p = self.__hn(n, x)
            hh = p[n]
            while 1:
                x = x + 0.05
                p = self.__hn(n, x)
                if hh * p[n] < 0.0:
                    break

            # Cubic newton
            for iter in range(7):
                p = self.__hn(n, x)
                p0 = p[n]  # Value
                p1 = 2 * n * p[n - 1]  # First derivative
                p2 = 4 * n * (n - 1) * p[n - 2]  # Second derivative
                delta = -(p0 / p1) * (1 + (p0 * p2) / (2 * p1 * p1))
                #print "newton", x, delta
                x = x + delta
                if abs(delta) < acc:
                    break
            if iter >= 6:
                raise "Hermite netwon iteration for root failed"

            new = 1
            for i in range(nfound):
                if abs(x - roots[i]) < 1e-3:
                    new = 0
                    break
            if not new:
                guess = guess + 0.1
                if guess > 100.0:
                    raise "Hermite root finder is lost"
                continue

            #print "found root", x
            roots[nfound] = x
            p = self.__hn(n + 1, x)
            weights[nfound] = two**(
                n + 1) * self.__factorial(n) * rootpi / p[n + 1]**2
            nfound = nfound + 1

            guess = x + 0.05

        return roots, weights
Esempio n. 27
0
    def __lrule(self):
        """

        Gauss-Laguerre rule on [0,inf]

        """
        n = self.order

        nbits = 52
        zero = 0.0
        if self.uselongfloat:
            zero = longfloat(0)
            nbits = longfloat.nbits
        acc = 0.5 ** (nbits / 3 + 10)
        if self.uselongfloat:
            acc = longfloat(acc)

        # Find the points which are the zeros of Ln
        # dL[n]/dx   =  n*(L[n] - L[n-1])/x

        roots = range(n)
        weights = range(n)
        nfound = 0
        guess = 0.0001
        step = 0.0001
        if self.uselongfloat:
            guess = longfloat(guess)
        while nfound != n:
            # Stupid linear search forward for sign change
            x = guess
            p = self.__ln(n, x)
            hh = p[n]
            if nfound > 1:
                step = 0.1 * (roots[nfound - 1] - roots[nfound - 2])
            print "step", step
            niter = 1000
            while niter:
                niter = niter - 1
                xp = x
                x = x + step
                p = self.__ln(n, x)
                if hh * p[n] < 0.0:
                    break
            x = (x + xp) / 2.0
            if niter == 0:
                print nfound, x
                raise "Gauss Laguerre lost a root?"

            print "linear search found", x, hh, p[n]

            # Cubic newton
            for iter in range(7):
                p = self.__ln(n, x)
                p0 = p[n]  # Value
                p1 = n * (p[n] - p[n - 1]) / x  # First derivative
                pp1 = (n - 1) * (p[n - 1] - p[n - 2]) / x
                p2 = n * (p1 - pp1) / x - p1 / x  # Second derivative
                delta = -(p0 / p1) * (1 + (p0 * p2) / (2 * p1 * p1))
                x = x + delta
                if abs(delta) < acc:
                    break
            if iter >= 6:
                raise "Laguerre netwon iteration for root failed"
            print "found", x

            new = 1
            for i in range(nfound):
                if abs(x - roots[i]) < 1e-3:
                    new = 0
                    break
            if not new:
                guess = guess + step
                if guess > 150.0:
                    raise "Laguerre root finder is lost"
                continue

            p = self.__ln(n + 1, x)
            roots[nfound] = x
            weights[nfound] = x / ((n + 1) * p[n + 1]) ** 2

            nfound = nfound + 1

            guess = x + 0.05

        return roots, weights
Esempio n. 28
0
    def __hrule(self):
        """

        Gauss-Hermite rule on [0,inf]

        """
        n = self.order

        nbits = 52
        rootpi = sqrt(pi)
        two = 2.0
        zero = 0.0
        if self.uselongfloat:
            two = longfloat(2)
            zero = longfloat(0)
            rootpi = longfloat(1).pi().sqrt()
            nbits = longfloat.nbits
        acc = 0.5 ** (nbits / 3 + 10)
        if self.uselongfloat:
            acc = longfloat(acc)

        # Find the points which are the zeros of Hn
        # dH[n]/dx = 2*n*H[n-1]

        npt = (n - 1) / 2 + 1
        roots = range(npt)
        weights = range(npt)
        nfound = 0
        if n % 2:
            p = self.__hn(n + 1, 0.0)
            roots[0] = zero
            weights[0] = two ** (n + 1) * self.__factorial(n) * rootpi / p[n + 1] ** 2
            # !!!! Since just doing [0,inf] need to halve this
            weights[0] = weights[0] / two
            nfound = nfound + 1

        guess = 0.01
        if self.uselongfloat:
            guess = longfloat(guess)
        while nfound != npt:

            # Stupid linear search forward for sign change
            x = guess
            p = self.__hn(n, x)
            hh = p[n]
            while 1:
                x = x + 0.05
                p = self.__hn(n, x)
                if hh * p[n] < 0.0:
                    break

            # Cubic newton
            for iter in range(7):
                p = self.__hn(n, x)
                p0 = p[n]  # Value
                p1 = 2 * n * p[n - 1]  # First derivative
                p2 = 4 * n * (n - 1) * p[n - 2]  # Second derivative
                delta = -(p0 / p1) * (1 + (p0 * p2) / (2 * p1 * p1))
                # print "newton", x, delta
                x = x + delta
                if abs(delta) < acc:
                    break
            if iter >= 6:
                raise "Hermite netwon iteration for root failed"

            new = 1
            for i in range(nfound):
                if abs(x - roots[i]) < 1e-3:
                    new = 0
                    break
            if not new:
                guess = guess + 0.1
                if guess > 100.0:
                    raise "Hermite root finder is lost"
                continue

            # print "found root", x
            roots[nfound] = x
            p = self.__hn(n + 1, x)
            weights[nfound] = two ** (n + 1) * self.__factorial(n) * rootpi / p[n + 1] ** 2
            nfound = nfound + 1

            guess = x + 0.05

        return roots, weights
Esempio n. 29
0
    def __lrule(self):
        '''

        Gauss-Laguerre rule on [0,inf]

        '''
        n = self.order

        nbits = 52
        zero = 0.0
        if self.uselongfloat:
            zero = longfloat(0)
            nbits = longfloat.nbits
        acc = 0.5**(nbits / 3 + 10)
        if self.uselongfloat:
            acc = longfloat(acc)

        # Find the points which are the zeros of Ln
        # dL[n]/dx   =  n*(L[n] - L[n-1])/x

        roots = range(n)
        weights = range(n)
        nfound = 0
        guess = 0.0001
        step = 0.0001
        if self.uselongfloat:
            guess = longfloat(guess)
        while nfound != n:
            # Stupid linear search forward for sign change
            x = guess
            p = self.__ln(n, x)
            hh = p[n]
            if nfound > 1:
                step = 0.1 * (roots[nfound - 1] - roots[nfound - 2])
            print "step", step
            niter = 1000
            while niter:
                niter = niter - 1
                xp = x
                x = x + step
                p = self.__ln(n, x)
                if hh * p[n] < 0.0:
                    break
            x = (x + xp) / 2.0
            if niter == 0:
                print nfound, x
                raise "Gauss Laguerre lost a root?"

            print "linear search found", x, hh, p[n]

            # Cubic newton
            for iter in range(7):
                p = self.__ln(n, x)
                p0 = p[n]  # Value
                p1 = n * (p[n] - p[n - 1]) / x  # First derivative
                pp1 = (n - 1) * (p[n - 1] - p[n - 2]) / x
                p2 = n * (p1 - pp1) / x - p1 / x  # Second derivative
                delta = -(p0 / p1) * (1 + (p0 * p2) / (2 * p1 * p1))
                x = x + delta
                if abs(delta) < acc:
                    break
            if iter >= 6:
                raise "Laguerre netwon iteration for root failed"
            print "found", x

            new = 1
            for i in range(nfound):
                if abs(x - roots[i]) < 1e-3:
                    new = 0
                    break
            if not new:
                guess = guess + step
                if guess > 150.0:
                    raise "Laguerre root finder is lost"
                continue

            p = self.__ln(n + 1, x)
            roots[nfound] = x
            weights[nfound] = x / ((n + 1) * p[n + 1])**2

            nfound = nfound + 1

            guess = x + 0.05

        return roots, weights
Esempio n. 30
0
def zerovector(n):
    v = vector(n)
    for i in range(n):
        v[i] = longfloat(0)
    return v