开发者

Optimize generator for multivariate polynomial exponents

开发者 https://www.devze.com 2023-02-09 08:57 出处:网络
HI, I\'m try to find a general expression to obtain exponents of a multivariate polynomial of order order and with n_variables, like the one presented in this reference in equation (3).

HI, I'm try to find a general expression to obtain exponents of a multivariate polynomial of order order and with n_variables, like the one presented in this reference in equation (3).

Here is my current code, which uses an itertools.product generator.

def generalized_taylor_expansion_exponents( order, n_variables ):
    """
    Find the exponents of a multivariate polynomial expression of order
    `order` and `n_variable` number of variables. 
    """
    exps = (p for p in itertools.product(range(order+1)开发者_运维问答, repeat=n_variables) if sum(p) <= order)
    # discard the first element, which is all zeros..
    exps.next()
    return exps

The desired out is this:

for i in generalized_taylor_expansion_exponents(order=3, n_variables=3): 
    print i

(0, 0, 1)
(0, 0, 2)
(0, 0, 3)
(0, 1, 0)
(0, 1, 1)
(0, 1, 2)
(0, 2, 0)
(0, 2, 1)
(0, 3, 0)
(1, 0, 0)
(1, 0, 1)
(1, 0, 2)
(1, 1, 0)
(1, 1, 1)
(1, 2, 0)
(2, 0, 0)
(2, 0, 1)
(2, 1, 0)
(3, 0, 0)

Actually this code executes fast, because the generator object is only created. If i want to fill a list with values from this generator execution really starts to be slow, mainly because of the high number of calls to sum. Tipical value for order and n_variables is 5 and 10, respectively.

How can i significantly improve execution speed?

Thanks for any help.

Davide Lasagna


Actually your biggest performance issue is that most of the tuples you're generating are too big and need to be thrown away. The following should generate exactly the tuples you want.

def generalized_taylor_expansion_exponents( order, n_variables ):
    """
    Find the exponents of a multivariate polynomial expression of order
    `order` and `n_variable` number of variables. 
    """
    pattern = [0] * n_variables
    for current_sum in range(1, order+1):
        pattern[0] = current_sum
        yield tuple(pattern)
        while pattern[-1] < current_sum:
            for i in range(2, n_variables + 1):
                if 0 < pattern[n_variables - i]:
                    pattern[n_variables - i] -= 1
                    if 2 < i:
                        pattern[n_variables - i + 1] = 1 + pattern[-1]
                        pattern[-1] = 0
                    else:
                        pattern[-1] += 1
                    break
            yield tuple(pattern)
        pattern[-1] = 0


I would try writing it recursively so as to generate only the desired elements:

def _gtee_helper(order, n_variables):
    if n_variables == 0:
        yield ()
        return
    for i in range(order + 1):
        for result in _gtee_helper(order - i, n_variables - 1):
            yield (i,) + result


def generalized_taylor_expansion_exponents(order, n_variables):
    """
    Find the exponents of a multivariate polynomial expression of order
    `order` and `n_variable` number of variables. 
    """
    result = _gtee_helper(order, n_variables)
    result.next() # discard the first element, which is all zeros
    return result
0

精彩评论

暂无评论...
验证码 换一张
取 消