common.py 93 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258
  1. """
  2. A module containing deprecated matrix mixin classes.
  3. The classes in this module are deprecated and will be removed in a future
  4. release. They are kept here for backwards compatibility in case downstream
  5. code was subclassing them.
  6. Importing anything else from this module is deprecated so anything here
  7. should either not be used or should be imported from somewhere else.
  8. """
  9. from __future__ import annotations
  10. from collections import defaultdict
  11. from collections.abc import Iterable
  12. from inspect import isfunction
  13. from functools import reduce
  14. from sympy.assumptions.refine import refine
  15. from sympy.core import SympifyError, Add
  16. from sympy.core.basic import Atom
  17. from sympy.core.decorators import call_highest_priority
  18. from sympy.core.logic import fuzzy_and, FuzzyBool
  19. from sympy.core.numbers import Integer
  20. from sympy.core.mod import Mod
  21. from sympy.core.singleton import S
  22. from sympy.core.symbol import Symbol
  23. from sympy.core.sympify import sympify
  24. from sympy.functions.elementary.complexes import Abs, re, im
  25. from sympy.utilities.exceptions import sympy_deprecation_warning
  26. from .utilities import _dotprodsimp, _simplify
  27. from sympy.polys.polytools import Poly
  28. from sympy.utilities.iterables import flatten, is_sequence
  29. from sympy.utilities.misc import as_int, filldedent
  30. from sympy.tensor.array import NDimArray
  31. from .utilities import _get_intermediate_simp_bool
  32. # These exception types were previously defined in this module but were moved
  33. # to exceptions.py. We reimport them here for backwards compatibility in case
  34. # downstream code was importing them from here.
  35. from .exceptions import ( # noqa: F401
  36. MatrixError, ShapeError, NonSquareMatrixError, NonInvertibleMatrixError,
  37. NonPositiveDefiniteMatrixError
  38. )
  39. _DEPRECATED_MIXINS = (
  40. 'MatrixShaping',
  41. 'MatrixSpecial',
  42. 'MatrixProperties',
  43. 'MatrixOperations',
  44. 'MatrixArithmetic',
  45. 'MatrixCommon',
  46. 'MatrixDeterminant',
  47. 'MatrixReductions',
  48. 'MatrixSubspaces',
  49. 'MatrixEigen',
  50. 'MatrixCalculus',
  51. 'MatrixDeprecated',
  52. )
  53. class _MatrixDeprecatedMeta(type):
  54. #
  55. # Override the default __instancecheck__ implementation to ensure that
  56. # e.g. isinstance(M, MatrixCommon) still works when M is one of the
  57. # matrix classes. Matrix no longer inherits from MatrixCommon so
  58. # isinstance(M, MatrixCommon) would now return False by default.
  59. #
  60. # There were lots of places in the codebase where this was being done
  61. # so it seems likely that downstream code may be doing it too. All use
  62. # of these mixins is deprecated though so we give a deprecation warning
  63. # unconditionally if they are being used with isinstance.
  64. #
  65. # Any code seeing this deprecation warning should be changed to use
  66. # isinstance(M, MatrixBase) instead which also works in previous versions
  67. # of SymPy.
  68. #
  69. def __instancecheck__(cls, instance):
  70. sympy_deprecation_warning(
  71. f"""
  72. Checking whether an object is an instance of {cls.__name__} is
  73. deprecated.
  74. Use `isinstance(obj, Matrix)` instead of `isinstance(obj, {cls.__name__})`.
  75. """,
  76. deprecated_since_version="1.13",
  77. active_deprecations_target="deprecated-matrix-mixins",
  78. stacklevel=3,
  79. )
  80. from sympy.matrices.matrixbase import MatrixBase
  81. from sympy.matrices.matrices import (
  82. MatrixDeterminant,
  83. MatrixReductions,
  84. MatrixSubspaces,
  85. MatrixEigen,
  86. MatrixCalculus,
  87. MatrixDeprecated
  88. )
  89. all_mixins = (
  90. MatrixRequired,
  91. MatrixShaping,
  92. MatrixSpecial,
  93. MatrixProperties,
  94. MatrixOperations,
  95. MatrixArithmetic,
  96. MatrixCommon,
  97. MatrixDeterminant,
  98. MatrixReductions,
  99. MatrixSubspaces,
  100. MatrixEigen,
  101. MatrixCalculus,
  102. MatrixDeprecated
  103. )
  104. if cls in all_mixins and isinstance(instance, MatrixBase):
  105. return True
  106. else:
  107. return super().__instancecheck__(instance)
  108. class MatrixRequired(metaclass=_MatrixDeprecatedMeta):
  109. """Deprecated mixin class for making matrix classes."""
  110. rows: int
  111. cols: int
  112. _simplify = None
  113. def __init_subclass__(cls, **kwargs):
  114. # Warn if any downstream code is subclassing this class or any of the
  115. # deprecated mixin classes that are all ultimately subclasses of this
  116. # class.
  117. #
  118. # We don't want to warn about the deprecated mixins themselves being
  119. # created, but only about them being used as mixins by downstream code.
  120. # Otherwise just importing this module would trigger a warning.
  121. # Ultimately the whole module should be deprecated and removed but for
  122. # SymPy 1.13 it is premature to do that given that this module was the
  123. # main way to import matrix exception types in all previous versions.
  124. if cls.__name__ not in _DEPRECATED_MIXINS:
  125. sympy_deprecation_warning(
  126. f"""
  127. Inheriting from the Matrix mixin classes is deprecated.
  128. The class {cls.__name__} is subclassing a deprecated mixin.
  129. """,
  130. deprecated_since_version="1.13",
  131. active_deprecations_target="deprecated-matrix-mixins",
  132. stacklevel=3,
  133. )
  134. super().__init_subclass__(**kwargs)
  135. @classmethod
  136. def _new(cls, *args, **kwargs):
  137. """`_new` must, at minimum, be callable as
  138. `_new(rows, cols, mat) where mat is a flat list of the
  139. elements of the matrix."""
  140. raise NotImplementedError("Subclasses must implement this.")
  141. def __eq__(self, other):
  142. raise NotImplementedError("Subclasses must implement this.")
  143. def __getitem__(self, key):
  144. """Implementations of __getitem__ should accept ints, in which
  145. case the matrix is indexed as a flat list, tuples (i,j) in which
  146. case the (i,j) entry is returned, slices, or mixed tuples (a,b)
  147. where a and b are any combination of slices and integers."""
  148. raise NotImplementedError("Subclasses must implement this.")
  149. def __len__(self):
  150. """The total number of entries in the matrix."""
  151. raise NotImplementedError("Subclasses must implement this.")
  152. @property
  153. def shape(self):
  154. raise NotImplementedError("Subclasses must implement this.")
  155. class MatrixShaping(MatrixRequired):
  156. """Provides basic matrix shaping and extracting of submatrices"""
  157. def _eval_col_del(self, col):
  158. def entry(i, j):
  159. return self[i, j] if j < col else self[i, j + 1]
  160. return self._new(self.rows, self.cols - 1, entry)
  161. def _eval_col_insert(self, pos, other):
  162. def entry(i, j):
  163. if j < pos:
  164. return self[i, j]
  165. elif pos <= j < pos + other.cols:
  166. return other[i, j - pos]
  167. return self[i, j - other.cols]
  168. return self._new(self.rows, self.cols + other.cols, entry)
  169. def _eval_col_join(self, other):
  170. rows = self.rows
  171. def entry(i, j):
  172. if i < rows:
  173. return self[i, j]
  174. return other[i - rows, j]
  175. return classof(self, other)._new(self.rows + other.rows, self.cols,
  176. entry)
  177. def _eval_extract(self, rowsList, colsList):
  178. mat = list(self)
  179. cols = self.cols
  180. indices = (i * cols + j for i in rowsList for j in colsList)
  181. return self._new(len(rowsList), len(colsList),
  182. [mat[i] for i in indices])
  183. def _eval_get_diag_blocks(self):
  184. sub_blocks = []
  185. def recurse_sub_blocks(M):
  186. for i in range(1, M.shape[0] + 1):
  187. if i == 1:
  188. to_the_right = M[0, i:]
  189. to_the_bottom = M[i:, 0]
  190. else:
  191. to_the_right = M[:i, i:]
  192. to_the_bottom = M[i:, :i]
  193. if any(to_the_right) or any(to_the_bottom):
  194. continue
  195. sub_blocks.append(M[:i, :i])
  196. if M.shape != M[:i, :i].shape:
  197. recurse_sub_blocks(M[i:, i:])
  198. return
  199. recurse_sub_blocks(self)
  200. return sub_blocks
  201. def _eval_row_del(self, row):
  202. def entry(i, j):
  203. return self[i, j] if i < row else self[i + 1, j]
  204. return self._new(self.rows - 1, self.cols, entry)
  205. def _eval_row_insert(self, pos, other):
  206. entries = list(self)
  207. insert_pos = pos * self.cols
  208. entries[insert_pos:insert_pos] = list(other)
  209. return self._new(self.rows + other.rows, self.cols, entries)
  210. def _eval_row_join(self, other):
  211. cols = self.cols
  212. def entry(i, j):
  213. if j < cols:
  214. return self[i, j]
  215. return other[i, j - cols]
  216. return classof(self, other)._new(self.rows, self.cols + other.cols,
  217. entry)
  218. def _eval_tolist(self):
  219. return [list(self[i,:]) for i in range(self.rows)]
  220. def _eval_todok(self):
  221. dok = {}
  222. rows, cols = self.shape
  223. for i in range(rows):
  224. for j in range(cols):
  225. val = self[i, j]
  226. if val != self.zero:
  227. dok[i, j] = val
  228. return dok
  229. def _eval_vec(self):
  230. rows = self.rows
  231. def entry(n, _):
  232. # we want to read off the columns first
  233. j = n // rows
  234. i = n - j * rows
  235. return self[i, j]
  236. return self._new(len(self), 1, entry)
  237. def _eval_vech(self, diagonal):
  238. c = self.cols
  239. v = []
  240. if diagonal:
  241. for j in range(c):
  242. for i in range(j, c):
  243. v.append(self[i, j])
  244. else:
  245. for j in range(c):
  246. for i in range(j + 1, c):
  247. v.append(self[i, j])
  248. return self._new(len(v), 1, v)
  249. def col_del(self, col):
  250. """Delete the specified column."""
  251. if col < 0:
  252. col += self.cols
  253. if not 0 <= col < self.cols:
  254. raise IndexError("Column {} is out of range.".format(col))
  255. return self._eval_col_del(col)
  256. def col_insert(self, pos, other):
  257. """Insert one or more columns at the given column position.
  258. Examples
  259. ========
  260. >>> from sympy import zeros, ones
  261. >>> M = zeros(3)
  262. >>> V = ones(3, 1)
  263. >>> M.col_insert(1, V)
  264. Matrix([
  265. [0, 1, 0, 0],
  266. [0, 1, 0, 0],
  267. [0, 1, 0, 0]])
  268. See Also
  269. ========
  270. col
  271. row_insert
  272. """
  273. # Allows you to build a matrix even if it is null matrix
  274. if not self:
  275. return type(self)(other)
  276. pos = as_int(pos)
  277. if pos < 0:
  278. pos = self.cols + pos
  279. if pos < 0:
  280. pos = 0
  281. elif pos > self.cols:
  282. pos = self.cols
  283. if self.rows != other.rows:
  284. raise ShapeError(
  285. "The matrices have incompatible number of rows ({} and {})"
  286. .format(self.rows, other.rows))
  287. return self._eval_col_insert(pos, other)
  288. def col_join(self, other):
  289. """Concatenates two matrices along self's last and other's first row.
  290. Examples
  291. ========
  292. >>> from sympy import zeros, ones
  293. >>> M = zeros(3)
  294. >>> V = ones(1, 3)
  295. >>> M.col_join(V)
  296. Matrix([
  297. [0, 0, 0],
  298. [0, 0, 0],
  299. [0, 0, 0],
  300. [1, 1, 1]])
  301. See Also
  302. ========
  303. col
  304. row_join
  305. """
  306. # A null matrix can always be stacked (see #10770)
  307. if self.rows == 0 and self.cols != other.cols:
  308. return self._new(0, other.cols, []).col_join(other)
  309. if self.cols != other.cols:
  310. raise ShapeError(
  311. "The matrices have incompatible number of columns ({} and {})"
  312. .format(self.cols, other.cols))
  313. return self._eval_col_join(other)
  314. def col(self, j):
  315. """Elementary column selector.
  316. Examples
  317. ========
  318. >>> from sympy import eye
  319. >>> eye(2).col(0)
  320. Matrix([
  321. [1],
  322. [0]])
  323. See Also
  324. ========
  325. row
  326. col_del
  327. col_join
  328. col_insert
  329. """
  330. return self[:, j]
  331. def extract(self, rowsList, colsList):
  332. r"""Return a submatrix by specifying a list of rows and columns.
  333. Negative indices can be given. All indices must be in the range
  334. $-n \le i < n$ where $n$ is the number of rows or columns.
  335. Examples
  336. ========
  337. >>> from sympy import Matrix
  338. >>> m = Matrix(4, 3, range(12))
  339. >>> m
  340. Matrix([
  341. [0, 1, 2],
  342. [3, 4, 5],
  343. [6, 7, 8],
  344. [9, 10, 11]])
  345. >>> m.extract([0, 1, 3], [0, 1])
  346. Matrix([
  347. [0, 1],
  348. [3, 4],
  349. [9, 10]])
  350. Rows or columns can be repeated:
  351. >>> m.extract([0, 0, 1], [-1])
  352. Matrix([
  353. [2],
  354. [2],
  355. [5]])
  356. Every other row can be taken by using range to provide the indices:
  357. >>> m.extract(range(0, m.rows, 2), [-1])
  358. Matrix([
  359. [2],
  360. [8]])
  361. RowsList or colsList can also be a list of booleans, in which case
  362. the rows or columns corresponding to the True values will be selected:
  363. >>> m.extract([0, 1, 2, 3], [True, False, True])
  364. Matrix([
  365. [0, 2],
  366. [3, 5],
  367. [6, 8],
  368. [9, 11]])
  369. """
  370. if not is_sequence(rowsList) or not is_sequence(colsList):
  371. raise TypeError("rowsList and colsList must be iterable")
  372. # ensure rowsList and colsList are lists of integers
  373. if rowsList and all(isinstance(i, bool) for i in rowsList):
  374. rowsList = [index for index, item in enumerate(rowsList) if item]
  375. if colsList and all(isinstance(i, bool) for i in colsList):
  376. colsList = [index for index, item in enumerate(colsList) if item]
  377. # ensure everything is in range
  378. rowsList = [a2idx(k, self.rows) for k in rowsList]
  379. colsList = [a2idx(k, self.cols) for k in colsList]
  380. return self._eval_extract(rowsList, colsList)
  381. def get_diag_blocks(self):
  382. """Obtains the square sub-matrices on the main diagonal of a square matrix.
  383. Useful for inverting symbolic matrices or solving systems of
  384. linear equations which may be decoupled by having a block diagonal
  385. structure.
  386. Examples
  387. ========
  388. >>> from sympy import Matrix
  389. >>> from sympy.abc import x, y, z
  390. >>> A = Matrix([[1, 3, 0, 0], [y, z*z, 0, 0], [0, 0, x, 0], [0, 0, 0, 0]])
  391. >>> a1, a2, a3 = A.get_diag_blocks()
  392. >>> a1
  393. Matrix([
  394. [1, 3],
  395. [y, z**2]])
  396. >>> a2
  397. Matrix([[x]])
  398. >>> a3
  399. Matrix([[0]])
  400. """
  401. return self._eval_get_diag_blocks()
  402. @classmethod
  403. def hstack(cls, *args):
  404. """Return a matrix formed by joining args horizontally (i.e.
  405. by repeated application of row_join).
  406. Examples
  407. ========
  408. >>> from sympy import Matrix, eye
  409. >>> Matrix.hstack(eye(2), 2*eye(2))
  410. Matrix([
  411. [1, 0, 2, 0],
  412. [0, 1, 0, 2]])
  413. """
  414. if len(args) == 0:
  415. return cls._new()
  416. kls = type(args[0])
  417. return reduce(kls.row_join, args)
  418. def reshape(self, rows, cols):
  419. """Reshape the matrix. Total number of elements must remain the same.
  420. Examples
  421. ========
  422. >>> from sympy import Matrix
  423. >>> m = Matrix(2, 3, lambda i, j: 1)
  424. >>> m
  425. Matrix([
  426. [1, 1, 1],
  427. [1, 1, 1]])
  428. >>> m.reshape(1, 6)
  429. Matrix([[1, 1, 1, 1, 1, 1]])
  430. >>> m.reshape(3, 2)
  431. Matrix([
  432. [1, 1],
  433. [1, 1],
  434. [1, 1]])
  435. """
  436. if self.rows * self.cols != rows * cols:
  437. raise ValueError("Invalid reshape parameters %d %d" % (rows, cols))
  438. return self._new(rows, cols, lambda i, j: self[i * cols + j])
  439. def row_del(self, row):
  440. """Delete the specified row."""
  441. if row < 0:
  442. row += self.rows
  443. if not 0 <= row < self.rows:
  444. raise IndexError("Row {} is out of range.".format(row))
  445. return self._eval_row_del(row)
  446. def row_insert(self, pos, other):
  447. """Insert one or more rows at the given row position.
  448. Examples
  449. ========
  450. >>> from sympy import zeros, ones
  451. >>> M = zeros(3)
  452. >>> V = ones(1, 3)
  453. >>> M.row_insert(1, V)
  454. Matrix([
  455. [0, 0, 0],
  456. [1, 1, 1],
  457. [0, 0, 0],
  458. [0, 0, 0]])
  459. See Also
  460. ========
  461. row
  462. col_insert
  463. """
  464. # Allows you to build a matrix even if it is null matrix
  465. if not self:
  466. return self._new(other)
  467. pos = as_int(pos)
  468. if pos < 0:
  469. pos = self.rows + pos
  470. if pos < 0:
  471. pos = 0
  472. elif pos > self.rows:
  473. pos = self.rows
  474. if self.cols != other.cols:
  475. raise ShapeError(
  476. "The matrices have incompatible number of columns ({} and {})"
  477. .format(self.cols, other.cols))
  478. return self._eval_row_insert(pos, other)
  479. def row_join(self, other):
  480. """Concatenates two matrices along self's last and rhs's first column
  481. Examples
  482. ========
  483. >>> from sympy import zeros, ones
  484. >>> M = zeros(3)
  485. >>> V = ones(3, 1)
  486. >>> M.row_join(V)
  487. Matrix([
  488. [0, 0, 0, 1],
  489. [0, 0, 0, 1],
  490. [0, 0, 0, 1]])
  491. See Also
  492. ========
  493. row
  494. col_join
  495. """
  496. # A null matrix can always be stacked (see #10770)
  497. if self.cols == 0 and self.rows != other.rows:
  498. return self._new(other.rows, 0, []).row_join(other)
  499. if self.rows != other.rows:
  500. raise ShapeError(
  501. "The matrices have incompatible number of rows ({} and {})"
  502. .format(self.rows, other.rows))
  503. return self._eval_row_join(other)
  504. def diagonal(self, k=0):
  505. """Returns the kth diagonal of self. The main diagonal
  506. corresponds to `k=0`; diagonals above and below correspond to
  507. `k > 0` and `k < 0`, respectively. The values of `self[i, j]`
  508. for which `j - i = k`, are returned in order of increasing
  509. `i + j`, starting with `i + j = |k|`.
  510. Examples
  511. ========
  512. >>> from sympy import Matrix
  513. >>> m = Matrix(3, 3, lambda i, j: j - i); m
  514. Matrix([
  515. [ 0, 1, 2],
  516. [-1, 0, 1],
  517. [-2, -1, 0]])
  518. >>> _.diagonal()
  519. Matrix([[0, 0, 0]])
  520. >>> m.diagonal(1)
  521. Matrix([[1, 1]])
  522. >>> m.diagonal(-2)
  523. Matrix([[-2]])
  524. Even though the diagonal is returned as a Matrix, the element
  525. retrieval can be done with a single index:
  526. >>> Matrix.diag(1, 2, 3).diagonal()[1] # instead of [0, 1]
  527. 2
  528. See Also
  529. ========
  530. diag
  531. """
  532. rv = []
  533. k = as_int(k)
  534. r = 0 if k > 0 else -k
  535. c = 0 if r else k
  536. while True:
  537. if r == self.rows or c == self.cols:
  538. break
  539. rv.append(self[r, c])
  540. r += 1
  541. c += 1
  542. if not rv:
  543. raise ValueError(filldedent('''
  544. The %s diagonal is out of range [%s, %s]''' % (
  545. k, 1 - self.rows, self.cols - 1)))
  546. return self._new(1, len(rv), rv)
  547. def row(self, i):
  548. """Elementary row selector.
  549. Examples
  550. ========
  551. >>> from sympy import eye
  552. >>> eye(2).row(0)
  553. Matrix([[1, 0]])
  554. See Also
  555. ========
  556. col
  557. row_del
  558. row_join
  559. row_insert
  560. """
  561. return self[i, :]
  562. @property
  563. def shape(self):
  564. """The shape (dimensions) of the matrix as the 2-tuple (rows, cols).
  565. Examples
  566. ========
  567. >>> from sympy import zeros
  568. >>> M = zeros(2, 3)
  569. >>> M.shape
  570. (2, 3)
  571. >>> M.rows
  572. 2
  573. >>> M.cols
  574. 3
  575. """
  576. return (self.rows, self.cols)
  577. def todok(self):
  578. """Return the matrix as dictionary of keys.
  579. Examples
  580. ========
  581. >>> from sympy import Matrix
  582. >>> M = Matrix.eye(3)
  583. >>> M.todok()
  584. {(0, 0): 1, (1, 1): 1, (2, 2): 1}
  585. """
  586. return self._eval_todok()
  587. def tolist(self):
  588. """Return the Matrix as a nested Python list.
  589. Examples
  590. ========
  591. >>> from sympy import Matrix, ones
  592. >>> m = Matrix(3, 3, range(9))
  593. >>> m
  594. Matrix([
  595. [0, 1, 2],
  596. [3, 4, 5],
  597. [6, 7, 8]])
  598. >>> m.tolist()
  599. [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
  600. >>> ones(3, 0).tolist()
  601. [[], [], []]
  602. When there are no rows then it will not be possible to tell how
  603. many columns were in the original matrix:
  604. >>> ones(0, 3).tolist()
  605. []
  606. """
  607. if not self.rows:
  608. return []
  609. if not self.cols:
  610. return [[] for i in range(self.rows)]
  611. return self._eval_tolist()
  612. def todod(M):
  613. """Returns matrix as dict of dicts containing non-zero elements of the Matrix
  614. Examples
  615. ========
  616. >>> from sympy import Matrix
  617. >>> A = Matrix([[0, 1],[0, 3]])
  618. >>> A
  619. Matrix([
  620. [0, 1],
  621. [0, 3]])
  622. >>> A.todod()
  623. {0: {1: 1}, 1: {1: 3}}
  624. """
  625. rowsdict = {}
  626. Mlol = M.tolist()
  627. for i, Mi in enumerate(Mlol):
  628. row = {j: Mij for j, Mij in enumerate(Mi) if Mij}
  629. if row:
  630. rowsdict[i] = row
  631. return rowsdict
  632. def vec(self):
  633. """Return the Matrix converted into a one column matrix by stacking columns
  634. Examples
  635. ========
  636. >>> from sympy import Matrix
  637. >>> m=Matrix([[1, 3], [2, 4]])
  638. >>> m
  639. Matrix([
  640. [1, 3],
  641. [2, 4]])
  642. >>> m.vec()
  643. Matrix([
  644. [1],
  645. [2],
  646. [3],
  647. [4]])
  648. See Also
  649. ========
  650. vech
  651. """
  652. return self._eval_vec()
  653. def vech(self, diagonal=True, check_symmetry=True):
  654. """Reshapes the matrix into a column vector by stacking the
  655. elements in the lower triangle.
  656. Parameters
  657. ==========
  658. diagonal : bool, optional
  659. If ``True``, it includes the diagonal elements.
  660. check_symmetry : bool, optional
  661. If ``True``, it checks whether the matrix is symmetric.
  662. Examples
  663. ========
  664. >>> from sympy import Matrix
  665. >>> m=Matrix([[1, 2], [2, 3]])
  666. >>> m
  667. Matrix([
  668. [1, 2],
  669. [2, 3]])
  670. >>> m.vech()
  671. Matrix([
  672. [1],
  673. [2],
  674. [3]])
  675. >>> m.vech(diagonal=False)
  676. Matrix([[2]])
  677. Notes
  678. =====
  679. This should work for symmetric matrices and ``vech`` can
  680. represent symmetric matrices in vector form with less size than
  681. ``vec``.
  682. See Also
  683. ========
  684. vec
  685. """
  686. if not self.is_square:
  687. raise NonSquareMatrixError
  688. if check_symmetry and not self.is_symmetric():
  689. raise ValueError("The matrix is not symmetric.")
  690. return self._eval_vech(diagonal)
  691. @classmethod
  692. def vstack(cls, *args):
  693. """Return a matrix formed by joining args vertically (i.e.
  694. by repeated application of col_join).
  695. Examples
  696. ========
  697. >>> from sympy import Matrix, eye
  698. >>> Matrix.vstack(eye(2), 2*eye(2))
  699. Matrix([
  700. [1, 0],
  701. [0, 1],
  702. [2, 0],
  703. [0, 2]])
  704. """
  705. if len(args) == 0:
  706. return cls._new()
  707. kls = type(args[0])
  708. return reduce(kls.col_join, args)
  709. class MatrixSpecial(MatrixRequired):
  710. """Construction of special matrices"""
  711. @classmethod
  712. def _eval_diag(cls, rows, cols, diag_dict):
  713. """diag_dict is a defaultdict containing
  714. all the entries of the diagonal matrix."""
  715. def entry(i, j):
  716. return diag_dict[(i, j)]
  717. return cls._new(rows, cols, entry)
  718. @classmethod
  719. def _eval_eye(cls, rows, cols):
  720. vals = [cls.zero]*(rows*cols)
  721. vals[::cols+1] = [cls.one]*min(rows, cols)
  722. return cls._new(rows, cols, vals, copy=False)
  723. @classmethod
  724. def _eval_jordan_block(cls, size: int, eigenvalue, band='upper'):
  725. if band == 'lower':
  726. def entry(i, j):
  727. if i == j:
  728. return eigenvalue
  729. elif j + 1 == i:
  730. return cls.one
  731. return cls.zero
  732. else:
  733. def entry(i, j):
  734. if i == j:
  735. return eigenvalue
  736. elif i + 1 == j:
  737. return cls.one
  738. return cls.zero
  739. return cls._new(size, size, entry)
  740. @classmethod
  741. def _eval_ones(cls, rows, cols):
  742. def entry(i, j):
  743. return cls.one
  744. return cls._new(rows, cols, entry)
  745. @classmethod
  746. def _eval_zeros(cls, rows, cols):
  747. return cls._new(rows, cols, [cls.zero]*(rows*cols), copy=False)
  748. @classmethod
  749. def _eval_wilkinson(cls, n):
  750. def entry(i, j):
  751. return cls.one if i + 1 == j else cls.zero
  752. D = cls._new(2*n + 1, 2*n + 1, entry)
  753. wminus = cls.diag(list(range(-n, n + 1)), unpack=True) + D + D.T
  754. wplus = abs(cls.diag(list(range(-n, n + 1)), unpack=True)) + D + D.T
  755. return wminus, wplus
  756. @classmethod
  757. def diag(kls, *args, strict=False, unpack=True, rows=None, cols=None, **kwargs):
  758. """Returns a matrix with the specified diagonal.
  759. If matrices are passed, a block-diagonal matrix
  760. is created (i.e. the "direct sum" of the matrices).
  761. kwargs
  762. ======
  763. rows : rows of the resulting matrix; computed if
  764. not given.
  765. cols : columns of the resulting matrix; computed if
  766. not given.
  767. cls : class for the resulting matrix
  768. unpack : bool which, when True (default), unpacks a single
  769. sequence rather than interpreting it as a Matrix.
  770. strict : bool which, when False (default), allows Matrices to
  771. have variable-length rows.
  772. Examples
  773. ========
  774. >>> from sympy import Matrix
  775. >>> Matrix.diag(1, 2, 3)
  776. Matrix([
  777. [1, 0, 0],
  778. [0, 2, 0],
  779. [0, 0, 3]])
  780. The current default is to unpack a single sequence. If this is
  781. not desired, set `unpack=False` and it will be interpreted as
  782. a matrix.
  783. >>> Matrix.diag([1, 2, 3]) == Matrix.diag(1, 2, 3)
  784. True
  785. When more than one element is passed, each is interpreted as
  786. something to put on the diagonal. Lists are converted to
  787. matrices. Filling of the diagonal always continues from
  788. the bottom right hand corner of the previous item: this
  789. will create a block-diagonal matrix whether the matrices
  790. are square or not.
  791. >>> col = [1, 2, 3]
  792. >>> row = [[4, 5]]
  793. >>> Matrix.diag(col, row)
  794. Matrix([
  795. [1, 0, 0],
  796. [2, 0, 0],
  797. [3, 0, 0],
  798. [0, 4, 5]])
  799. When `unpack` is False, elements within a list need not all be
  800. of the same length. Setting `strict` to True would raise a
  801. ValueError for the following:
  802. >>> Matrix.diag([[1, 2, 3], [4, 5], [6]], unpack=False)
  803. Matrix([
  804. [1, 2, 3],
  805. [4, 5, 0],
  806. [6, 0, 0]])
  807. The type of the returned matrix can be set with the ``cls``
  808. keyword.
  809. >>> from sympy import ImmutableMatrix
  810. >>> from sympy.utilities.misc import func_name
  811. >>> func_name(Matrix.diag(1, cls=ImmutableMatrix))
  812. 'ImmutableDenseMatrix'
  813. A zero dimension matrix can be used to position the start of
  814. the filling at the start of an arbitrary row or column:
  815. >>> from sympy import ones
  816. >>> r2 = ones(0, 2)
  817. >>> Matrix.diag(r2, 1, 2)
  818. Matrix([
  819. [0, 0, 1, 0],
  820. [0, 0, 0, 2]])
  821. See Also
  822. ========
  823. eye
  824. diagonal
  825. .dense.diag
  826. .expressions.blockmatrix.BlockMatrix
  827. .sparsetools.banded
  828. """
  829. from sympy.matrices.matrixbase import MatrixBase
  830. from sympy.matrices.dense import Matrix
  831. from sympy.matrices import SparseMatrix
  832. klass = kwargs.get('cls', kls)
  833. if unpack and len(args) == 1 and is_sequence(args[0]) and \
  834. not isinstance(args[0], MatrixBase):
  835. args = args[0]
  836. # fill a default dict with the diagonal entries
  837. diag_entries = defaultdict(int)
  838. rmax = cmax = 0 # keep track of the biggest index seen
  839. for m in args:
  840. if isinstance(m, list):
  841. if strict:
  842. # if malformed, Matrix will raise an error
  843. _ = Matrix(m)
  844. r, c = _.shape
  845. m = _.tolist()
  846. else:
  847. r, c, smat = SparseMatrix._handle_creation_inputs(m)
  848. for (i, j), _ in smat.items():
  849. diag_entries[(i + rmax, j + cmax)] = _
  850. m = [] # to skip process below
  851. elif hasattr(m, 'shape'): # a Matrix
  852. # convert to list of lists
  853. r, c = m.shape
  854. m = m.tolist()
  855. else: # in this case, we're a single value
  856. diag_entries[(rmax, cmax)] = m
  857. rmax += 1
  858. cmax += 1
  859. continue
  860. # process list of lists
  861. for i, mi in enumerate(m):
  862. for j, _ in enumerate(mi):
  863. diag_entries[(i + rmax, j + cmax)] = _
  864. rmax += r
  865. cmax += c
  866. if rows is None:
  867. rows, cols = cols, rows
  868. if rows is None:
  869. rows, cols = rmax, cmax
  870. else:
  871. cols = rows if cols is None else cols
  872. if rows < rmax or cols < cmax:
  873. raise ValueError(filldedent('''
  874. The constructed matrix is {} x {} but a size of {} x {}
  875. was specified.'''.format(rmax, cmax, rows, cols)))
  876. return klass._eval_diag(rows, cols, diag_entries)
  877. @classmethod
  878. def eye(kls, rows, cols=None, **kwargs):
  879. """Returns an identity matrix.
  880. Parameters
  881. ==========
  882. rows : rows of the matrix
  883. cols : cols of the matrix (if None, cols=rows)
  884. kwargs
  885. ======
  886. cls : class of the returned matrix
  887. """
  888. if cols is None:
  889. cols = rows
  890. if rows < 0 or cols < 0:
  891. raise ValueError("Cannot create a {} x {} matrix. "
  892. "Both dimensions must be positive".format(rows, cols))
  893. klass = kwargs.get('cls', kls)
  894. rows, cols = as_int(rows), as_int(cols)
  895. return klass._eval_eye(rows, cols)
  896. @classmethod
  897. def jordan_block(kls, size=None, eigenvalue=None, *, band='upper', **kwargs):
  898. """Returns a Jordan block
  899. Parameters
  900. ==========
  901. size : Integer, optional
  902. Specifies the shape of the Jordan block matrix.
  903. eigenvalue : Number or Symbol
  904. Specifies the value for the main diagonal of the matrix.
  905. .. note::
  906. The keyword ``eigenval`` is also specified as an alias
  907. of this keyword, but it is not recommended to use.
  908. We may deprecate the alias in later release.
  909. band : 'upper' or 'lower', optional
  910. Specifies the position of the off-diagonal to put `1` s on.
  911. cls : Matrix, optional
  912. Specifies the matrix class of the output form.
  913. If it is not specified, the class type where the method is
  914. being executed on will be returned.
  915. Returns
  916. =======
  917. Matrix
  918. A Jordan block matrix.
  919. Raises
  920. ======
  921. ValueError
  922. If insufficient arguments are given for matrix size
  923. specification, or no eigenvalue is given.
  924. Examples
  925. ========
  926. Creating a default Jordan block:
  927. >>> from sympy import Matrix
  928. >>> from sympy.abc import x
  929. >>> Matrix.jordan_block(4, x)
  930. Matrix([
  931. [x, 1, 0, 0],
  932. [0, x, 1, 0],
  933. [0, 0, x, 1],
  934. [0, 0, 0, x]])
  935. Creating an alternative Jordan block matrix where `1` is on
  936. lower off-diagonal:
  937. >>> Matrix.jordan_block(4, x, band='lower')
  938. Matrix([
  939. [x, 0, 0, 0],
  940. [1, x, 0, 0],
  941. [0, 1, x, 0],
  942. [0, 0, 1, x]])
  943. Creating a Jordan block with keyword arguments
  944. >>> Matrix.jordan_block(size=4, eigenvalue=x)
  945. Matrix([
  946. [x, 1, 0, 0],
  947. [0, x, 1, 0],
  948. [0, 0, x, 1],
  949. [0, 0, 0, x]])
  950. References
  951. ==========
  952. .. [1] https://en.wikipedia.org/wiki/Jordan_matrix
  953. """
  954. klass = kwargs.pop('cls', kls)
  955. eigenval = kwargs.get('eigenval', None)
  956. if eigenvalue is None and eigenval is None:
  957. raise ValueError("Must supply an eigenvalue")
  958. elif eigenvalue != eigenval and None not in (eigenval, eigenvalue):
  959. raise ValueError(
  960. "Inconsistent values are given: 'eigenval'={}, "
  961. "'eigenvalue'={}".format(eigenval, eigenvalue))
  962. else:
  963. if eigenval is not None:
  964. eigenvalue = eigenval
  965. if size is None:
  966. raise ValueError("Must supply a matrix size")
  967. size = as_int(size)
  968. return klass._eval_jordan_block(size, eigenvalue, band)
  969. @classmethod
  970. def ones(kls, rows, cols=None, **kwargs):
  971. """Returns a matrix of ones.
  972. Parameters
  973. ==========
  974. rows : rows of the matrix
  975. cols : cols of the matrix (if None, cols=rows)
  976. kwargs
  977. ======
  978. cls : class of the returned matrix
  979. """
  980. if cols is None:
  981. cols = rows
  982. klass = kwargs.get('cls', kls)
  983. rows, cols = as_int(rows), as_int(cols)
  984. return klass._eval_ones(rows, cols)
  985. @classmethod
  986. def zeros(kls, rows, cols=None, **kwargs):
  987. """Returns a matrix of zeros.
  988. Parameters
  989. ==========
  990. rows : rows of the matrix
  991. cols : cols of the matrix (if None, cols=rows)
  992. kwargs
  993. ======
  994. cls : class of the returned matrix
  995. """
  996. if cols is None:
  997. cols = rows
  998. if rows < 0 or cols < 0:
  999. raise ValueError("Cannot create a {} x {} matrix. "
  1000. "Both dimensions must be positive".format(rows, cols))
  1001. klass = kwargs.get('cls', kls)
  1002. rows, cols = as_int(rows), as_int(cols)
  1003. return klass._eval_zeros(rows, cols)
  1004. @classmethod
  1005. def companion(kls, poly):
  1006. """Returns a companion matrix of a polynomial.
  1007. Examples
  1008. ========
  1009. >>> from sympy import Matrix, Poly, Symbol, symbols
  1010. >>> x = Symbol('x')
  1011. >>> c0, c1, c2, c3, c4 = symbols('c0:5')
  1012. >>> p = Poly(c0 + c1*x + c2*x**2 + c3*x**3 + c4*x**4 + x**5, x)
  1013. >>> Matrix.companion(p)
  1014. Matrix([
  1015. [0, 0, 0, 0, -c0],
  1016. [1, 0, 0, 0, -c1],
  1017. [0, 1, 0, 0, -c2],
  1018. [0, 0, 1, 0, -c3],
  1019. [0, 0, 0, 1, -c4]])
  1020. """
  1021. poly = kls._sympify(poly)
  1022. if not isinstance(poly, Poly):
  1023. raise ValueError("{} must be a Poly instance.".format(poly))
  1024. if not poly.is_monic:
  1025. raise ValueError("{} must be a monic polynomial.".format(poly))
  1026. if not poly.is_univariate:
  1027. raise ValueError(
  1028. "{} must be a univariate polynomial.".format(poly))
  1029. size = poly.degree()
  1030. if not size >= 1:
  1031. raise ValueError(
  1032. "{} must have degree not less than 1.".format(poly))
  1033. coeffs = poly.all_coeffs()
  1034. def entry(i, j):
  1035. if j == size - 1:
  1036. return -coeffs[-1 - i]
  1037. elif i == j + 1:
  1038. return kls.one
  1039. return kls.zero
  1040. return kls._new(size, size, entry)
  1041. @classmethod
  1042. def wilkinson(kls, n, **kwargs):
  1043. """Returns two square Wilkinson Matrix of size 2*n + 1
  1044. $W_{2n + 1}^-, W_{2n + 1}^+ =$ Wilkinson(n)
  1045. Examples
  1046. ========
  1047. >>> from sympy import Matrix
  1048. >>> wminus, wplus = Matrix.wilkinson(3)
  1049. >>> wminus
  1050. Matrix([
  1051. [-3, 1, 0, 0, 0, 0, 0],
  1052. [ 1, -2, 1, 0, 0, 0, 0],
  1053. [ 0, 1, -1, 1, 0, 0, 0],
  1054. [ 0, 0, 1, 0, 1, 0, 0],
  1055. [ 0, 0, 0, 1, 1, 1, 0],
  1056. [ 0, 0, 0, 0, 1, 2, 1],
  1057. [ 0, 0, 0, 0, 0, 1, 3]])
  1058. >>> wplus
  1059. Matrix([
  1060. [3, 1, 0, 0, 0, 0, 0],
  1061. [1, 2, 1, 0, 0, 0, 0],
  1062. [0, 1, 1, 1, 0, 0, 0],
  1063. [0, 0, 1, 0, 1, 0, 0],
  1064. [0, 0, 0, 1, 1, 1, 0],
  1065. [0, 0, 0, 0, 1, 2, 1],
  1066. [0, 0, 0, 0, 0, 1, 3]])
  1067. References
  1068. ==========
  1069. .. [1] https://blogs.mathworks.com/cleve/2013/04/15/wilkinsons-matrices-2/
  1070. .. [2] J. H. Wilkinson, The Algebraic Eigenvalue Problem, Claredon Press, Oxford, 1965, 662 pp.
  1071. """
  1072. klass = kwargs.get('cls', kls)
  1073. n = as_int(n)
  1074. return klass._eval_wilkinson(n)
  1075. class MatrixProperties(MatrixRequired):
  1076. """Provides basic properties of a matrix."""
  1077. def _eval_atoms(self, *types):
  1078. result = set()
  1079. for i in self:
  1080. result.update(i.atoms(*types))
  1081. return result
  1082. def _eval_free_symbols(self):
  1083. return set().union(*(i.free_symbols for i in self if i))
  1084. def _eval_has(self, *patterns):
  1085. return any(a.has(*patterns) for a in self)
  1086. def _eval_is_anti_symmetric(self, simpfunc):
  1087. if not all(simpfunc(self[i, j] + self[j, i]).is_zero for i in range(self.rows) for j in range(self.cols)):
  1088. return False
  1089. return True
  1090. def _eval_is_diagonal(self):
  1091. for i in range(self.rows):
  1092. for j in range(self.cols):
  1093. if i != j and self[i, j]:
  1094. return False
  1095. return True
  1096. # _eval_is_hermitian is called by some general SymPy
  1097. # routines and has a different *args signature. Make
  1098. # sure the names don't clash by adding `_matrix_` in name.
  1099. def _eval_is_matrix_hermitian(self, simpfunc):
  1100. mat = self._new(self.rows, self.cols, lambda i, j: simpfunc(self[i, j] - self[j, i].conjugate()))
  1101. return mat.is_zero_matrix
  1102. def _eval_is_Identity(self) -> FuzzyBool:
  1103. def dirac(i, j):
  1104. if i == j:
  1105. return 1
  1106. return 0
  1107. return all(self[i, j] == dirac(i, j)
  1108. for i in range(self.rows)
  1109. for j in range(self.cols))
  1110. def _eval_is_lower_hessenberg(self):
  1111. return all(self[i, j].is_zero
  1112. for i in range(self.rows)
  1113. for j in range(i + 2, self.cols))
  1114. def _eval_is_lower(self):
  1115. return all(self[i, j].is_zero
  1116. for i in range(self.rows)
  1117. for j in range(i + 1, self.cols))
  1118. def _eval_is_symbolic(self):
  1119. return self.has(Symbol)
  1120. def _eval_is_symmetric(self, simpfunc):
  1121. mat = self._new(self.rows, self.cols, lambda i, j: simpfunc(self[i, j] - self[j, i]))
  1122. return mat.is_zero_matrix
  1123. def _eval_is_zero_matrix(self):
  1124. if any(i.is_zero == False for i in self):
  1125. return False
  1126. if any(i.is_zero is None for i in self):
  1127. return None
  1128. return True
  1129. def _eval_is_upper_hessenberg(self):
  1130. return all(self[i, j].is_zero
  1131. for i in range(2, self.rows)
  1132. for j in range(min(self.cols, (i - 1))))
  1133. def _eval_values(self):
  1134. return [i for i in self if not i.is_zero]
  1135. def _has_positive_diagonals(self):
  1136. diagonal_entries = (self[i, i] for i in range(self.rows))
  1137. return fuzzy_and(x.is_positive for x in diagonal_entries)
  1138. def _has_nonnegative_diagonals(self):
  1139. diagonal_entries = (self[i, i] for i in range(self.rows))
  1140. return fuzzy_and(x.is_nonnegative for x in diagonal_entries)
  1141. def atoms(self, *types):
  1142. """Returns the atoms that form the current object.
  1143. Examples
  1144. ========
  1145. >>> from sympy.abc import x, y
  1146. >>> from sympy import Matrix
  1147. >>> Matrix([[x]])
  1148. Matrix([[x]])
  1149. >>> _.atoms()
  1150. {x}
  1151. >>> Matrix([[x, y], [y, x]])
  1152. Matrix([
  1153. [x, y],
  1154. [y, x]])
  1155. >>> _.atoms()
  1156. {x, y}
  1157. """
  1158. types = tuple(t if isinstance(t, type) else type(t) for t in types)
  1159. if not types:
  1160. types = (Atom,)
  1161. return self._eval_atoms(*types)
  1162. @property
  1163. def free_symbols(self):
  1164. """Returns the free symbols within the matrix.
  1165. Examples
  1166. ========
  1167. >>> from sympy.abc import x
  1168. >>> from sympy import Matrix
  1169. >>> Matrix([[x], [1]]).free_symbols
  1170. {x}
  1171. """
  1172. return self._eval_free_symbols()
  1173. def has(self, *patterns):
  1174. """Test whether any subexpression matches any of the patterns.
  1175. Examples
  1176. ========
  1177. >>> from sympy import Matrix, SparseMatrix, Float
  1178. >>> from sympy.abc import x, y
  1179. >>> A = Matrix(((1, x), (0.2, 3)))
  1180. >>> B = SparseMatrix(((1, x), (0.2, 3)))
  1181. >>> A.has(x)
  1182. True
  1183. >>> A.has(y)
  1184. False
  1185. >>> A.has(Float)
  1186. True
  1187. >>> B.has(x)
  1188. True
  1189. >>> B.has(y)
  1190. False
  1191. >>> B.has(Float)
  1192. True
  1193. """
  1194. return self._eval_has(*patterns)
  1195. def is_anti_symmetric(self, simplify=True):
  1196. """Check if matrix M is an antisymmetric matrix,
  1197. that is, M is a square matrix with all M[i, j] == -M[j, i].
  1198. When ``simplify=True`` (default), the sum M[i, j] + M[j, i] is
  1199. simplified before testing to see if it is zero. By default,
  1200. the SymPy simplify function is used. To use a custom function
  1201. set simplify to a function that accepts a single argument which
  1202. returns a simplified expression. To skip simplification, set
  1203. simplify to False but note that although this will be faster,
  1204. it may induce false negatives.
  1205. Examples
  1206. ========
  1207. >>> from sympy import Matrix, symbols
  1208. >>> m = Matrix(2, 2, [0, 1, -1, 0])
  1209. >>> m
  1210. Matrix([
  1211. [ 0, 1],
  1212. [-1, 0]])
  1213. >>> m.is_anti_symmetric()
  1214. True
  1215. >>> x, y = symbols('x y')
  1216. >>> m = Matrix(2, 3, [0, 0, x, -y, 0, 0])
  1217. >>> m
  1218. Matrix([
  1219. [ 0, 0, x],
  1220. [-y, 0, 0]])
  1221. >>> m.is_anti_symmetric()
  1222. False
  1223. >>> from sympy.abc import x, y
  1224. >>> m = Matrix(3, 3, [0, x**2 + 2*x + 1, y,
  1225. ... -(x + 1)**2, 0, x*y,
  1226. ... -y, -x*y, 0])
  1227. Simplification of matrix elements is done by default so even
  1228. though two elements which should be equal and opposite would not
  1229. pass an equality test, the matrix is still reported as
  1230. anti-symmetric:
  1231. >>> m[0, 1] == -m[1, 0]
  1232. False
  1233. >>> m.is_anti_symmetric()
  1234. True
  1235. If ``simplify=False`` is used for the case when a Matrix is already
  1236. simplified, this will speed things up. Here, we see that without
  1237. simplification the matrix does not appear anti-symmetric:
  1238. >>> print(m.is_anti_symmetric(simplify=False))
  1239. None
  1240. But if the matrix were already expanded, then it would appear
  1241. anti-symmetric and simplification in the is_anti_symmetric routine
  1242. is not needed:
  1243. >>> m = m.expand()
  1244. >>> m.is_anti_symmetric(simplify=False)
  1245. True
  1246. """
  1247. # accept custom simplification
  1248. simpfunc = simplify
  1249. if not isfunction(simplify):
  1250. simpfunc = _simplify if simplify else lambda x: x
  1251. if not self.is_square:
  1252. return False
  1253. return self._eval_is_anti_symmetric(simpfunc)
  1254. def is_diagonal(self):
  1255. """Check if matrix is diagonal,
  1256. that is matrix in which the entries outside the main diagonal are all zero.
  1257. Examples
  1258. ========
  1259. >>> from sympy import Matrix, diag
  1260. >>> m = Matrix(2, 2, [1, 0, 0, 2])
  1261. >>> m
  1262. Matrix([
  1263. [1, 0],
  1264. [0, 2]])
  1265. >>> m.is_diagonal()
  1266. True
  1267. >>> m = Matrix(2, 2, [1, 1, 0, 2])
  1268. >>> m
  1269. Matrix([
  1270. [1, 1],
  1271. [0, 2]])
  1272. >>> m.is_diagonal()
  1273. False
  1274. >>> m = diag(1, 2, 3)
  1275. >>> m
  1276. Matrix([
  1277. [1, 0, 0],
  1278. [0, 2, 0],
  1279. [0, 0, 3]])
  1280. >>> m.is_diagonal()
  1281. True
  1282. See Also
  1283. ========
  1284. is_lower
  1285. is_upper
  1286. sympy.matrices.matrixbase.MatrixCommon.is_diagonalizable
  1287. diagonalize
  1288. """
  1289. return self._eval_is_diagonal()
  1290. @property
  1291. def is_weakly_diagonally_dominant(self):
  1292. r"""Tests if the matrix is row weakly diagonally dominant.
  1293. Explanation
  1294. ===========
  1295. A $n, n$ matrix $A$ is row weakly diagonally dominant if
  1296. .. math::
  1297. \left|A_{i, i}\right| \ge \sum_{j = 0, j \neq i}^{n-1}
  1298. \left|A_{i, j}\right| \quad {\text{for all }}
  1299. i \in \{ 0, ..., n-1 \}
  1300. Examples
  1301. ========
  1302. >>> from sympy import Matrix
  1303. >>> A = Matrix([[3, -2, 1], [1, -3, 2], [-1, 2, 4]])
  1304. >>> A.is_weakly_diagonally_dominant
  1305. True
  1306. >>> A = Matrix([[-2, 2, 1], [1, 3, 2], [1, -2, 0]])
  1307. >>> A.is_weakly_diagonally_dominant
  1308. False
  1309. >>> A = Matrix([[-4, 2, 1], [1, 6, 2], [1, -2, 5]])
  1310. >>> A.is_weakly_diagonally_dominant
  1311. True
  1312. Notes
  1313. =====
  1314. If you want to test whether a matrix is column diagonally
  1315. dominant, you can apply the test after transposing the matrix.
  1316. """
  1317. if not self.is_square:
  1318. return False
  1319. rows, cols = self.shape
  1320. def test_row(i):
  1321. summation = self.zero
  1322. for j in range(cols):
  1323. if i != j:
  1324. summation += Abs(self[i, j])
  1325. return (Abs(self[i, i]) - summation).is_nonnegative
  1326. return fuzzy_and(test_row(i) for i in range(rows))
  1327. @property
  1328. def is_strongly_diagonally_dominant(self):
  1329. r"""Tests if the matrix is row strongly diagonally dominant.
  1330. Explanation
  1331. ===========
  1332. A $n, n$ matrix $A$ is row strongly diagonally dominant if
  1333. .. math::
  1334. \left|A_{i, i}\right| > \sum_{j = 0, j \neq i}^{n-1}
  1335. \left|A_{i, j}\right| \quad {\text{for all }}
  1336. i \in \{ 0, ..., n-1 \}
  1337. Examples
  1338. ========
  1339. >>> from sympy import Matrix
  1340. >>> A = Matrix([[3, -2, 1], [1, -3, 2], [-1, 2, 4]])
  1341. >>> A.is_strongly_diagonally_dominant
  1342. False
  1343. >>> A = Matrix([[-2, 2, 1], [1, 3, 2], [1, -2, 0]])
  1344. >>> A.is_strongly_diagonally_dominant
  1345. False
  1346. >>> A = Matrix([[-4, 2, 1], [1, 6, 2], [1, -2, 5]])
  1347. >>> A.is_strongly_diagonally_dominant
  1348. True
  1349. Notes
  1350. =====
  1351. If you want to test whether a matrix is column diagonally
  1352. dominant, you can apply the test after transposing the matrix.
  1353. """
  1354. if not self.is_square:
  1355. return False
  1356. rows, cols = self.shape
  1357. def test_row(i):
  1358. summation = self.zero
  1359. for j in range(cols):
  1360. if i != j:
  1361. summation += Abs(self[i, j])
  1362. return (Abs(self[i, i]) - summation).is_positive
  1363. return fuzzy_and(test_row(i) for i in range(rows))
  1364. @property
  1365. def is_hermitian(self):
  1366. """Checks if the matrix is Hermitian.
  1367. In a Hermitian matrix element i,j is the complex conjugate of
  1368. element j,i.
  1369. Examples
  1370. ========
  1371. >>> from sympy import Matrix
  1372. >>> from sympy import I
  1373. >>> from sympy.abc import x
  1374. >>> a = Matrix([[1, I], [-I, 1]])
  1375. >>> a
  1376. Matrix([
  1377. [ 1, I],
  1378. [-I, 1]])
  1379. >>> a.is_hermitian
  1380. True
  1381. >>> a[0, 0] = 2*I
  1382. >>> a.is_hermitian
  1383. False
  1384. >>> a[0, 0] = x
  1385. >>> a.is_hermitian
  1386. >>> a[0, 1] = a[1, 0]*I
  1387. >>> a.is_hermitian
  1388. False
  1389. """
  1390. if not self.is_square:
  1391. return False
  1392. return self._eval_is_matrix_hermitian(_simplify)
  1393. @property
  1394. def is_Identity(self) -> FuzzyBool:
  1395. if not self.is_square:
  1396. return False
  1397. return self._eval_is_Identity()
  1398. @property
  1399. def is_lower_hessenberg(self):
  1400. r"""Checks if the matrix is in the lower-Hessenberg form.
  1401. The lower hessenberg matrix has zero entries
  1402. above the first superdiagonal.
  1403. Examples
  1404. ========
  1405. >>> from sympy import Matrix
  1406. >>> a = Matrix([[1, 2, 0, 0], [5, 2, 3, 0], [3, 4, 3, 7], [5, 6, 1, 1]])
  1407. >>> a
  1408. Matrix([
  1409. [1, 2, 0, 0],
  1410. [5, 2, 3, 0],
  1411. [3, 4, 3, 7],
  1412. [5, 6, 1, 1]])
  1413. >>> a.is_lower_hessenberg
  1414. True
  1415. See Also
  1416. ========
  1417. is_upper_hessenberg
  1418. is_lower
  1419. """
  1420. return self._eval_is_lower_hessenberg()
  1421. @property
  1422. def is_lower(self):
  1423. """Check if matrix is a lower triangular matrix. True can be returned
  1424. even if the matrix is not square.
  1425. Examples
  1426. ========
  1427. >>> from sympy import Matrix
  1428. >>> m = Matrix(2, 2, [1, 0, 0, 1])
  1429. >>> m
  1430. Matrix([
  1431. [1, 0],
  1432. [0, 1]])
  1433. >>> m.is_lower
  1434. True
  1435. >>> m = Matrix(4, 3, [0, 0, 0, 2, 0, 0, 1, 4, 0, 6, 6, 5])
  1436. >>> m
  1437. Matrix([
  1438. [0, 0, 0],
  1439. [2, 0, 0],
  1440. [1, 4, 0],
  1441. [6, 6, 5]])
  1442. >>> m.is_lower
  1443. True
  1444. >>> from sympy.abc import x, y
  1445. >>> m = Matrix(2, 2, [x**2 + y, y**2 + x, 0, x + y])
  1446. >>> m
  1447. Matrix([
  1448. [x**2 + y, x + y**2],
  1449. [ 0, x + y]])
  1450. >>> m.is_lower
  1451. False
  1452. See Also
  1453. ========
  1454. is_upper
  1455. is_diagonal
  1456. is_lower_hessenberg
  1457. """
  1458. return self._eval_is_lower()
  1459. @property
  1460. def is_square(self):
  1461. """Checks if a matrix is square.
  1462. A matrix is square if the number of rows equals the number of columns.
  1463. The empty matrix is square by definition, since the number of rows and
  1464. the number of columns are both zero.
  1465. Examples
  1466. ========
  1467. >>> from sympy import Matrix
  1468. >>> a = Matrix([[1, 2, 3], [4, 5, 6]])
  1469. >>> b = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
  1470. >>> c = Matrix([])
  1471. >>> a.is_square
  1472. False
  1473. >>> b.is_square
  1474. True
  1475. >>> c.is_square
  1476. True
  1477. """
  1478. return self.rows == self.cols
  1479. def is_symbolic(self):
  1480. """Checks if any elements contain Symbols.
  1481. Examples
  1482. ========
  1483. >>> from sympy import Matrix
  1484. >>> from sympy.abc import x, y
  1485. >>> M = Matrix([[x, y], [1, 0]])
  1486. >>> M.is_symbolic()
  1487. True
  1488. """
  1489. return self._eval_is_symbolic()
  1490. def is_symmetric(self, simplify=True):
  1491. """Check if matrix is symmetric matrix,
  1492. that is square matrix and is equal to its transpose.
  1493. By default, simplifications occur before testing symmetry.
  1494. They can be skipped using 'simplify=False'; while speeding things a bit,
  1495. this may however induce false negatives.
  1496. Examples
  1497. ========
  1498. >>> from sympy import Matrix
  1499. >>> m = Matrix(2, 2, [0, 1, 1, 2])
  1500. >>> m
  1501. Matrix([
  1502. [0, 1],
  1503. [1, 2]])
  1504. >>> m.is_symmetric()
  1505. True
  1506. >>> m = Matrix(2, 2, [0, 1, 2, 0])
  1507. >>> m
  1508. Matrix([
  1509. [0, 1],
  1510. [2, 0]])
  1511. >>> m.is_symmetric()
  1512. False
  1513. >>> m = Matrix(2, 3, [0, 0, 0, 0, 0, 0])
  1514. >>> m
  1515. Matrix([
  1516. [0, 0, 0],
  1517. [0, 0, 0]])
  1518. >>> m.is_symmetric()
  1519. False
  1520. >>> from sympy.abc import x, y
  1521. >>> m = Matrix(3, 3, [1, x**2 + 2*x + 1, y, (x + 1)**2, 2, 0, y, 0, 3])
  1522. >>> m
  1523. Matrix([
  1524. [ 1, x**2 + 2*x + 1, y],
  1525. [(x + 1)**2, 2, 0],
  1526. [ y, 0, 3]])
  1527. >>> m.is_symmetric()
  1528. True
  1529. If the matrix is already simplified, you may speed-up is_symmetric()
  1530. test by using 'simplify=False'.
  1531. >>> bool(m.is_symmetric(simplify=False))
  1532. False
  1533. >>> m1 = m.expand()
  1534. >>> m1.is_symmetric(simplify=False)
  1535. True
  1536. """
  1537. simpfunc = simplify
  1538. if not isfunction(simplify):
  1539. simpfunc = _simplify if simplify else lambda x: x
  1540. if not self.is_square:
  1541. return False
  1542. return self._eval_is_symmetric(simpfunc)
  1543. @property
  1544. def is_upper_hessenberg(self):
  1545. """Checks if the matrix is the upper-Hessenberg form.
  1546. The upper hessenberg matrix has zero entries
  1547. below the first subdiagonal.
  1548. Examples
  1549. ========
  1550. >>> from sympy import Matrix
  1551. >>> a = Matrix([[1, 4, 2, 3], [3, 4, 1, 7], [0, 2, 3, 4], [0, 0, 1, 3]])
  1552. >>> a
  1553. Matrix([
  1554. [1, 4, 2, 3],
  1555. [3, 4, 1, 7],
  1556. [0, 2, 3, 4],
  1557. [0, 0, 1, 3]])
  1558. >>> a.is_upper_hessenberg
  1559. True
  1560. See Also
  1561. ========
  1562. is_lower_hessenberg
  1563. is_upper
  1564. """
  1565. return self._eval_is_upper_hessenberg()
  1566. @property
  1567. def is_upper(self):
  1568. """Check if matrix is an upper triangular matrix. True can be returned
  1569. even if the matrix is not square.
  1570. Examples
  1571. ========
  1572. >>> from sympy import Matrix
  1573. >>> m = Matrix(2, 2, [1, 0, 0, 1])
  1574. >>> m
  1575. Matrix([
  1576. [1, 0],
  1577. [0, 1]])
  1578. >>> m.is_upper
  1579. True
  1580. >>> m = Matrix(4, 3, [5, 1, 9, 0, 4, 6, 0, 0, 5, 0, 0, 0])
  1581. >>> m
  1582. Matrix([
  1583. [5, 1, 9],
  1584. [0, 4, 6],
  1585. [0, 0, 5],
  1586. [0, 0, 0]])
  1587. >>> m.is_upper
  1588. True
  1589. >>> m = Matrix(2, 3, [4, 2, 5, 6, 1, 1])
  1590. >>> m
  1591. Matrix([
  1592. [4, 2, 5],
  1593. [6, 1, 1]])
  1594. >>> m.is_upper
  1595. False
  1596. See Also
  1597. ========
  1598. is_lower
  1599. is_diagonal
  1600. is_upper_hessenberg
  1601. """
  1602. return all(self[i, j].is_zero
  1603. for i in range(1, self.rows)
  1604. for j in range(min(i, self.cols)))
  1605. @property
  1606. def is_zero_matrix(self):
  1607. """Checks if a matrix is a zero matrix.
  1608. A matrix is zero if every element is zero. A matrix need not be square
  1609. to be considered zero. The empty matrix is zero by the principle of
  1610. vacuous truth. For a matrix that may or may not be zero (e.g.
  1611. contains a symbol), this will be None
  1612. Examples
  1613. ========
  1614. >>> from sympy import Matrix, zeros
  1615. >>> from sympy.abc import x
  1616. >>> a = Matrix([[0, 0], [0, 0]])
  1617. >>> b = zeros(3, 4)
  1618. >>> c = Matrix([[0, 1], [0, 0]])
  1619. >>> d = Matrix([])
  1620. >>> e = Matrix([[x, 0], [0, 0]])
  1621. >>> a.is_zero_matrix
  1622. True
  1623. >>> b.is_zero_matrix
  1624. True
  1625. >>> c.is_zero_matrix
  1626. False
  1627. >>> d.is_zero_matrix
  1628. True
  1629. >>> e.is_zero_matrix
  1630. """
  1631. return self._eval_is_zero_matrix()
  1632. def values(self):
  1633. """Return non-zero values of self."""
  1634. return self._eval_values()
  1635. class MatrixOperations(MatrixRequired):
  1636. """Provides basic matrix shape and elementwise
  1637. operations. Should not be instantiated directly."""
  1638. def _eval_adjoint(self):
  1639. return self.transpose().conjugate()
  1640. def _eval_applyfunc(self, f):
  1641. out = self._new(self.rows, self.cols, [f(x) for x in self])
  1642. return out
  1643. def _eval_as_real_imag(self): # type: ignore
  1644. return (self.applyfunc(re), self.applyfunc(im))
  1645. def _eval_conjugate(self):
  1646. return self.applyfunc(lambda x: x.conjugate())
  1647. def _eval_permute_cols(self, perm):
  1648. # apply the permutation to a list
  1649. mapping = list(perm)
  1650. def entry(i, j):
  1651. return self[i, mapping[j]]
  1652. return self._new(self.rows, self.cols, entry)
  1653. def _eval_permute_rows(self, perm):
  1654. # apply the permutation to a list
  1655. mapping = list(perm)
  1656. def entry(i, j):
  1657. return self[mapping[i], j]
  1658. return self._new(self.rows, self.cols, entry)
  1659. def _eval_trace(self):
  1660. return sum(self[i, i] for i in range(self.rows))
  1661. def _eval_transpose(self):
  1662. return self._new(self.cols, self.rows, lambda i, j: self[j, i])
  1663. def adjoint(self):
  1664. """Conjugate transpose or Hermitian conjugation."""
  1665. return self._eval_adjoint()
  1666. def applyfunc(self, f):
  1667. """Apply a function to each element of the matrix.
  1668. Examples
  1669. ========
  1670. >>> from sympy import Matrix
  1671. >>> m = Matrix(2, 2, lambda i, j: i*2+j)
  1672. >>> m
  1673. Matrix([
  1674. [0, 1],
  1675. [2, 3]])
  1676. >>> m.applyfunc(lambda i: 2*i)
  1677. Matrix([
  1678. [0, 2],
  1679. [4, 6]])
  1680. """
  1681. if not callable(f):
  1682. raise TypeError("`f` must be callable.")
  1683. return self._eval_applyfunc(f)
  1684. def as_real_imag(self, deep=True, **hints):
  1685. """Returns a tuple containing the (real, imaginary) part of matrix."""
  1686. # XXX: Ignoring deep and hints...
  1687. return self._eval_as_real_imag()
  1688. def conjugate(self):
  1689. """Return the by-element conjugation.
  1690. Examples
  1691. ========
  1692. >>> from sympy import SparseMatrix, I
  1693. >>> a = SparseMatrix(((1, 2 + I), (3, 4), (I, -I)))
  1694. >>> a
  1695. Matrix([
  1696. [1, 2 + I],
  1697. [3, 4],
  1698. [I, -I]])
  1699. >>> a.C
  1700. Matrix([
  1701. [ 1, 2 - I],
  1702. [ 3, 4],
  1703. [-I, I]])
  1704. See Also
  1705. ========
  1706. transpose: Matrix transposition
  1707. H: Hermite conjugation
  1708. sympy.matrices.matrixbase.MatrixBase.D: Dirac conjugation
  1709. """
  1710. return self._eval_conjugate()
  1711. def doit(self, **hints):
  1712. return self.applyfunc(lambda x: x.doit(**hints))
  1713. def evalf(self, n=15, subs=None, maxn=100, chop=False, strict=False, quad=None, verbose=False):
  1714. """Apply evalf() to each element of self."""
  1715. options = {'subs':subs, 'maxn':maxn, 'chop':chop, 'strict':strict,
  1716. 'quad':quad, 'verbose':verbose}
  1717. return self.applyfunc(lambda i: i.evalf(n, **options))
  1718. def expand(self, deep=True, modulus=None, power_base=True, power_exp=True,
  1719. mul=True, log=True, multinomial=True, basic=True, **hints):
  1720. """Apply core.function.expand to each entry of the matrix.
  1721. Examples
  1722. ========
  1723. >>> from sympy.abc import x
  1724. >>> from sympy import Matrix
  1725. >>> Matrix(1, 1, [x*(x+1)])
  1726. Matrix([[x*(x + 1)]])
  1727. >>> _.expand()
  1728. Matrix([[x**2 + x]])
  1729. """
  1730. return self.applyfunc(lambda x: x.expand(
  1731. deep, modulus, power_base, power_exp, mul, log, multinomial, basic,
  1732. **hints))
  1733. @property
  1734. def H(self):
  1735. """Return Hermite conjugate.
  1736. Examples
  1737. ========
  1738. >>> from sympy import Matrix, I
  1739. >>> m = Matrix((0, 1 + I, 2, 3))
  1740. >>> m
  1741. Matrix([
  1742. [ 0],
  1743. [1 + I],
  1744. [ 2],
  1745. [ 3]])
  1746. >>> m.H
  1747. Matrix([[0, 1 - I, 2, 3]])
  1748. See Also
  1749. ========
  1750. conjugate: By-element conjugation
  1751. sympy.matrices.matrixbase.MatrixBase.D: Dirac conjugation
  1752. """
  1753. return self.T.C
  1754. def permute(self, perm, orientation='rows', direction='forward'):
  1755. r"""Permute the rows or columns of a matrix by the given list of
  1756. swaps.
  1757. Parameters
  1758. ==========
  1759. perm : Permutation, list, or list of lists
  1760. A representation for the permutation.
  1761. If it is ``Permutation``, it is used directly with some
  1762. resizing with respect to the matrix size.
  1763. If it is specified as list of lists,
  1764. (e.g., ``[[0, 1], [0, 2]]``), then the permutation is formed
  1765. from applying the product of cycles. The direction how the
  1766. cyclic product is applied is described in below.
  1767. If it is specified as a list, the list should represent
  1768. an array form of a permutation. (e.g., ``[1, 2, 0]``) which
  1769. would would form the swapping function
  1770. `0 \mapsto 1, 1 \mapsto 2, 2\mapsto 0`.
  1771. orientation : 'rows', 'cols'
  1772. A flag to control whether to permute the rows or the columns
  1773. direction : 'forward', 'backward'
  1774. A flag to control whether to apply the permutations from
  1775. the start of the list first, or from the back of the list
  1776. first.
  1777. For example, if the permutation specification is
  1778. ``[[0, 1], [0, 2]]``,
  1779. If the flag is set to ``'forward'``, the cycle would be
  1780. formed as `0 \mapsto 2, 2 \mapsto 1, 1 \mapsto 0`.
  1781. If the flag is set to ``'backward'``, the cycle would be
  1782. formed as `0 \mapsto 1, 1 \mapsto 2, 2 \mapsto 0`.
  1783. If the argument ``perm`` is not in a form of list of lists,
  1784. this flag takes no effect.
  1785. Examples
  1786. ========
  1787. >>> from sympy import eye
  1788. >>> M = eye(3)
  1789. >>> M.permute([[0, 1], [0, 2]], orientation='rows', direction='forward')
  1790. Matrix([
  1791. [0, 0, 1],
  1792. [1, 0, 0],
  1793. [0, 1, 0]])
  1794. >>> from sympy import eye
  1795. >>> M = eye(3)
  1796. >>> M.permute([[0, 1], [0, 2]], orientation='rows', direction='backward')
  1797. Matrix([
  1798. [0, 1, 0],
  1799. [0, 0, 1],
  1800. [1, 0, 0]])
  1801. Notes
  1802. =====
  1803. If a bijective function
  1804. `\sigma : \mathbb{N}_0 \rightarrow \mathbb{N}_0` denotes the
  1805. permutation.
  1806. If the matrix `A` is the matrix to permute, represented as
  1807. a horizontal or a vertical stack of vectors:
  1808. .. math::
  1809. A =
  1810. \begin{bmatrix}
  1811. a_0 \\ a_1 \\ \vdots \\ a_{n-1}
  1812. \end{bmatrix} =
  1813. \begin{bmatrix}
  1814. \alpha_0 & \alpha_1 & \cdots & \alpha_{n-1}
  1815. \end{bmatrix}
  1816. If the matrix `B` is the result, the permutation of matrix rows
  1817. is defined as:
  1818. .. math::
  1819. B := \begin{bmatrix}
  1820. a_{\sigma(0)} \\ a_{\sigma(1)} \\ \vdots \\ a_{\sigma(n-1)}
  1821. \end{bmatrix}
  1822. And the permutation of matrix columns is defined as:
  1823. .. math::
  1824. B := \begin{bmatrix}
  1825. \alpha_{\sigma(0)} & \alpha_{\sigma(1)} &
  1826. \cdots & \alpha_{\sigma(n-1)}
  1827. \end{bmatrix}
  1828. """
  1829. from sympy.combinatorics import Permutation
  1830. # allow british variants and `columns`
  1831. if direction == 'forwards':
  1832. direction = 'forward'
  1833. if direction == 'backwards':
  1834. direction = 'backward'
  1835. if orientation == 'columns':
  1836. orientation = 'cols'
  1837. if direction not in ('forward', 'backward'):
  1838. raise TypeError("direction='{}' is an invalid kwarg. "
  1839. "Try 'forward' or 'backward'".format(direction))
  1840. if orientation not in ('rows', 'cols'):
  1841. raise TypeError("orientation='{}' is an invalid kwarg. "
  1842. "Try 'rows' or 'cols'".format(orientation))
  1843. if not isinstance(perm, (Permutation, Iterable)):
  1844. raise ValueError(
  1845. "{} must be a list, a list of lists, "
  1846. "or a SymPy permutation object.".format(perm))
  1847. # ensure all swaps are in range
  1848. max_index = self.rows if orientation == 'rows' else self.cols
  1849. if not all(0 <= t <= max_index for t in flatten(list(perm))):
  1850. raise IndexError("`swap` indices out of range.")
  1851. if perm and not isinstance(perm, Permutation) and \
  1852. isinstance(perm[0], Iterable):
  1853. if direction == 'forward':
  1854. perm = list(reversed(perm))
  1855. perm = Permutation(perm, size=max_index+1)
  1856. else:
  1857. perm = Permutation(perm, size=max_index+1)
  1858. if orientation == 'rows':
  1859. return self._eval_permute_rows(perm)
  1860. if orientation == 'cols':
  1861. return self._eval_permute_cols(perm)
  1862. def permute_cols(self, swaps, direction='forward'):
  1863. """Alias for
  1864. ``self.permute(swaps, orientation='cols', direction=direction)``
  1865. See Also
  1866. ========
  1867. permute
  1868. """
  1869. return self.permute(swaps, orientation='cols', direction=direction)
  1870. def permute_rows(self, swaps, direction='forward'):
  1871. """Alias for
  1872. ``self.permute(swaps, orientation='rows', direction=direction)``
  1873. See Also
  1874. ========
  1875. permute
  1876. """
  1877. return self.permute(swaps, orientation='rows', direction=direction)
  1878. def refine(self, assumptions=True):
  1879. """Apply refine to each element of the matrix.
  1880. Examples
  1881. ========
  1882. >>> from sympy import Symbol, Matrix, Abs, sqrt, Q
  1883. >>> x = Symbol('x')
  1884. >>> Matrix([[Abs(x)**2, sqrt(x**2)],[sqrt(x**2), Abs(x)**2]])
  1885. Matrix([
  1886. [ Abs(x)**2, sqrt(x**2)],
  1887. [sqrt(x**2), Abs(x)**2]])
  1888. >>> _.refine(Q.real(x))
  1889. Matrix([
  1890. [ x**2, Abs(x)],
  1891. [Abs(x), x**2]])
  1892. """
  1893. return self.applyfunc(lambda x: refine(x, assumptions))
  1894. def replace(self, F, G, map=False, simultaneous=True, exact=None):
  1895. """Replaces Function F in Matrix entries with Function G.
  1896. Examples
  1897. ========
  1898. >>> from sympy import symbols, Function, Matrix
  1899. >>> F, G = symbols('F, G', cls=Function)
  1900. >>> M = Matrix(2, 2, lambda i, j: F(i+j)) ; M
  1901. Matrix([
  1902. [F(0), F(1)],
  1903. [F(1), F(2)]])
  1904. >>> N = M.replace(F,G)
  1905. >>> N
  1906. Matrix([
  1907. [G(0), G(1)],
  1908. [G(1), G(2)]])
  1909. """
  1910. return self.applyfunc(
  1911. lambda x: x.replace(F, G, map=map, simultaneous=simultaneous, exact=exact))
  1912. def rot90(self, k=1):
  1913. """Rotates Matrix by 90 degrees
  1914. Parameters
  1915. ==========
  1916. k : int
  1917. Specifies how many times the matrix is rotated by 90 degrees
  1918. (clockwise when positive, counter-clockwise when negative).
  1919. Examples
  1920. ========
  1921. >>> from sympy import Matrix, symbols
  1922. >>> A = Matrix(2, 2, symbols('a:d'))
  1923. >>> A
  1924. Matrix([
  1925. [a, b],
  1926. [c, d]])
  1927. Rotating the matrix clockwise one time:
  1928. >>> A.rot90(1)
  1929. Matrix([
  1930. [c, a],
  1931. [d, b]])
  1932. Rotating the matrix anticlockwise two times:
  1933. >>> A.rot90(-2)
  1934. Matrix([
  1935. [d, c],
  1936. [b, a]])
  1937. """
  1938. mod = k%4
  1939. if mod == 0:
  1940. return self
  1941. if mod == 1:
  1942. return self[::-1, ::].T
  1943. if mod == 2:
  1944. return self[::-1, ::-1]
  1945. if mod == 3:
  1946. return self[::, ::-1].T
  1947. def simplify(self, **kwargs):
  1948. """Apply simplify to each element of the matrix.
  1949. Examples
  1950. ========
  1951. >>> from sympy.abc import x, y
  1952. >>> from sympy import SparseMatrix, sin, cos
  1953. >>> SparseMatrix(1, 1, [x*sin(y)**2 + x*cos(y)**2])
  1954. Matrix([[x*sin(y)**2 + x*cos(y)**2]])
  1955. >>> _.simplify()
  1956. Matrix([[x]])
  1957. """
  1958. return self.applyfunc(lambda x: x.simplify(**kwargs))
  1959. def subs(self, *args, **kwargs): # should mirror core.basic.subs
  1960. """Return a new matrix with subs applied to each entry.
  1961. Examples
  1962. ========
  1963. >>> from sympy.abc import x, y
  1964. >>> from sympy import SparseMatrix, Matrix
  1965. >>> SparseMatrix(1, 1, [x])
  1966. Matrix([[x]])
  1967. >>> _.subs(x, y)
  1968. Matrix([[y]])
  1969. >>> Matrix(_).subs(y, x)
  1970. Matrix([[x]])
  1971. """
  1972. if len(args) == 1 and not isinstance(args[0], (dict, set)) and iter(args[0]) and not is_sequence(args[0]):
  1973. args = (list(args[0]),)
  1974. return self.applyfunc(lambda x: x.subs(*args, **kwargs))
  1975. def trace(self):
  1976. """
  1977. Returns the trace of a square matrix i.e. the sum of the
  1978. diagonal elements.
  1979. Examples
  1980. ========
  1981. >>> from sympy import Matrix
  1982. >>> A = Matrix(2, 2, [1, 2, 3, 4])
  1983. >>> A.trace()
  1984. 5
  1985. """
  1986. if self.rows != self.cols:
  1987. raise NonSquareMatrixError()
  1988. return self._eval_trace()
  1989. def transpose(self):
  1990. """
  1991. Returns the transpose of the matrix.
  1992. Examples
  1993. ========
  1994. >>> from sympy import Matrix
  1995. >>> A = Matrix(2, 2, [1, 2, 3, 4])
  1996. >>> A.transpose()
  1997. Matrix([
  1998. [1, 3],
  1999. [2, 4]])
  2000. >>> from sympy import Matrix, I
  2001. >>> m=Matrix(((1, 2+I), (3, 4)))
  2002. >>> m
  2003. Matrix([
  2004. [1, 2 + I],
  2005. [3, 4]])
  2006. >>> m.transpose()
  2007. Matrix([
  2008. [ 1, 3],
  2009. [2 + I, 4]])
  2010. >>> m.T == m.transpose()
  2011. True
  2012. See Also
  2013. ========
  2014. conjugate: By-element conjugation
  2015. """
  2016. return self._eval_transpose()
  2017. @property
  2018. def T(self):
  2019. '''Matrix transposition'''
  2020. return self.transpose()
  2021. @property
  2022. def C(self):
  2023. '''By-element conjugation'''
  2024. return self.conjugate()
  2025. def n(self, *args, **kwargs):
  2026. """Apply evalf() to each element of self."""
  2027. return self.evalf(*args, **kwargs)
  2028. def xreplace(self, rule): # should mirror core.basic.xreplace
  2029. """Return a new matrix with xreplace applied to each entry.
  2030. Examples
  2031. ========
  2032. >>> from sympy.abc import x, y
  2033. >>> from sympy import SparseMatrix, Matrix
  2034. >>> SparseMatrix(1, 1, [x])
  2035. Matrix([[x]])
  2036. >>> _.xreplace({x: y})
  2037. Matrix([[y]])
  2038. >>> Matrix(_).xreplace({y: x})
  2039. Matrix([[x]])
  2040. """
  2041. return self.applyfunc(lambda x: x.xreplace(rule))
  2042. def _eval_simplify(self, **kwargs):
  2043. # XXX: We can't use self.simplify here as mutable subclasses will
  2044. # override simplify and have it return None
  2045. return MatrixOperations.simplify(self, **kwargs)
  2046. def _eval_trigsimp(self, **opts):
  2047. from sympy.simplify.trigsimp import trigsimp
  2048. return self.applyfunc(lambda x: trigsimp(x, **opts))
  2049. def upper_triangular(self, k=0):
  2050. """Return the elements on and above the kth diagonal of a matrix.
  2051. If k is not specified then simply returns upper-triangular portion
  2052. of a matrix
  2053. Examples
  2054. ========
  2055. >>> from sympy import ones
  2056. >>> A = ones(4)
  2057. >>> A.upper_triangular()
  2058. Matrix([
  2059. [1, 1, 1, 1],
  2060. [0, 1, 1, 1],
  2061. [0, 0, 1, 1],
  2062. [0, 0, 0, 1]])
  2063. >>> A.upper_triangular(2)
  2064. Matrix([
  2065. [0, 0, 1, 1],
  2066. [0, 0, 0, 1],
  2067. [0, 0, 0, 0],
  2068. [0, 0, 0, 0]])
  2069. >>> A.upper_triangular(-1)
  2070. Matrix([
  2071. [1, 1, 1, 1],
  2072. [1, 1, 1, 1],
  2073. [0, 1, 1, 1],
  2074. [0, 0, 1, 1]])
  2075. """
  2076. def entry(i, j):
  2077. return self[i, j] if i + k <= j else self.zero
  2078. return self._new(self.rows, self.cols, entry)
  2079. def lower_triangular(self, k=0):
  2080. """Return the elements on and below the kth diagonal of a matrix.
  2081. If k is not specified then simply returns lower-triangular portion
  2082. of a matrix
  2083. Examples
  2084. ========
  2085. >>> from sympy import ones
  2086. >>> A = ones(4)
  2087. >>> A.lower_triangular()
  2088. Matrix([
  2089. [1, 0, 0, 0],
  2090. [1, 1, 0, 0],
  2091. [1, 1, 1, 0],
  2092. [1, 1, 1, 1]])
  2093. >>> A.lower_triangular(-2)
  2094. Matrix([
  2095. [0, 0, 0, 0],
  2096. [0, 0, 0, 0],
  2097. [1, 0, 0, 0],
  2098. [1, 1, 0, 0]])
  2099. >>> A.lower_triangular(1)
  2100. Matrix([
  2101. [1, 1, 0, 0],
  2102. [1, 1, 1, 0],
  2103. [1, 1, 1, 1],
  2104. [1, 1, 1, 1]])
  2105. """
  2106. def entry(i, j):
  2107. return self[i, j] if i + k >= j else self.zero
  2108. return self._new(self.rows, self.cols, entry)
  2109. class MatrixArithmetic(MatrixRequired):
  2110. """Provides basic matrix arithmetic operations.
  2111. Should not be instantiated directly."""
  2112. _op_priority = 10.01
  2113. def _eval_Abs(self):
  2114. return self._new(self.rows, self.cols, lambda i, j: Abs(self[i, j]))
  2115. def _eval_add(self, other):
  2116. return self._new(self.rows, self.cols,
  2117. lambda i, j: self[i, j] + other[i, j])
  2118. def _eval_matrix_mul(self, other):
  2119. def entry(i, j):
  2120. vec = [self[i,k]*other[k,j] for k in range(self.cols)]
  2121. try:
  2122. return Add(*vec)
  2123. except (TypeError, SympifyError):
  2124. # Some matrices don't work with `sum` or `Add`
  2125. # They don't work with `sum` because `sum` tries to add `0`
  2126. # Fall back to a safe way to multiply if the `Add` fails.
  2127. return reduce(lambda a, b: a + b, vec)
  2128. return self._new(self.rows, other.cols, entry)
  2129. def _eval_matrix_mul_elementwise(self, other):
  2130. return self._new(self.rows, self.cols, lambda i, j: self[i,j]*other[i,j])
  2131. def _eval_matrix_rmul(self, other):
  2132. def entry(i, j):
  2133. return sum(other[i,k]*self[k,j] for k in range(other.cols))
  2134. return self._new(other.rows, self.cols, entry)
  2135. def _eval_pow_by_recursion(self, num):
  2136. if num == 1:
  2137. return self
  2138. if num % 2 == 1:
  2139. a, b = self, self._eval_pow_by_recursion(num - 1)
  2140. else:
  2141. a = b = self._eval_pow_by_recursion(num // 2)
  2142. return a.multiply(b)
  2143. def _eval_pow_by_cayley(self, exp):
  2144. from sympy.discrete.recurrences import linrec_coeffs
  2145. row = self.shape[0]
  2146. p = self.charpoly()
  2147. coeffs = (-p).all_coeffs()[1:]
  2148. coeffs = linrec_coeffs(coeffs, exp)
  2149. new_mat = self.eye(row)
  2150. ans = self.zeros(row)
  2151. for i in range(row):
  2152. ans += coeffs[i]*new_mat
  2153. new_mat *= self
  2154. return ans
  2155. def _eval_pow_by_recursion_dotprodsimp(self, num, prevsimp=None):
  2156. if prevsimp is None:
  2157. prevsimp = [True]*len(self)
  2158. if num == 1:
  2159. return self
  2160. if num % 2 == 1:
  2161. a, b = self, self._eval_pow_by_recursion_dotprodsimp(num - 1,
  2162. prevsimp=prevsimp)
  2163. else:
  2164. a = b = self._eval_pow_by_recursion_dotprodsimp(num // 2,
  2165. prevsimp=prevsimp)
  2166. m = a.multiply(b, dotprodsimp=False)
  2167. lenm = len(m)
  2168. elems = [None]*lenm
  2169. for i in range(lenm):
  2170. if prevsimp[i]:
  2171. elems[i], prevsimp[i] = _dotprodsimp(m[i], withsimp=True)
  2172. else:
  2173. elems[i] = m[i]
  2174. return m._new(m.rows, m.cols, elems)
  2175. def _eval_scalar_mul(self, other):
  2176. return self._new(self.rows, self.cols, lambda i, j: self[i,j]*other)
  2177. def _eval_scalar_rmul(self, other):
  2178. return self._new(self.rows, self.cols, lambda i, j: other*self[i,j])
  2179. def _eval_Mod(self, other):
  2180. return self._new(self.rows, self.cols, lambda i, j: Mod(self[i, j], other))
  2181. # Python arithmetic functions
  2182. def __abs__(self):
  2183. """Returns a new matrix with entry-wise absolute values."""
  2184. return self._eval_Abs()
  2185. @call_highest_priority('__radd__')
  2186. def __add__(self, other):
  2187. """Return self + other, raising ShapeError if shapes do not match."""
  2188. if isinstance(other, NDimArray): # Matrix and array addition is currently not implemented
  2189. return NotImplemented
  2190. other = _matrixify(other)
  2191. # matrix-like objects can have shapes. This is
  2192. # our first sanity check.
  2193. if hasattr(other, 'shape'):
  2194. if self.shape != other.shape:
  2195. raise ShapeError("Matrix size mismatch: %s + %s" % (
  2196. self.shape, other.shape))
  2197. # honest SymPy matrices defer to their class's routine
  2198. if getattr(other, 'is_Matrix', False):
  2199. # call the highest-priority class's _eval_add
  2200. a, b = self, other
  2201. if a.__class__ != classof(a, b):
  2202. b, a = a, b
  2203. return a._eval_add(b)
  2204. # Matrix-like objects can be passed to CommonMatrix routines directly.
  2205. if getattr(other, 'is_MatrixLike', False):
  2206. return MatrixArithmetic._eval_add(self, other)
  2207. raise TypeError('cannot add %s and %s' % (type(self), type(other)))
  2208. @call_highest_priority('__rtruediv__')
  2209. def __truediv__(self, other):
  2210. return self * (self.one / other)
  2211. @call_highest_priority('__rmatmul__')
  2212. def __matmul__(self, other):
  2213. other = _matrixify(other)
  2214. if not getattr(other, 'is_Matrix', False) and not getattr(other, 'is_MatrixLike', False):
  2215. return NotImplemented
  2216. return self.__mul__(other)
  2217. def __mod__(self, other):
  2218. return self.applyfunc(lambda x: x % other)
  2219. @call_highest_priority('__rmul__')
  2220. def __mul__(self, other):
  2221. """Return self*other where other is either a scalar or a matrix
  2222. of compatible dimensions.
  2223. Examples
  2224. ========
  2225. >>> from sympy import Matrix
  2226. >>> A = Matrix([[1, 2, 3], [4, 5, 6]])
  2227. >>> 2*A == A*2 == Matrix([[2, 4, 6], [8, 10, 12]])
  2228. True
  2229. >>> B = Matrix([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
  2230. >>> A*B
  2231. Matrix([
  2232. [30, 36, 42],
  2233. [66, 81, 96]])
  2234. >>> B*A
  2235. Traceback (most recent call last):
  2236. ...
  2237. ShapeError: Matrices size mismatch.
  2238. >>>
  2239. See Also
  2240. ========
  2241. matrix_multiply_elementwise
  2242. """
  2243. return self.multiply(other)
  2244. def multiply(self, other, dotprodsimp=None):
  2245. """Same as __mul__() but with optional simplification.
  2246. Parameters
  2247. ==========
  2248. dotprodsimp : bool, optional
  2249. Specifies whether intermediate term algebraic simplification is used
  2250. during matrix multiplications to control expression blowup and thus
  2251. speed up calculation. Default is off.
  2252. """
  2253. isimpbool = _get_intermediate_simp_bool(False, dotprodsimp)
  2254. other = _matrixify(other)
  2255. # matrix-like objects can have shapes. This is
  2256. # our first sanity check. Double check other is not explicitly not a Matrix.
  2257. if (hasattr(other, 'shape') and len(other.shape) == 2 and
  2258. (getattr(other, 'is_Matrix', True) or
  2259. getattr(other, 'is_MatrixLike', True))):
  2260. if self.shape[1] != other.shape[0]:
  2261. raise ShapeError("Matrix size mismatch: %s * %s." % (
  2262. self.shape, other.shape))
  2263. # honest SymPy matrices defer to their class's routine
  2264. if getattr(other, 'is_Matrix', False):
  2265. m = self._eval_matrix_mul(other)
  2266. if isimpbool:
  2267. return m._new(m.rows, m.cols, [_dotprodsimp(e) for e in m])
  2268. return m
  2269. # Matrix-like objects can be passed to CommonMatrix routines directly.
  2270. if getattr(other, 'is_MatrixLike', False):
  2271. return MatrixArithmetic._eval_matrix_mul(self, other)
  2272. # if 'other' is not iterable then scalar multiplication.
  2273. if not isinstance(other, Iterable):
  2274. try:
  2275. return self._eval_scalar_mul(other)
  2276. except TypeError:
  2277. pass
  2278. return NotImplemented
  2279. def multiply_elementwise(self, other):
  2280. """Return the Hadamard product (elementwise product) of A and B
  2281. Examples
  2282. ========
  2283. >>> from sympy import Matrix
  2284. >>> A = Matrix([[0, 1, 2], [3, 4, 5]])
  2285. >>> B = Matrix([[1, 10, 100], [100, 10, 1]])
  2286. >>> A.multiply_elementwise(B)
  2287. Matrix([
  2288. [ 0, 10, 200],
  2289. [300, 40, 5]])
  2290. See Also
  2291. ========
  2292. sympy.matrices.matrixbase.MatrixBase.cross
  2293. sympy.matrices.matrixbase.MatrixBase.dot
  2294. multiply
  2295. """
  2296. if self.shape != other.shape:
  2297. raise ShapeError("Matrix shapes must agree {} != {}".format(self.shape, other.shape))
  2298. return self._eval_matrix_mul_elementwise(other)
  2299. def __neg__(self):
  2300. return self._eval_scalar_mul(-1)
  2301. @call_highest_priority('__rpow__')
  2302. def __pow__(self, exp):
  2303. """Return self**exp a scalar or symbol."""
  2304. return self.pow(exp)
  2305. def pow(self, exp, method=None):
  2306. r"""Return self**exp a scalar or symbol.
  2307. Parameters
  2308. ==========
  2309. method : multiply, mulsimp, jordan, cayley
  2310. If multiply then it returns exponentiation using recursion.
  2311. If jordan then Jordan form exponentiation will be used.
  2312. If cayley then the exponentiation is done using Cayley-Hamilton
  2313. theorem.
  2314. If mulsimp then the exponentiation is done using recursion
  2315. with dotprodsimp. This specifies whether intermediate term
  2316. algebraic simplification is used during naive matrix power to
  2317. control expression blowup and thus speed up calculation.
  2318. If None, then it heuristically decides which method to use.
  2319. """
  2320. if method is not None and method not in ['multiply', 'mulsimp', 'jordan', 'cayley']:
  2321. raise TypeError('No such method')
  2322. if self.rows != self.cols:
  2323. raise NonSquareMatrixError()
  2324. a = self
  2325. jordan_pow = getattr(a, '_matrix_pow_by_jordan_blocks', None)
  2326. exp = sympify(exp)
  2327. if exp.is_zero:
  2328. return a._new(a.rows, a.cols, lambda i, j: int(i == j))
  2329. if exp == 1:
  2330. return a
  2331. diagonal = getattr(a, 'is_diagonal', None)
  2332. if diagonal is not None and diagonal():
  2333. return a._new(a.rows, a.cols, lambda i, j: a[i,j]**exp if i == j else 0)
  2334. if exp.is_Number and exp % 1 == 0:
  2335. if a.rows == 1:
  2336. return a._new([[a[0]**exp]])
  2337. if exp < 0:
  2338. exp = -exp
  2339. a = a.inv()
  2340. # When certain conditions are met,
  2341. # Jordan block algorithm is faster than
  2342. # computation by recursion.
  2343. if method == 'jordan':
  2344. try:
  2345. return jordan_pow(exp)
  2346. except MatrixError:
  2347. if method == 'jordan':
  2348. raise
  2349. elif method == 'cayley':
  2350. if not exp.is_Number or exp % 1 != 0:
  2351. raise ValueError("cayley method is only valid for integer powers")
  2352. return a._eval_pow_by_cayley(exp)
  2353. elif method == "mulsimp":
  2354. if not exp.is_Number or exp % 1 != 0:
  2355. raise ValueError("mulsimp method is only valid for integer powers")
  2356. return a._eval_pow_by_recursion_dotprodsimp(exp)
  2357. elif method == "multiply":
  2358. if not exp.is_Number or exp % 1 != 0:
  2359. raise ValueError("multiply method is only valid for integer powers")
  2360. return a._eval_pow_by_recursion(exp)
  2361. elif method is None and exp.is_Number and exp % 1 == 0:
  2362. if exp.is_Float:
  2363. exp = Integer(exp)
  2364. # Decide heuristically which method to apply
  2365. if a.rows == 2 and exp > 100000:
  2366. return jordan_pow(exp)
  2367. elif _get_intermediate_simp_bool(True, None):
  2368. return a._eval_pow_by_recursion_dotprodsimp(exp)
  2369. elif exp > 10000:
  2370. return a._eval_pow_by_cayley(exp)
  2371. else:
  2372. return a._eval_pow_by_recursion(exp)
  2373. if jordan_pow:
  2374. try:
  2375. return jordan_pow(exp)
  2376. except NonInvertibleMatrixError:
  2377. # Raised by jordan_pow on zero determinant matrix unless exp is
  2378. # definitely known to be a non-negative integer.
  2379. # Here we raise if n is definitely not a non-negative integer
  2380. # but otherwise we can leave this as an unevaluated MatPow.
  2381. if exp.is_integer is False or exp.is_nonnegative is False:
  2382. raise
  2383. from sympy.matrices.expressions import MatPow
  2384. return MatPow(a, exp)
  2385. @call_highest_priority('__add__')
  2386. def __radd__(self, other):
  2387. return self + other
  2388. @call_highest_priority('__matmul__')
  2389. def __rmatmul__(self, other):
  2390. other = _matrixify(other)
  2391. if not getattr(other, 'is_Matrix', False) and not getattr(other, 'is_MatrixLike', False):
  2392. return NotImplemented
  2393. return self.__rmul__(other)
  2394. @call_highest_priority('__mul__')
  2395. def __rmul__(self, other):
  2396. return self.rmultiply(other)
  2397. def rmultiply(self, other, dotprodsimp=None):
  2398. """Same as __rmul__() but with optional simplification.
  2399. Parameters
  2400. ==========
  2401. dotprodsimp : bool, optional
  2402. Specifies whether intermediate term algebraic simplification is used
  2403. during matrix multiplications to control expression blowup and thus
  2404. speed up calculation. Default is off.
  2405. """
  2406. isimpbool = _get_intermediate_simp_bool(False, dotprodsimp)
  2407. other = _matrixify(other)
  2408. # matrix-like objects can have shapes. This is
  2409. # our first sanity check. Double check other is not explicitly not a Matrix.
  2410. if (hasattr(other, 'shape') and len(other.shape) == 2 and
  2411. (getattr(other, 'is_Matrix', True) or
  2412. getattr(other, 'is_MatrixLike', True))):
  2413. if self.shape[0] != other.shape[1]:
  2414. raise ShapeError("Matrix size mismatch.")
  2415. # honest SymPy matrices defer to their class's routine
  2416. if getattr(other, 'is_Matrix', False):
  2417. m = self._eval_matrix_rmul(other)
  2418. if isimpbool:
  2419. return m._new(m.rows, m.cols, [_dotprodsimp(e) for e in m])
  2420. return m
  2421. # Matrix-like objects can be passed to CommonMatrix routines directly.
  2422. if getattr(other, 'is_MatrixLike', False):
  2423. return MatrixArithmetic._eval_matrix_rmul(self, other)
  2424. # if 'other' is not iterable then scalar multiplication.
  2425. if not isinstance(other, Iterable):
  2426. try:
  2427. return self._eval_scalar_rmul(other)
  2428. except TypeError:
  2429. pass
  2430. return NotImplemented
  2431. @call_highest_priority('__sub__')
  2432. def __rsub__(self, a):
  2433. return (-self) + a
  2434. @call_highest_priority('__rsub__')
  2435. def __sub__(self, a):
  2436. return self + (-a)
  2437. class MatrixCommon(MatrixArithmetic, MatrixOperations, MatrixProperties,
  2438. MatrixSpecial, MatrixShaping):
  2439. """All common matrix operations including basic arithmetic, shaping,
  2440. and special matrices like `zeros`, and `eye`."""
  2441. _diff_wrt: bool = True
  2442. class _MinimalMatrix:
  2443. """Class providing the minimum functionality
  2444. for a matrix-like object and implementing every method
  2445. required for a `MatrixRequired`. This class does not have everything
  2446. needed to become a full-fledged SymPy object, but it will satisfy the
  2447. requirements of anything inheriting from `MatrixRequired`. If you wish
  2448. to make a specialized matrix type, make sure to implement these
  2449. methods and properties with the exception of `__init__` and `__repr__`
  2450. which are included for convenience."""
  2451. is_MatrixLike = True
  2452. _sympify = staticmethod(sympify)
  2453. _class_priority = 3
  2454. zero = S.Zero
  2455. one = S.One
  2456. is_Matrix = True
  2457. is_MatrixExpr = False
  2458. @classmethod
  2459. def _new(cls, *args, **kwargs):
  2460. return cls(*args, **kwargs)
  2461. def __init__(self, rows, cols=None, mat=None, copy=False):
  2462. if isfunction(mat):
  2463. # if we passed in a function, use that to populate the indices
  2464. mat = [mat(i, j) for i in range(rows) for j in range(cols)]
  2465. if cols is None and mat is None:
  2466. mat = rows
  2467. rows, cols = getattr(mat, 'shape', (rows, cols))
  2468. try:
  2469. # if we passed in a list of lists, flatten it and set the size
  2470. if cols is None and mat is None:
  2471. mat = rows
  2472. cols = len(mat[0])
  2473. rows = len(mat)
  2474. mat = [x for l in mat for x in l]
  2475. except (IndexError, TypeError):
  2476. pass
  2477. self.mat = tuple(self._sympify(x) for x in mat)
  2478. self.rows, self.cols = rows, cols
  2479. if self.rows is None or self.cols is None:
  2480. raise NotImplementedError("Cannot initialize matrix with given parameters")
  2481. def __getitem__(self, key):
  2482. def _normalize_slices(row_slice, col_slice):
  2483. """Ensure that row_slice and col_slice do not have
  2484. `None` in their arguments. Any integers are converted
  2485. to slices of length 1"""
  2486. if not isinstance(row_slice, slice):
  2487. row_slice = slice(row_slice, row_slice + 1, None)
  2488. row_slice = slice(*row_slice.indices(self.rows))
  2489. if not isinstance(col_slice, slice):
  2490. col_slice = slice(col_slice, col_slice + 1, None)
  2491. col_slice = slice(*col_slice.indices(self.cols))
  2492. return (row_slice, col_slice)
  2493. def _coord_to_index(i, j):
  2494. """Return the index in _mat corresponding
  2495. to the (i,j) position in the matrix. """
  2496. return i * self.cols + j
  2497. if isinstance(key, tuple):
  2498. i, j = key
  2499. if isinstance(i, slice) or isinstance(j, slice):
  2500. # if the coordinates are not slices, make them so
  2501. # and expand the slices so they don't contain `None`
  2502. i, j = _normalize_slices(i, j)
  2503. rowsList, colsList = list(range(self.rows))[i], \
  2504. list(range(self.cols))[j]
  2505. indices = (i * self.cols + j for i in rowsList for j in
  2506. colsList)
  2507. return self._new(len(rowsList), len(colsList),
  2508. [self.mat[i] for i in indices])
  2509. # if the key is a tuple of ints, change
  2510. # it to an array index
  2511. key = _coord_to_index(i, j)
  2512. return self.mat[key]
  2513. def __eq__(self, other):
  2514. try:
  2515. classof(self, other)
  2516. except TypeError:
  2517. return False
  2518. return (
  2519. self.shape == other.shape and list(self) == list(other))
  2520. def __len__(self):
  2521. return self.rows*self.cols
  2522. def __repr__(self):
  2523. return "_MinimalMatrix({}, {}, {})".format(self.rows, self.cols,
  2524. self.mat)
  2525. @property
  2526. def shape(self):
  2527. return (self.rows, self.cols)
  2528. class _CastableMatrix: # this is needed here ONLY FOR TESTS.
  2529. def as_mutable(self):
  2530. return self
  2531. def as_immutable(self):
  2532. return self
  2533. class _MatrixWrapper:
  2534. """Wrapper class providing the minimum functionality for a matrix-like
  2535. object: .rows, .cols, .shape, indexability, and iterability. CommonMatrix
  2536. math operations should work on matrix-like objects. This one is intended for
  2537. matrix-like objects which use the same indexing format as SymPy with respect
  2538. to returning matrix elements instead of rows for non-tuple indexes.
  2539. """
  2540. is_Matrix = False # needs to be here because of __getattr__
  2541. is_MatrixLike = True
  2542. def __init__(self, mat, shape):
  2543. self.mat = mat
  2544. self.shape = shape
  2545. self.rows, self.cols = shape
  2546. def __getitem__(self, key):
  2547. if isinstance(key, tuple):
  2548. return sympify(self.mat.__getitem__(key))
  2549. return sympify(self.mat.__getitem__((key // self.rows, key % self.cols)))
  2550. def __iter__(self): # supports numpy.matrix and numpy.array
  2551. mat = self.mat
  2552. cols = self.cols
  2553. return iter(sympify(mat[r, c]) for r in range(self.rows) for c in range(cols))
  2554. def _matrixify(mat):
  2555. """If `mat` is a Matrix or is matrix-like,
  2556. return a Matrix or MatrixWrapper object. Otherwise
  2557. `mat` is passed through without modification."""
  2558. if getattr(mat, 'is_Matrix', False) or getattr(mat, 'is_MatrixLike', False):
  2559. return mat
  2560. if not(getattr(mat, 'is_Matrix', True) or getattr(mat, 'is_MatrixLike', True)):
  2561. return mat
  2562. shape = None
  2563. if hasattr(mat, 'shape'): # numpy, scipy.sparse
  2564. if len(mat.shape) == 2:
  2565. shape = mat.shape
  2566. elif hasattr(mat, 'rows') and hasattr(mat, 'cols'): # mpmath
  2567. shape = (mat.rows, mat.cols)
  2568. if shape:
  2569. return _MatrixWrapper(mat, shape)
  2570. return mat
  2571. def a2idx(j, n=None):
  2572. """Return integer after making positive and validating against n."""
  2573. if not isinstance(j, int):
  2574. jindex = getattr(j, '__index__', None)
  2575. if jindex is not None:
  2576. j = jindex()
  2577. else:
  2578. raise IndexError("Invalid index a[%r]" % (j,))
  2579. if n is not None:
  2580. if j < 0:
  2581. j += n
  2582. if not (j >= 0 and j < n):
  2583. raise IndexError("Index out of range: a[%s]" % (j,))
  2584. return int(j)
  2585. def classof(A, B):
  2586. """
  2587. Get the type of the result when combining matrices of different types.
  2588. Currently the strategy is that immutability is contagious.
  2589. Examples
  2590. ========
  2591. >>> from sympy import Matrix, ImmutableMatrix
  2592. >>> from sympy.matrices.matrixbase import classof
  2593. >>> M = Matrix([[1, 2], [3, 4]]) # a Mutable Matrix
  2594. >>> IM = ImmutableMatrix([[1, 2], [3, 4]])
  2595. >>> classof(M, IM)
  2596. <class 'sympy.matrices.immutable.ImmutableDenseMatrix'>
  2597. """
  2598. priority_A = getattr(A, '_class_priority', None)
  2599. priority_B = getattr(B, '_class_priority', None)
  2600. if None not in (priority_A, priority_B):
  2601. if A._class_priority > B._class_priority:
  2602. return A.__class__
  2603. else:
  2604. return B.__class__
  2605. try:
  2606. import numpy
  2607. except ImportError:
  2608. pass
  2609. else:
  2610. if isinstance(A, numpy.ndarray):
  2611. return B.__class__
  2612. if isinstance(B, numpy.ndarray):
  2613. return A.__class__
  2614. raise TypeError("Incompatible classes %s, %s" % (A.__class__, B.__class__))