Exemplo n.º 1
0
def test_QuadraticForm_invariances():
    #nu = numx.linspace(2.,-3,10)
    nu = numx.linspace(6., 1, 10)
    H = utils.symrand(nu)
    E, W = mdp.utils.symeig(H)
    q = utils.QuadraticForm(H)
    xmax, xmin = q.get_extrema(5.)
    e_w, e_sd = q.get_invariances(xmax)
    #print e_sd,nu[1:]-nu[0]
    assert_array_almost_equal(e_sd,nu[1:]-nu[0],6)
    assert_array_almost_equal(abs(e_w),abs(W[:,-2::-1]),6)
    e_w, e_sd = q.get_invariances(xmin)
    assert_array_almost_equal(e_sd,nu[-2::-1]-nu[-1],6)
    assert_array_almost_equal(abs(e_w),abs(W[:,1:]),6)
Exemplo n.º 2
0
    def _givens_angle_case1(self, m, n, covs, bica_bsfa, complete=0):
        # This function makes use of the constants computed in the paper
        #
        # R -> R
        # m -> \mu
        # n -> \nu
        #
        # Note that the minus sign before the angle phi is there because
        # in the paper the rotation convention is the opposite of ours.
        ncovs = covs.ncovs
        covs = covs.covs
        icaweights = self.icaweights
        sfaweights = self.sfaweights
        bica, bsfa = bica_bsfa

        Cmm, Cmn, Cnn = covs[m, m, :], covs[m, n, :], covs[n, n, :]
        d0 =   (sfaweights * (Cmm*Cmm+Cnn*Cnn)).sum()
        d1 = 4*(sfaweights * (Cmm*Cmn-Cmn*Cnn)).sum()
        d2 = 2*(sfaweights * (2*Cmn*Cmn+Cmm*Cnn)).sum()
        e0 = 2*(icaweights * Cmn*Cmn).sum()
        e1 = 4*(icaweights * (Cmn*Cnn-Cmm*Cmn)).sum()
        e2 =   (icaweights * ((Cmm-Cnn)*(Cmm-Cnn)-2*Cmn*Cmn)).sum()

        s24 = 0.25* (bsfa * d1    + bica * e1)
        c24 = 0.25* (bsfa *(d0-d2)+ bica *(e0-e2))

        # compute the exact minimum
        # Note that 'arctan' finds always the first maximum
        # because s24sin(4p)+c24cos(4p)=const*cos(4p-arctan)
        # the minimum lies +pi/4 apart (period = pi/2).
        # In other words we want that: abs(minimum) < pi/4
        phi4 = numx.arctan2(s24, c24)
        # use if-structure until bug in numx.sign is solved
        if  phi4 >= 0:
            minimum = -0.25*(phi4-PI)
        else:
            minimum = -0.25*(phi4+PI)

        # compute all constants:
        R = self.output_dim
        dc = numx.zeros((ncovs, ), dtype = self.dtype)
        for t in range(ncovs):
            dg = covs[:R, :R, t].diagonal()
            dc[t] = (dg*dg).sum(axis=0)
        dc = ((dc-Cnn*Cnn-Cmm*Cmm)*sfaweights).sum()
        ec = numx.zeros((ncovs, ), dtype = self.dtype)
        for t in range(ncovs):
            triu_covs = _triu(covs[:R, :R, t], 1).ravel()
            ec[t] = ((triu_covs*triu_covs).sum() - covs[m, n, t]*covs[m, n, t])
        ec = 2*(icaweights*ec).sum()
        a20 = 0.25*(bsfa*(4*dc+d2+3*d0)+bica*(4*ec+e2+3*e0))
        minimum_contrast = a20+c24*cos(-4*minimum)+s24*sin(-4*minimum)
        npoints = 1000
        if complete == 1:
            # Compute the contrast between -pi/2 and pi/2
            # (useful for testing purposes)
            phi = numx.linspace(old_div(-PI,2), old_div(PI,2), npoints+1)
            contrast = a20 + c24*cos(-4*phi) + s24*sin(-4*phi)
            return phi, contrast, minimum, minimum_contrast
        elif complete == 2:
            phi = numx.linspace(old_div(-PI,4), old_div(PI,4), npoints+1)
            contrast = a20 + c24*cos(-4*phi) + s24*sin(-4*phi)
            return phi, contrast, minimum, minimum_contrast
        else:
            return minimum, minimum_contrast
