Source code for normal_forms.multiindex

import numpy as np
import combinatorics


[docs]class multiindex(object): """A multiindex representation. In this implementation, the multiindex :math:`(m_1,\\ldots,m_n)` corresponds to partial derivative :math:`\\frac{\\partial}{\\partial x_{m_1}}\\cdots\\frac{\\partial}{\\partial x_{m_n}}f` and homogenous :math:`n^{th}` degree monomial :math:`x_1^{m_1}\\cdots x_n^{m_n}`. A 'telephone-book' ordering is used and indices within the multiindex are assumed to be non-decreasing. For example, the multiindices with length ``n=2`` and with indices less than ``idx_max=3`` are, in increasing order: (0,0), (0,1), (0,2), (1,1), (1,2), (2,2). The next multiindex is cycled back to the first multiindex. Attributes ---------- n : int number of indices idx_max : int upper bound, indices can take nonnegative values less than ``idx_max`` """ def __init__(self, n, idx_max): """Initialize zero multiindex.""" self.idx = np.zeros(n, dtype=int) self.idx_max = idx_max
[docs] def increment(self): """Increment multiindex.""" n_idx = len(self.idx) if all(self.idx >= self.idx_max): self.idx = np.zeros(n_idx, dtype=int) else: i = n_idx - 1 self.idx[i] += 1 while self.idx[i] == self.idx_max: i -= 1 self.idx[i] += 1 self.idx[i:] = self.idx[i]
[docs] def to_polynomial(self, var, x=None): """Convert multiindex to corresponding polynomial. Parameters ---------- var : tuple of ``sympy.symbol`` objects list of variables ``x_0``, ``x_1``, ..., ``x_{n-1}`` x : tuple of length n, optional roots of polynomial Returns ------- ``sympy`` expression :math:`\\prod_{i=0}^{n}` ``var[i]`` if ``x`` is not supplied, otherwise :math:`\\prod_{i=0}^{n}` ``var[i]-x[i]`` """ if x == None: return np.product([var[idx] for idx in self.idx]) else: return np.product([var[idx] - x[idx] for idx in self.idx])
[docs] def to_var(self, var): """Convert multiindex to list of variables. Parameters ---------- var : tuple of ``sympy.symbol`` objects list of variables ``x_0``, ``x_1``, ..., ``x_{n-1}`` Returns ------- list of ``sympy.symbol`` objects list of ``var[idx]`` for ``idx`` in ``self.idx`` """ return [var[idx] for idx in self.idx]
[docs] def factorial(self): """Return multiindex factorial. In this implementation, multiindex :math:`m=(m_1,\ldots,m_n)` factorial is defined as :math:`\\alpha_1!\cdots \\alpha_n!` where :math:`\\alpha_i` is the number of occurences of :math:`i` in :math:`m`. Returns ------- int multiindex factorial """ # record number of occurences of idx in self.idx fac_dict = np.zeros(self.idx_max, dtype=int) for idx in self.idx: fac_dict[idx] += 1 # list of factorials fac = combinatorics.factorial_list(int(np.max(fac_dict))) # return multiindex factorial return np.product([fac[key] for key in fac_dict])