def wronskian(functions, var, method='bareis'): """ Compute Wronskian for [] of functions :: | f1 f2 ... fn | | f1' f2' ... fn' | | . . . . | W(f1, ..., fn) = | . . . . | | . . . . | | (n) (n) (n) | | D (f1) D (f2) ... D (fn) | see: http://en.wikipedia.org/wiki/Wronskian See Also ======== sympy.matrices.mutable.Matrix.jacobian hessian """ from dense import Matrix for index in range(0, len(functions)): functions[index] = sympify(functions[index]) n = len(functions) if n == 0: return 1 W = Matrix(n, n, lambda i, j: functions[i].diff(var, j)) return W.det(method)
def ones(r, c=None): """Returns a matrix of ones with ``r`` rows and ``c`` columns; if ``c`` is omitted a square matrix will be returned. See Also ======== zeros eye diag """ from dense import Matrix if is_sequence(r): SymPyDeprecationWarning( feature="The syntax ones([%i, %i])" % tuple(r), useinstead="ones(%i, %i)." % tuple(r), issue=3381, deprecated_since_version="0.7.2", ).warn() r, c = r else: c = r if c is None else c r = as_int(r) c = as_int(c) return Matrix(r, c, [S.One] * r * c)
def __eq__(self, other): try: if self.shape != other.shape: return False if isinstance(other, Matrix): return self._mat == other._mat elif isinstance(other, MatrixBase): return self._mat == Matrix(other)._mat except AttributeError: return False
def _force_mutable(x): """Return a matrix as a Matrix, otherwise return x.""" if getattr(x, 'is_Matrix', False): return x.as_mutable() elif isinstance(x, Basic): return x elif hasattr(x, '__array__'): a = x.__array__() if len(a.shape) == 0: return sympify(a) return Matrix(x) return x
def as_mutable(self): """Returns a mutable version of this matrix Examples ======== >>> from sympy import ImmutableMatrix >>> X = ImmutableMatrix([[1, 2], [3, 4]]) >>> Y = X.as_mutable() >>> Y[1, 1] = 5 # Can set values in Y >>> Y [1, 2] [3, 5] """ return Matrix(self)
def __init__(self, *args): if len(args) == 1 and isinstance(args[0], SparseMatrix): self.rows = args[0].rows self.cols = args[0].cols self._smat = dict(args[0]._smat) return self._smat = {} if len(args) == 3: self.rows = as_int(args[0]) self.cols = as_int(args[1]) if callable(args[2]): op = args[2] for i in range(self.rows): for j in range(self.cols): value = sympify(op(i, j)) if value: self._smat[(i, j)] = value elif isinstance(args[2], (dict, Dict)): # manual copy, copy.deepcopy() doesn't work for key in args[2].keys(): v = args[2][key] if v: self._smat[key] = v elif is_sequence(args[2]): if len(args[2]) != self.rows*self.cols: raise ValueError( 'List length (%s) != rows*columns (%s)' % (len(args[2]), self.rows*self.cols)) flat_list = args[2] for i in range(self.rows): for j in range(self.cols): value = sympify(flat_list[i*self.cols + j]) if value: self._smat[(i, j)] = value else: # handle full matrix forms with _handle_creation_inputs r, c, _list = Matrix._handle_creation_inputs(*args) self.rows = r self.cols = c for i in range(self.rows): for j in range(self.cols): value = _list[self.cols*i + j] if value: self._smat[(i, j)] = value
def __init__(self, *args): if len(args) == 1 and isinstance(args[0], SparseMatrix): self.rows = args[0].rows self.cols = args[0].cols self._smat = dict(args[0]._smat) return self._smat = {} if len(args) == 3: self.rows = as_int(args[0]) self.cols = as_int(args[1]) if callable(args[2]): op = args[2] for i in range(self.rows): for j in range(self.cols): value = self._sympify(op(i, j)) if value: self._smat[(i, j)] = value elif isinstance(args[2], (dict, Dict)): # manual copy, copy.deepcopy() doesn't work for key in args[2].keys(): v = args[2][key] if v: self._smat[key] = v elif is_sequence(args[2]): if len(args[2]) != self.rows*self.cols: raise ValueError( 'List length (%s) != rows*columns (%s)' % (len(args[2]), self.rows*self.cols)) flat_list = args[2] for i in range(self.rows): for j in range(self.cols): value = self._sympify(flat_list[i*self.cols + j]) if value: self._smat[(i, j)] = value else: # handle full matrix forms with _handle_creation_inputs r, c, _list = Matrix._handle_creation_inputs(*args) self.rows = r self.cols = c for i in range(self.rows): for j in range(self.cols): value = _list[self.cols*i + j] if value: self._smat[(i, j)] = value
def casoratian(seqs, n, zero=True): """Given linear difference operator L of order 'k' and homogeneous equation Ly = 0 we want to compute kernel of L, which is a set of 'k' sequences: a(n), b(n), ... z(n). Solutions of L are linearly independent iff their Casoratian, denoted as C(a, b, ..., z), do not vanish for n = 0. Casoratian is defined by k x k determinant:: + a(n) b(n) . . . z(n) + | a(n+1) b(n+1) . . . z(n+1) | | . . . . | | . . . . | | . . . . | + a(n+k-1) b(n+k-1) . . . z(n+k-1) + It proves very useful in rsolve_hyper() where it is applied to a generating set of a recurrence to factor out linearly dependent solutions and return a basis: >>> from sympy import Symbol, casoratian, factorial >>> n = Symbol('n', integer=True) Exponential and factorial are linearly independent: >>> casoratian([2**n, factorial(n)], n) != 0 True """ from dense import Matrix seqs = map(sympify, seqs) if not zero: f = lambda i, j: seqs[j].subs(n, n + i) else: f = lambda i, j: seqs[j].subs(n, i) k = len(seqs) return Matrix(k, k, f).det()
def rot_axis1(theta): """Returns a rotation matrix for a rotation of theta (in radians) about the 1-axis. Examples ======== >>> from sympy import pi >>> from sympy.matrices import rot_axis1 A rotation of pi/3 (60 degrees): >>> theta = pi/3 >>> rot_axis1(theta) Matrix([ [1, 0, 0], [0, 1/2, sqrt(3)/2], [0, -sqrt(3)/2, 1/2]]) If we rotate by pi/2 (90 degrees): >>> rot_axis1(pi/2) Matrix([ [1, 0, 0], [0, 0, 1], [0, -1, 0]]) See Also ======== rot_axis2: Returns a rotation matrix for a rotation of theta (in radians) about the 2-axis rot_axis3: Returns a rotation matrix for a rotation of theta (in radians) about the 3-axis """ ct = cos(theta) st = sin(theta) lil = ((1, 0, 0), (0, ct, st), (0, -st, ct)) return Matrix(lil)
def rot_axis2(theta): """Returns a rotation matrix for a rotation of theta (in radians) about the 2-axis. Examples -------- >>> from sympy import pi >>> from sympy.matrices import rot_axis2 A rotation of pi/3 (60 degrees): >>> theta = pi/3 >>> rot_axis2(theta) [ 1/2, 0, -sqrt(3)/2] [ 0, 1, 0] [sqrt(3)/2, 0, 1/2] If we rotate by pi/2 (90 degrees): >>> rot_axis2(pi/2) [0, 0, -1] [0, 1, 0] [1, 0, 0] See Also ======== rot_axis1: Returns a rotation matrix for a rotation of theta (in radians) about the 1-axis rot_axis3: Returns a rotation matrix for a rotation of theta (in radians) about the 3-axis """ ct = cos(theta) st = sin(theta) lil = ((ct, 0, -st), (0, 1, 0), (st, 0, ct)) return Matrix(lil)
def copyin_list(self, key, value): """Copy in elements from a list. Parameters ========== key : slice The section of this matrix to replace. value : iterable The iterable to copy values from. Examples ======== >>> from sympy.matrices import eye >>> I = eye(3) >>> I[:2, 0] = [1, 2] # col >>> I Matrix([ [1, 0, 0], [2, 1, 0], [0, 0, 1]]) >>> I[1, :2] = [[3, 4]] >>> I Matrix([ [1, 0, 0], [3, 4, 0], [0, 0, 1]]) See Also ======== copyin_matrix """ if not is_sequence(value): raise TypeError("`value` must be an ordered iterable, not %s." % type(value)) return self.copyin_matrix(key, Matrix(value))
def zeros(r, c=None, cls=None): """Returns a matrix of zeros with ``r`` rows and ``c`` columns; if ``c`` is omitted a square matrix will be returned. See Also ======== ones eye diag """ if cls is None: from dense import Matrix as cls if is_sequence(r): SymPyDeprecationWarning( feature="The syntax zeros([%i, %i])" % tuple(r), useinstead="zeros(%i, %i)." % tuple(r), issue=3381, deprecated_since_version="0.7.2", ).warn() r, c = r else: c = r if c is None else c r, c = [int(i) for i in [r, c]] return cls.zeros(r, c)
def randMatrix(r, c=None, min=0, max=99, seed=None, symmetric=False, percent=100): """Create random matrix with dimensions ``r`` x ``c``. If ``c`` is omitted the matrix will be square. If ``symmetric`` is True the matrix must be square. If ``percent`` is less than 100 then only approximately the given percentage of elements will be non-zero. Examples ======== >>> from sympy.matrices import randMatrix >>> randMatrix(3) # doctest:+SKIP [25, 45, 27] [44, 54, 9] [23, 96, 46] >>> randMatrix(3, 2) # doctest:+SKIP [87, 29] [23, 37] [90, 26] >>> randMatrix(3, 3, 0, 2) # doctest:+SKIP [0, 2, 0] [2, 0, 1] [0, 0, 1] >>> randMatrix(3, symmetric=True) # doctest:+SKIP [85, 26, 29] [26, 71, 43] [29, 43, 57] >>> A = randMatrix(3, seed=1) >>> B = randMatrix(3, seed=2) >>> A == B # doctest:+SKIP False >>> A == randMatrix(3, seed=1) True >>> randMatrix(3, symmetric=True, percent=50) # doctest:+SKIP [0, 68, 43] [0, 68, 0] [0, 91, 34] """ if c is None: c = r if seed is None: prng = random.Random() # use system time else: prng = random.Random(seed) if symmetric and r != c: raise ValueError( 'For symmetric matrices, r must equal c, but %i != %i' % (r, c)) if not symmetric: m = Matrix._new(r, c, lambda i, j: prng.randint(min, max)) else: m = zeros(r) for i in range(r): for j in range(i, r): m[i, j] = prng.randint(min, max) for i in range(r): for j in range(i): m[i, j] = m[j, i] if percent == 100: return m else: z = int(r*c*percent // 100) m._mat[:z] = [S.Zero]*z random.shuffle(m._mat) return m
def randMatrix(r, c=None, min=0, max=99, seed=None, symmetric=False, percent=100): """Create random matrix with dimensions ``r`` x ``c``. If ``c`` is omitted the matrix will be square. If ``symmetric`` is True the matrix must be square. If ``percent`` is less than 100 then only approximately the given percentage of elements will be non-zero. Examples ======== >>> from sympy.matrices import randMatrix >>> randMatrix(3) # doctest:+SKIP [25, 45, 27] [44, 54, 9] [23, 96, 46] >>> randMatrix(3, 2) # doctest:+SKIP [87, 29] [23, 37] [90, 26] >>> randMatrix(3, 3, 0, 2) # doctest:+SKIP [0, 2, 0] [2, 0, 1] [0, 0, 1] >>> randMatrix(3, symmetric=True) # doctest:+SKIP [85, 26, 29] [26, 71, 43] [29, 43, 57] >>> A = randMatrix(3, seed=1) >>> B = randMatrix(3, seed=2) >>> A == B # doctest:+SKIP False >>> A == randMatrix(3, seed=1) True >>> randMatrix(3, symmetric=True, percent=50) # doctest:+SKIP [0, 68, 43] [0, 68, 0] [0, 91, 34] """ if c is None: c = r if seed is None: prng = random.Random() # use system time else: prng = random.Random(seed) if symmetric and r != c: raise ValueError( 'For symmetric matrices, r must equal c, but %i != %i' % (r, c)) if not symmetric: m = Matrix._new(r, c, lambda i, j: prng.randint(min, max)) else: m = zeros(r) for i in range(r): for j in range(i, r): m[i, j] = prng.randint(min, max) for i in range(r): for j in range(i): m[i, j] = m[j, i] if percent == 100: return m else: z = int(r*c*percent // 100) m._mat[:z] = [S.Zero]*z prng.shuffle(m._mat) return m
def diag(*values, **kwargs): """Create a sparse, diagonal matrix from a list of diagonal values. Notes ===== When arguments are matrices they are fitted in resultant matrix. The returned matrix is a mutable, dense matrix. To make it a different type, send the desired class for keyword ``cls``. Examples ======== >>> from sympy.matrices import diag, Matrix, ones >>> diag(1, 2, 3) Matrix([ [1, 0, 0], [0, 2, 0], [0, 0, 3]]) >>> diag(*[1, 2, 3]) Matrix([ [1, 0, 0], [0, 2, 0], [0, 0, 3]]) The diagonal elements can be matrices; diagonal filling will continue on the diagonal from the last element of the matrix: >>> from sympy.abc import x, y, z >>> a = Matrix([x, y, z]) >>> b = Matrix([[1, 2], [3, 4]]) >>> c = Matrix([[5, 6]]) >>> diag(a, 7, b, c) Matrix([ [x, 0, 0, 0, 0, 0], [y, 0, 0, 0, 0, 0], [z, 0, 0, 0, 0, 0], [0, 7, 0, 0, 0, 0], [0, 0, 1, 2, 0, 0], [0, 0, 3, 4, 0, 0], [0, 0, 0, 0, 5, 6]]) When diagonal elements are lists, they will be treated as arguments to Matrix: >>> diag([1, 2, 3], 4) Matrix([ [1, 0], [2, 0], [3, 0], [0, 4]]) >>> diag([[1, 2, 3]], 4) Matrix([ [1, 2, 3, 0], [0, 0, 0, 4]]) A given band off the diagonal can be made by padding with a vertical or horizontal "kerning" vector: >>> hpad = ones(0, 2) >>> vpad = ones(2, 0) >>> diag(vpad, 1, 2, 3, hpad) + diag(hpad, 4, 5, 6, vpad) Matrix([ [0, 0, 4, 0, 0], [0, 0, 0, 5, 0], [1, 0, 0, 0, 6], [0, 2, 0, 0, 0], [0, 0, 3, 0, 0]]) The type is mutable by default but can be made immutable by setting the ``mutable`` flag to False: >>> type(diag(1)) <class 'sympy.matrices.dense.MutableDenseMatrix'> >>> from sympy.matrices import ImmutableMatrix >>> type(diag(1, cls=ImmutableMatrix)) <class 'sympy.matrices.immutable.ImmutableMatrix'> See Also ======== eye """ from sparse import MutableSparseMatrix cls = kwargs.pop('cls', None) if cls is None: from dense import Matrix as cls if kwargs: raise ValueError('unrecognized keyword%s: %s' % ( 's' if len(kwargs) > 1 else '', ', '.join(kwargs.keys()))) rows = 0 cols = 0 values = list(values) for i in range(len(values)): m = values[i] if isinstance(m, MatrixBase): rows += m.rows cols += m.cols elif is_sequence(m): m = values[i] = Matrix(m) rows += m.rows cols += m.cols else: rows += 1 cols += 1 res = MutableSparseMatrix.zeros(rows, cols) i_row = 0 i_col = 0 for m in values: if isinstance(m, MatrixBase): res[i_row:i_row + m.rows, i_col:i_col + m.cols] = m i_row += m.rows i_col += m.cols else: res[i_row, i_col] = m i_row += 1 i_col += 1 return cls._new(res)
def copyin_list(self, key, value): if not is_sequence(value): raise TypeError("`value` must be of type list or tuple.") self.copyin_matrix(key, Matrix(value))