Exemplo n.º 3
0
    def _givens_angle_case2(self, m, n, covs, bica_bsfa, complete=0):
        # This function makes use of the constants computed in the paper
        #
        # R -> R
        # m -> \mu
        # n -> \nu
        #
        # Note that the minus sign before the angle phi is there because
        # in the paper the rotation convention is the opposite of ours.

        ncovs = covs.ncovs
        covs = covs.covs
        icaweights = self.icaweights
        sfaweights = self.sfaweights
        R = self.output_dim
        bica, bsfa = bica_bsfa

        Cmm, Cmn, Cnn = covs[m, m, :], covs[m, n, :], covs[n, n, :]
        d0 =   (sfaweights * Cmm*Cmm).sum()
        d1 = 4*(sfaweights * Cmn*Cmm).sum()
        d2 = 2*(sfaweights * (2*Cmn*Cmn + Cmm*Cnn)).sum()
        d3 = 4*(sfaweights * Cmn*Cnn).sum()
        d4 =   (sfaweights * Cnn*Cnn).sum()
        e0 = 2*(icaweights * ((covs[:R, m, :]*covs[:R, m, :]).sum(axis=0)
                              - Cmm*Cmm)).sum()
        e1 = 4*(icaweights * ((covs[:R, m, :]*covs[:R, n, :]).sum(axis=0)
                              - Cmm*Cmn)).sum()
        e2 = 2*(icaweights * ((covs[:R, n, :]*covs[:R, n, :]).sum(axis=0)
                              - Cmn*Cmn)).sum()

        s22 = 0.25 * bsfa*(d1+d3)   + 0.5* bica*(e1)
        c22 = 0.5  * bsfa*(d0-d4)   + 0.5* bica*(e0-e2)
        s24 = 0.125* bsfa*(d1-d3)
        c24 = 0.125* bsfa*(d0-d2+d4)

        # Compute the contrast function in a grid of angles to find a
        # first approximation for the minimum.  Repeat two times
        # (effectively doubling the resolution). Note that we can do
        # that because we know we have a single minimum.
        #
        # npoints should not be too large otherwise the contrast
        # funtion appears to be constant. This is because we hit the
        # maximum resolution for the cosine function (ca. 1e-15)
        npoints = 100
        left = old_div(-PI,2) - old_div(PI,(npoints+1))
        right = old_div(PI,2) + old_div(PI,(npoints+1))
        for iter in (1, 2):
            phi = numx.linspace(left, right, npoints+3)
            contrast = c22*cos(-2*phi)+s22*sin(-2*phi)+\
                       c24*cos(-4*phi)+s24*sin(-4*phi)
            minidx = contrast.argmin()
            left = phi[max(minidx-1, 0)]
            right = phi[min(minidx+1, len(phi)-1)]

        # The contrast is almost a parabola around the minimum.
        # To find the minimum we can therefore compute the derivative
        # (which should be a line) and calculate its root.
        # This step helps to overcome the resolution limit of the
        # cosine function and clearly improve the final result.
        der_left = 2*c22*sin(-2*left)- 2*s22*cos(-2*left)+\
                   4*c24*sin(-4*left)- 4*s24*cos(-4*left)
        der_right = 2*c22*sin(-2*right)-2*s22*cos(-2*right)+\
                    4*c24*sin(-4*right)-4*s24*cos(-4*right)
        if abs(der_left - der_right) < SQRT_EPS_D:
            minimum = phi[minidx]
        else:
            minimum = right - der_right*(right-left)/(der_right-der_left)

        dc = numx.zeros((ncovs,), dtype = self.dtype)
        for t in range(ncovs):
            dg = covs[:R, :R, t].diagonal()
            dc[t] = (dg*dg).sum(axis=0)
        dc = ((dc-Cmm*Cmm)*sfaweights).sum()

        ec = numx.zeros((ncovs, ), dtype = self.dtype)
        for t in range(ncovs):
            ec[t] = sum([covs[i, j, t]*covs[i, j, t] for i in range(R-1)
                         for j in range(i+1, R) if i != m and j != m])
        ec = 2*(ec*icaweights).sum()
        a20 = 0.125*bsfa*(3*d0+d2+3*d4+8*dc)+0.5*bica*(e0+e2+2*ec)
        minimum_contrast = a20+c22*cos(-2*minimum)+s22*sin(-2*minimum)+\
                           c24*cos(-4*minimum)+s24*sin(-4*minimum)
        if complete:
            # Compute the contrast between -pi/2 and pi/2
            # (useful for testing purposes)
            npoints = 1000
            phi = numx.linspace(old_div(-PI,2), old_div(PI,2), npoints+1)
            contrast = a20 + c22*cos(-2*phi) + s22*sin(-2*phi) +\
                       c24*cos(-4*phi) + s24*sin(-4*phi)
            return phi, contrast, minimum, minimum_contrast
        else:
            return minimum, minimum_contrast
