Coverage for /usr/lib/python3/dist-packages/sympy/matrices/expressions/funcmatrix.py: 44%
34 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-14 15:55 +0200
1from .matexpr import MatrixExpr
2from sympy.core.function import FunctionClass, Lambda
3from sympy.core.symbol import Dummy
4from sympy.core.sympify import _sympify, sympify
5from sympy.matrices import Matrix
6from sympy.functions.elementary.complexes import re, im
9class FunctionMatrix(MatrixExpr):
10 """Represents a matrix using a function (``Lambda``) which gives
11 outputs according to the coordinates of each matrix entries.
13 Parameters
14 ==========
16 rows : nonnegative integer. Can be symbolic.
18 cols : nonnegative integer. Can be symbolic.
20 lamda : Function, Lambda or str
21 If it is a SymPy ``Function`` or ``Lambda`` instance,
22 it should be able to accept two arguments which represents the
23 matrix coordinates.
25 If it is a pure string containing Python ``lambda`` semantics,
26 it is interpreted by the SymPy parser and casted into a SymPy
27 ``Lambda`` instance.
29 Examples
30 ========
32 Creating a ``FunctionMatrix`` from ``Lambda``:
34 >>> from sympy import FunctionMatrix, symbols, Lambda, MatPow
35 >>> i, j, n, m = symbols('i,j,n,m')
36 >>> FunctionMatrix(n, m, Lambda((i, j), i + j))
37 FunctionMatrix(n, m, Lambda((i, j), i + j))
39 Creating a ``FunctionMatrix`` from a SymPy function:
41 >>> from sympy import KroneckerDelta
42 >>> X = FunctionMatrix(3, 3, KroneckerDelta)
43 >>> X.as_explicit()
44 Matrix([
45 [1, 0, 0],
46 [0, 1, 0],
47 [0, 0, 1]])
49 Creating a ``FunctionMatrix`` from a SymPy undefined function:
51 >>> from sympy import Function
52 >>> f = Function('f')
53 >>> X = FunctionMatrix(3, 3, f)
54 >>> X.as_explicit()
55 Matrix([
56 [f(0, 0), f(0, 1), f(0, 2)],
57 [f(1, 0), f(1, 1), f(1, 2)],
58 [f(2, 0), f(2, 1), f(2, 2)]])
60 Creating a ``FunctionMatrix`` from Python ``lambda``:
62 >>> FunctionMatrix(n, m, 'lambda i, j: i + j')
63 FunctionMatrix(n, m, Lambda((i, j), i + j))
65 Example of lazy evaluation of matrix product:
67 >>> Y = FunctionMatrix(1000, 1000, Lambda((i, j), i + j))
68 >>> isinstance(Y*Y, MatPow) # this is an expression object
69 True
70 >>> (Y**2)[10,10] # So this is evaluated lazily
71 342923500
73 Notes
74 =====
76 This class provides an alternative way to represent an extremely
77 dense matrix with entries in some form of a sequence, in a most
78 sparse way.
79 """
80 def __new__(cls, rows, cols, lamda):
81 rows, cols = _sympify(rows), _sympify(cols)
82 cls._check_dim(rows)
83 cls._check_dim(cols)
85 lamda = sympify(lamda)
86 if not isinstance(lamda, (FunctionClass, Lambda)):
87 raise ValueError(
88 "{} should be compatible with SymPy function classes."
89 .format(lamda))
91 if 2 not in lamda.nargs:
92 raise ValueError(
93 '{} should be able to accept 2 arguments.'.format(lamda))
95 if not isinstance(lamda, Lambda):
96 i, j = Dummy('i'), Dummy('j')
97 lamda = Lambda((i, j), lamda(i, j))
99 return super().__new__(cls, rows, cols, lamda)
101 @property
102 def shape(self):
103 return self.args[0:2]
105 @property
106 def lamda(self):
107 return self.args[2]
109 def _entry(self, i, j, **kwargs):
110 return self.lamda(i, j)
112 def _eval_trace(self):
113 from sympy.matrices.expressions.trace import Trace
114 from sympy.concrete.summations import Sum
115 return Trace(self).rewrite(Sum).doit()
117 def _eval_as_real_imag(self):
118 return (re(Matrix(self)), im(Matrix(self)))