Source code for modelparameters.sympy.holonomic.linearsolver

""" Linear Solver for Holonomic Functions"""

from __future__ import print_function, division

from ..matrices.dense import MutableDenseMatrix
from ..utilities.iterables import flatten, numbered_symbols
from ..core.symbol import Symbol, Dummy, symbols
from .. import S


[docs]class NewMatrix(MutableDenseMatrix): """ Supports elements which can't be Sympified. See docstrings in sympy/matrices/matrices.py """ @staticmethod def _sympify(a): return a
[docs] def row_join(self, rhs): from ..matrices import MutableMatrix # Allows you to build a matrix even if it is null matrix if not self: return type(self)(rhs) if self.rows != rhs.rows: raise ShapeError( "`self` and `rhs` must have the same number of rows.") newmat = NewMatrix.zeros(self.rows, self.cols + rhs.cols) newmat[:, :self.cols] = self newmat[:, self.cols:] = rhs return type(self)(newmat)
[docs] def col_join(self, bott): from ..matrices import MutableMatrix # Allows you to build a matrix even if it is null matrix if not self: return type(self)(bott) if self.cols != bott.cols: raise ShapeError( "`self` and `bott` must have the same number of columns.") newmat = NewMatrix.zeros(self.rows + bott.rows, self.cols) newmat[:self.rows, :] = self newmat[self.rows:, :] = bott return type(self)(newmat)
[docs] def gauss_jordan_solve(self, b, freevar=False): from ..matrices import Matrix, zeros aug = self.hstack(self.copy(), b.copy()) row, col = aug[:, :-1].shape # solve by reduced row echelon form A, pivots = aug.rref() A, v = A[:, :-1], A[:, -1] pivots = list(filter(lambda p: p < col, pivots)) rank = len(pivots) # Bring to block form permutation = Matrix(range(col)).T A = A.vstack(A, permutation) for i, c in enumerate(pivots): A.col_swap(i, c) A, permutation = A[:-1, :], A[-1, :] # check for existence of solutions # rank of aug Matrix should be equal to rank of coefficient matrix if not v[rank:, 0].is_zero: raise ValueError("Linear system has no solution") # Get index of free symbols (free parameters) free_var_index = permutation[len(pivots):] # non-pivots columns are free variables # Free parameters tau = NewMatrix([S(1) for k in range(col - rank)]).reshape(col - rank, 1) # Full parametric solution V = A[:rank, rank:] vt = v[:rank, 0] free_sol = tau.vstack(vt - V*tau, tau) # Undo permutation sol = NewMatrix.zeros(col, 1) for k, v in enumerate(free_sol): sol[permutation[k], 0] = v if freevar: return sol, tau, free_var_index else: return sol, tau