Exemplo n.º 4
0
    def _givens_angle_case1(self, m, n, covs, bica_bsfa, complete=0):
        # This function makes use of the constants computed in the paper
        #
        # R -> R
        # m -> \mu
        # n -> \nu
        #
        # Note that the minus sign before the angle phi is there because
        # in the paper the rotation convention is the opposite of ours.
        ncovs = covs.ncovs
        covs = covs.covs
        icaweights = self.icaweights
        sfaweights = self.sfaweights
        bica, bsfa = bica_bsfa

        Cmm, Cmn, Cnn = covs[m, m, :], covs[m, n, :], covs[n, n, :]
        d0 =   (sfaweights * (Cmm*Cmm+Cnn*Cnn)).sum()
        d1 = 4*(sfaweights * (Cmm*Cmn-Cmn*Cnn)).sum()
        d2 = 2*(sfaweights * (2*Cmn*Cmn+Cmm*Cnn)).sum()
        e0 = 2*(icaweights * Cmn*Cmn).sum()
        e1 = 4*(icaweights * (Cmn*Cnn-Cmm*Cmn)).sum()
        e2 =   (icaweights * ((Cmm-Cnn)*(Cmm-Cnn)-2*Cmn*Cmn)).sum()

        s24 = 0.25* (bsfa * d1    + bica * e1)
        c24 = 0.25* (bsfa *(d0-d2)+ bica *(e0-e2))

        # compute the exact minimum
        # Note that 'arctan' finds always the first maximum
        # because s24sin(4p)+c24cos(4p)=const*cos(4p-arctan)
        # the minimum lies +pi/4 apart (period = pi/2).
        # In other words we want that: abs(minimum) < pi/4
        phi4 = numx.arctan2(s24, c24)
        # use if-structure until bug in numx.sign is solved
        if  phi4 >= 0:
            minimum = -0.25*(phi4-PI)
        else:
            minimum = -0.25*(phi4+PI)

        # compute all constants:
        R = self.output_dim
        dc = numx.zeros((ncovs, ), dtype = self.dtype)
        for t in range(ncovs):
            dg = covs[:R, :R, t].diagonal()
            dc[t] = (dg*dg).sum(axis=0)
        dc = ((dc-Cnn*Cnn-Cmm*Cmm)*sfaweights).sum()
        ec = numx.zeros((ncovs, ), dtype = self.dtype)
        for t in range(ncovs):
            triu_covs = _triu(covs[:R, :R, t], 1).ravel()
            ec[t] = ((triu_covs*triu_covs).sum() - covs[m, n, t]*covs[m, n, t])
        ec = 2*(icaweights*ec).sum()
        a20 = 0.25*(bsfa*(4*dc+d2+3*d0)+bica*(4*ec+e2+3*e0))
        minimum_contrast = a20+c24*cos(-4*minimum)+s24*sin(-4*minimum)
        npoints = 1000
        if complete == 1:
            # Compute the contrast between -pi/2 and pi/2
            # (useful for testing purposes)
            phi = numx.linspace(old_div(-PI,2), old_div(PI,2), npoints+1)
            contrast = a20 + c24*cos(-4*phi) + s24*sin(-4*phi)
            return phi, contrast, minimum, minimum_contrast
        elif complete == 2:
            phi = numx.linspace(old_div(-PI,4), old_div(PI,4), npoints+1)
            contrast = a20 + c24*cos(-4*phi) + s24*sin(-4*phi)
            return phi, contrast, minimum, minimum_contrast
        else:
            return minimum, minimum_contrast
