(self, cycle='V')
return float(flops) / float(nnz[0])
Cycle complexity of V, W, AMLI, and F(1,1) cycle with simple relaxation.

        Cycle complexity is an approximate measure of the number of
        floating point operations (FLOPs) required to perform a single
        multigrid cycle relative to the cost a single smoothing operation.

        Parameters
        ----------
        cycle : {'V','W','F','AMLI'}
            Type of multigrid cycle to perform in each iteration.

        Returns
        -------
        cc : float
            Defined as F_sum / F_0, where
            F_sum is the total number of nonzeros in the matrix on all
            levels encountered during a cycle and F_0 is the number of
            nonzeros in the matrix on the finest level.

        Notes
        -----
        This is only a rough estimate of the true cycle complexity. The
        estimate assumes that the cost of pre and post-smoothing are
        (each) equal to the number of nonzeros in the matrix on that level.
        This assumption holds for smoothers like Jacobi and Gauss-Seidel.
        However, the true cycle complexity of cycle using more expensive
        methods, like block Gauss-Seidel will be underestimated.

        Additionally, if the cycle used in practice isn't a (1,1)-cycle,
        then this cost estimate will be off.
Cycle complexity of V, W, AMLI, and F(1,1) cycle with simple relaxation.
Cycle complexity of V W AMLI and F ( 1 1 ) cycle with simple relaxation .
def cycle_complexity(self, cycle='V'):
        """Cycle complexity of V, W, AMLI, and F(1,1) cycle with simple relaxation.

        Cycle complexity is an approximate measure of the number of
        floating point operations (FLOPs) required to perform a single
        multigrid cycle relative to the cost a single smoothing operation.

        Parameters
        ----------
        cycle : {'V','W','F','AMLI'}
            Type of multigrid cycle to perform in each iteration.

        Returns
        -------
        cc : float
            Defined as F_sum / F_0, where
            F_sum is the total number of nonzeros in the matrix on all
            levels encountered during a cycle and F_0 is the number of
            nonzeros in the matrix on the finest level.

        Notes
        -----
        This is only a rough estimate of the true cycle complexity. The
        estimate assumes that the cost of pre and post-smoothing are
        (each) equal to the number of nonzeros in the matrix on that level.
        This assumption holds for smoothers like Jacobi and Gauss-Seidel.
        However, the true cycle complexity of cycle using more expensive
        methods, like block Gauss-Seidel will be underestimated.

        Additionally, if the cycle used in practice isn't a (1,1)-cycle,
        then this cost estimate will be off.

        """
        cycle = str(cycle).upper()

        nnz = [level.A.nnz for level in self.levels]

        def V(level):
            if len(self.levels) == 1:
                return nnz[0]

            if level == len(self.levels) - 2:
                return 2 * nnz[level] + nnz[level + 1]

            return 2 * nnz[level] + V(level + 1)

        def W(level):
            if len(self.levels) == 1:
                return nnz[0]

            if level == len(self.levels) - 2:
                return 2 * nnz[level] + nnz[level + 1]

            return 2 * nnz[level] + 2 * W(level + 1)

        def F(level):
            if len(self.levels) == 1:
                return nnz[0]

            if level == len(self.levels) - 2:
                return 2 * nnz[level] + nnz[level + 1]

            return 2 * nnz[level] + F(level + 1) + V(level + 1)

        if cycle == 'V':
            flops = V(0)
        elif cycle in ('W', 'AMLI'):
            flops = W(0)
        elif cycle == 'F':
            flops = F(0)
        else:
            raise TypeError(f'Unrecognized cycle type ({cycle})')

        return float(flops) / float(nnz[0])
def cycle_complexity ( self , cycle = 'V' ) : cycle = str ( cycle ) . upper ( ) nnz = [ level . A . nnz for level in self . levels ] def V ( level ) : if len ( self . levels ) == 1 : return nnz [ 0 ] if level == len ( self . levels ) - 2 : return 2 * nnz [ level ] + nnz [ level + 1 ] return 2 * nnz [ level ] + V ( level + 1 ) def W ( level ) : if len ( self . levels ) == 1 : return nnz [ 0 ] if level == len ( self . levels ) - 2 : return 2 * nnz [ level ] + nnz [ level + 1 ] return 2 * nnz [ level ] + 2 * W ( level + 1 ) def F ( level ) : if len ( self . levels ) == 1 : return nnz [ 0 ] if level == len ( self . levels ) - 2 : return 2 * nnz [ level ] + nnz [ level + 1 ] return 2 * nnz [ level ] + F ( level + 1 ) + V ( level + 1 ) if cycle == 'V' : flops = V ( 0 ) elif cycle in ( 'W' , 'AMLI' ) : flops = W ( 0 ) elif cycle == 'F' : flops = F ( 0 ) else : raise TypeError ( f'Unrecognized cycle type ({cycle})' ) return float ( flops ) / float ( nnz [ 0 ] )