Ejemplo n.º 1
0
    def rank_by_w_correl(self):
        ''' find optimal rank by:
            2) calculate summ of correlations for each row of self.w_correl
            3) find index where those summ is minimal. This is a rank
            @return pair of (calculated rank of SVD, w-correlation for that rank))
            Note: rank >= 1
        '''
        # w-correlation matrix has simmetry about main diagonal.
        # Coefficients at main diagonal always 1(self correlation).
        # Coefficients at (i+1,j) where j=1(close to main diagonal) can
        # be viewed as correlation of cos/sin of the same frequency
        # when coefficient more 0.5 and as noise in other case.
        # Assumptions:
        # - calculation is made in one half of matrix,
        # - main diagonal excluded from calculation.
        # - for element (i,i) calculation made for elements (i+1, i+wd), where
        #   wd is a w-correlation depth.
        # - No more than wlen elements analyzed. Assume rank of S no more
        #   than rank_max.
        # - according to condition above, size of analized SVD is
        #   wd + rank_max.
        # - correlations should be calculated at early step because
        #   the same value is used ofter more than one time.
        if not self.ssa:
            return 0, 0
        # calc w-correl limit
        rank_max = min(len(self.s_svd()) - 5, self.SSA_RANK_MAX)
        if rank_max < 0:
            self.log.error("Could not calc w-correl - S too short")
        if rank_max + self.W_MIN_DEPTH > len(self.s_svd()):
            m_size = len(self.s_svd())
        else:
            m_size = rank_max + self.W_MIN_DEPTH
        if rank_max > len(self.s_svd()):
            rank_max = len(self.s_svd())

        if self.w_correl is None:
            self.calc_w_unit_correl_matrix(rank_max, m_size)
        weights = self.calc_w_unit_correl_weights(rank_max)
        log_array(weights, "weights of w-correlation")
        if self.USE_W_CORR_WEIGHTS:
            self.log.info("correction weights by square")
            for i in range(weights.size):
                square = (i + 1) * (m_size - i)
                weights[i] /= square
            log_array(weights, "normalized by square weights of w-correlation")
        w_min = 1e10
        rank = -1
        # first and second values excluded, because:
        # 1) anyway, this value in most cases in small;
        # 2) rank = 1 is not interested in most cases.
        if weights.size < 3:
            imin = 1
        else:
            imin = 3
        for i in range(imin, weights.size):
            if weights[i] < w_min:
                rank = i
                w_min = weights[i]
        return (rank + 1, w_min)
Ejemplo n.º 2
0
 def debug_array(self, m, title):
     if self.loglevel <= logging.DEBUG:
         log_array(m, title)