Exemplo n.º 5
0
    def _givens_angle_case2(self, m, n, covs, bica_bsfa, complete=0):
        # This function makes use of the constants computed in the paper
        #
        # R -> R
        # m -> \mu
        # n -> \nu
        #
        # Note that the minus sign before the angle phi is there because
        # in the paper the rotation convention is the opposite of ours.

        ncovs = covs.ncovs
        covs = covs.covs
        icaweights = self.icaweights
        sfaweights = self.sfaweights
        R = self.output_dim
        bica, bsfa = bica_bsfa

        Cmm, Cmn, Cnn = covs[m, m, :], covs[m, n, :], covs[n, n, :]
        d0 =   (sfaweights * Cmm*Cmm).sum()
        d1 = 4*(sfaweights * Cmn*Cmm).sum()
        d2 = 2*(sfaweights * (2*Cmn*Cmn + Cmm*Cnn)).sum()
        d3 = 4*(sfaweights * Cmn*Cnn).sum()
        d4 =   (sfaweights * Cnn*Cnn).sum()
        e0 = 2*(icaweights * ((covs[:R, m, :]*covs[:R, m, :]).sum(axis=0)
                              - Cmm*Cmm)).sum()
        e1 = 4*(icaweights * ((covs[:R, m, :]*covs[:R, n, :]).sum(axis=0)
                              - Cmm*Cmn)).sum()
        e2 = 2*(icaweights * ((covs[:R, n, :]*covs[:R, n, :]).sum(axis=0)
                              - Cmn*Cmn)).sum()

        s22 = 0.25 * bsfa*(d1+d3)   + 0.5* bica*(e1)
        c22 = 0.5  * bsfa*(d0-d4)   + 0.5* bica*(e0-e2)
        s24 = 0.125* bsfa*(d1-d3)
        c24 = 0.125* bsfa*(d0-d2+d4)

        # Compute the contrast function in a grid of angles to find a
        # first approximation for the minimum.  Repeat two times
        # (effectively doubling the resolution). Note that we can do
        # that because we know we have a single minimum.
        #
        # npoints should not be too large otherwise the contrast
        # funtion appears to be constant. This is because we hit the
        # maximum resolution for the cosine function (ca. 1e-15)
        npoints = 100
        left = old_div(-PI,2) - old_div(PI,(npoints+1))
        right = old_div(PI,2) + old_div(PI,(npoints+1))
        for iter in (1, 2):
            phi = numx.linspace(left, right, npoints+3)
            contrast = c22*cos(-2*phi)+s22*sin(-2*phi)+\
                       c24*cos(-4*phi)+s24*sin(-4*phi)
            minidx = contrast.argmin()
            left = phi[max(minidx-1, 0)]
            right = phi[min(minidx+1, len(phi)-1)]

        # The contrast is almost a parabola around the minimum.
        # To find the minimum we can therefore compute the derivative
        # (which should be a line) and calculate its root.
        # This step helps to overcome the resolution limit of the
        # cosine function and clearly improve the final result.
        der_left = 2*c22*sin(-2*left)- 2*s22*cos(-2*left)+\
                   4*c24*sin(-4*left)- 4*s24*cos(-4*left)
        der_right = 2*c22*sin(-2*right)-2*s22*cos(-2*right)+\
                    4*c24*sin(-4*right)-4*s24*cos(-4*right)
        if abs(der_left - der_right) < SQRT_EPS_D:
            minimum = phi[minidx]
        else:
            minimum = right - der_right*(right-left)/(der_right-der_left)

        dc = numx.zeros((ncovs,), dtype = self.dtype)
        for t in range(ncovs):
            dg = covs[:R, :R, t].diagonal()
            dc[t] = (dg*dg).sum(axis=0)
        dc = ((dc-Cmm*Cmm)*sfaweights).sum()

        ec = numx.zeros((ncovs, ), dtype = self.dtype)
        for t in range(ncovs):
            ec[t] = sum([covs[i, j, t]*covs[i, j, t] for i in range(R-1)
                         for j in range(i+1, R) if i != m and j != m])
        ec = 2*(ec*icaweights).sum()
        a20 = 0.125*bsfa*(3*d0+d2+3*d4+8*dc)+0.5*bica*(e0+e2+2*ec)
        minimum_contrast = a20+c22*cos(-2*minimum)+s22*sin(-2*minimum)+\
                           c24*cos(-4*minimum)+s24*sin(-4*minimum)
        if complete:
            # Compute the contrast between -pi/2 and pi/2
            # (useful for testing purposes)
            npoints = 1000
            phi = numx.linspace(old_div(-PI,2), old_div(PI,2), npoints+1)
            contrast = a20 + c22*cos(-2*phi) + s22*sin(-2*phi) +\
                       c24*cos(-4*phi) + s24*sin(-4*phi)
            return phi, contrast, minimum, minimum_contrast
        else:
            return minimum, minimum_contrast