K iRddlmZddlmZddlmZddlmZddlm Z ddl m Z m Z m Z mZmZmZmZmZmZmZmZddlmZddlmZmZdd lmZdd lmZdd lmZdd l m!Z"dd l#m$Z$ddl%m&Z&m'Z'm(Z(ddl)m*Z*Gdde Z+Gdde Z,Gdde Z-GddeZ.Gdde Z/Gdde Z0Gdde Z1dZ2Gdd e Z3Gd!d"e Z4Gd#d$e Z5Gd%d&e5Z6Gd'd(e Z7Gd)d*e Z8Gd+d,e Z9d@d.Z:dAd/Z;d0Zd3Z?d4Z@d5ZAd6ZBd7ZCd8ZDGd9d:ZEGd;deEeHZIdd?lJmKZKy-)C) annotations)Anyreduce) permutations) Permutation) BasicExprFunctiondiffPowMulAddLambdaSTupleDict)cacheit)SymbolDummy)Str)_sympify factorial)ImmutableDenseMatrix)solve)sympy_deprecation_warningSymPyDeprecationWarningignore_warnings)ImmutableDenseNDimArraycBeZdZdZfdZedZedZxZS)Manifolda A mathematical manifold. Explanation =========== A manifold is a topological space that locally resembles Euclidean space near each point [1]. This class does not provide any means to study the topological characteristics of the manifold that it represents, though. Parameters ========== name : str The name of the manifold. dim : int The dimension of the manifold. Examples ======== >>> from sympy.diffgeom import Manifold >>> m = Manifold('M', 2) >>> m M >>> m.dim 2 References ========== .. [1] https://en.wikipedia.org/wiki/Manifold c t|ts t|}t|}t||||}t dg|_|S)Nz Manifold.patches is deprecated. The Manifold object is now immutable. Instead use a separate list to keep track of the patches. ) isinstancerrsuper__new___deprecated_listpatches)clsnamedimkwargsobj __class__s ]/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/sympy/diffgeom/diffgeom.pyr&zManifold.__new__FsN$$t9Dsmgoc4-&    c |jdSNrargsselfs r/r*z Manifold.nameTyy|r0c |jdSNr3r5s r/r+z Manifold.dimXr7r0) __name__ __module__ __qualname____doc__r&propertyr*r+ __classcell__r.s@r/r"r"!s6"H r0r"cReZdZdZfdZedZedZedZxZ S)Patcha A patch on a manifold. Explanation =========== Coordinate patch, or patch in short, is a simply-connected open set around a point in the manifold [1]. On a manifold one can have many patches that do not always include the whole manifold. On these patches coordinate charts can be defined that permit the parameterization of any point on the patch in terms of a tuple of real numbers (the coordinates). This class does not provide any means to study the topological characteristics of the patch that it represents. Parameters ========== name : str The name of the patch. manifold : Manifold The manifold on which the patch is defined. Examples ======== >>> from sympy.diffgeom import Manifold, Patch >>> m = Manifold('M', 2) >>> p = Patch('P', m) >>> p P >>> p.dim 2 References ========== .. [1] G. Sussman, J. Wisdom, W. Farr, Functional Differential Geometry (2013) c t|ts t|}t| |||}|jj j |tdg|_|S)Nz Patch.coord_systms is deprecated. The Patch class is now immutable. Instead use a separate list to keep track of coordinate systems. ) r$rr%r&manifoldr(appendr' coord_systems)r)r*rEr,r-r.s r/r&z Patch.__new__s^$$t9Dgoc42 ##C(,    r0c |jdSr2r3r5s r/r*z Patch.namer7r0c |jdSr9r3r5s r/rEzPatch.manifoldr7r0c.|jjSNrEr+r5s r/r+z Patch.dim}}   r0) r;r<r=r>r&r?r*rEr+r@rAs@r/rCrC]sJ)T !!r0rCcZeZdZdZdiffd ZedZedZedZedZ edZ ed Z d Z e d Zed Zeed Ze dZddZe dZe dZddZdZddZeZddZdZdZdZeZdZ e Z!dZ"dZ#dZ$dZ%xZ&S) CoordSystemai A coordinate system defined on the patch. Explanation =========== Coordinate system is a system that uses one or more coordinates to uniquely determine the position of the points or other geometric elements on a manifold [1]. By passing ``Symbols`` to *symbols* parameter, user can define the name and assumptions of coordinate symbols of the coordinate system. If not passed, these symbols are generated automatically and are assumed to be real valued. By passing *relations* parameter, user can define the transform relations of coordinate systems. Inverse transformation and indirect transformation can be found automatically. If this parameter is not passed, coordinate transformation cannot be done. Parameters ========== name : str The name of the coordinate system. patch : Patch The patch where the coordinate system is defined. symbols : list of Symbols, optional Defines the names and assumptions of coordinate symbols. relations : dict, optional Key is a tuple of two strings, who are the names of the systems where the coordinates transform from and transform to. Value is a tuple of the symbols before transformation and a tuple of the expressions after transformation. Examples ======== We define two-dimensional Cartesian coordinate system and polar coordinate system. >>> from sympy import symbols, pi, sqrt, atan2, cos, sin >>> from sympy.diffgeom import Manifold, Patch, CoordSystem >>> m = Manifold('M', 2) >>> p = Patch('P', m) >>> x, y = symbols('x y', real=True) >>> r, theta = symbols('r theta', nonnegative=True) >>> relation_dict = { ... ('Car2D', 'Pol'): [(x, y), (sqrt(x**2 + y**2), atan2(y, x))], ... ('Pol', 'Car2D'): [(r, theta), (r*cos(theta), r*sin(theta))] ... } >>> Car2D = CoordSystem('Car2D', p, (x, y), relation_dict) >>> Pol = CoordSystem('Pol', p, (r, theta), relation_dict) ``symbols`` property returns ``CoordinateSymbol`` instances. These symbols are not same with the symbols used to construct the coordinate system. >>> Car2D Car2D >>> Car2D.dim 2 >>> Car2D.symbols (x, y) >>> _[0].func ``transformation()`` method returns the transformation function from one coordinate system to another. ``transform()`` method returns the transformed coordinates. >>> Car2D.transformation(Pol) Lambda((x, y), Matrix([ [sqrt(x**2 + y**2)], [ atan2(y, x)]])) >>> Car2D.transform(Pol) Matrix([ [sqrt(x**2 + y**2)], [ atan2(y, x)]]) >>> Car2D.transform(Pol, [1, 2]) Matrix([ [sqrt(5)], [atan(2)]]) ``jacobian()`` method returns the Jacobian matrix of coordinate transformation between two systems. ``jacobian_determinant()`` method returns the Jacobian determinant of coordinate transformation between two systems. >>> Pol.jacobian(Car2D) Matrix([ [cos(theta), -r*sin(theta)], [sin(theta), r*cos(theta)]]) >>> Pol.jacobian(Car2D, [1, pi/2]) Matrix([ [0, -1], [1, 0]]) >>> Car2D.jacobian_determinant(Pol) 1/sqrt(x**2 + y**2) >>> Car2D.jacobian_determinant(Pol, [1,0]) 1 References ========== .. [1] https://en.wikipedia.org/wiki/Coordinate_system Nc t|ts t|}||jdd}|Ett |j Dcgc]}t |jd|d c}}ntd|ddj|Dcgc]}dt|zd zc}d d d t|Dcgc]}t |dc}}ng} |D]} t| t r:| jt | jfi| jjMt| ts^td| d| dd d | jt | dt| }i} |jD]\} } | \}}t|ts t|}t|ts t|}t||}t| t r+t#| j$t#| j&f} nt#| dt#| df} | | |<t)| }t*|Y|||||}t/di|_|Dcgc] }t|c}|_|j4j6j||Dcgc]}t9t|c}|_t9|_|Scc}wcc}wcc}wcc}wcc}w)Nnames_T)realzx The 'names' argument to CoordSystem is deprecated. Use 'symbols' instead. That is, replace CoordSystem(..., names=z') with CoordSystem(..., symbols=[z, zSymbol(z , real=True)z]) 1.7deprecated-diffgeom-mutabledeprecated_since_versionactive_deprecations_targetz Passing a string as the coordinate symbol name to CoordSystem is deprecated. Pass a Symbol with the appropriate name and assumptions instead. That is, replace z with Symbol(z&, real=True). rr:z CoordSystem.transforms is deprecated. The CoordSystem class is now immutable. Use the 'relations' keyword argument to the CoordSystems() constructor to specify relations. )r$rgetrranger+rr*rjoinreprrF _assumptions generatorstritemsrtuple signatureexprrr%r&_deprecated_dict transforms_namespatchrGr_dummies_dummy)r)r*rgsymbols relationsr,rQinsymssrel_tempkvs1s2keyr-r.s r/r&zCoordSystem.__new__s$$t9D ?JJw-E}$UYY/1 15DA1 *"7# $yyX])^ST)d1g*=*N)^_`a .3/L  49:qfQT*:D 6a(KKqvv J1I1I JK3'- M!' 273P KKqt 45! 6"TlG??$ CAaFBb#&Wb#&WB-C!V$1;;'qvv71Q4[%!+.HSM N goc4C*   '..c!f.  &&s+/67!c!f 7 W  W1*_ ;f/7s#KK$K)(K.+K3c |jdSr2r3r5s r/r*zCoordSystem.namegr7r0c |jdSr9r3r5s r/rgzCoordSystem.patchkr7r0c.|jjSrK)rgrEr5s r/rEzCoordSystem.manifoldoszz"""r0cXtfdtjdDS)Nc3fK|](\}}t|fi|jj*ywrK)CoordinateSymbolr]r^).0rlror6s r/ z&CoordSystem.symbols..us30!&dAJ1I1IJ0s.1)ra enumerater4r5s`r/rjzCoordSystem.symbolsss*0 1.00 0r0c |jdS)Nr3r5s r/rkzCoordSystem.relationsxr7r0c.|jjSrK)rgr+r5s r/r+zCoordSystem.dim|szz~~r0c|jd}t|j|j}||k(rt|j}nu||j vrt|j |d}nK|ddd|j vrt|j ||}nt|j||}t||S)a Return coordinate transformation function from *self* to *sys*. Parameters ========== sys : CoordSystem Returns ======= sympy.Lambda Examples ======== >>> from sympy.diffgeom.rn import R2_r, R2_p >>> R2_r.transformation(R2_p) Lambda((x, y), Matrix([ [sqrt(x**2 + y**2)], [ atan2(y, x)]])) r~r:N) r4rr*Matrixrjrk_inverse_transformation_indirect_transformationr)r6sysrbrurcs r/transformationzCoordSystem.transformations0IIaL DIIsxx( 3;$,,'D DNN "$..-a01D 2Y$.. ($66sDABD$77cBCDi&&r0c2tt||Dcgc] }|d|dz c}t|d}t|dk(rd}t |j ||t|dkDrd}t |j |||dScc}w)Nrr:Tdictz,Cannot solve inverse relation from {} to {}.z1Obtained multiple inverse relation from {} to {}.)rziplistlenNotImplementedErrorformat ValueError)sym1sym2exprs sys1_name sys2_nametrettemps r/_solve_inversezCoordSystem._solve_inverses"%dE"2 3QQqTAaD[ 3 JT# s8q=AD%dkk)Y&GH H X\FDT[[I>? ?1v  4sBc|j|}|j|j|j||j|j}t |j}|Dcgc]}|| c}Scc}wrK) transformrrjr*ra)r)sys1sys2forward inv_resultsrbros r/rz#CoordSystem._inverse_transformationsc..&((t||W)-DII? $,,' (121 A222s( A7c |j}|j||}g}t||ddD]z\}}||f|vr|j|||f#|||f\}} t d|D} |j || | ||t fd|D|j| f||j d} | |D]\} t fd| D  S)Nr:c30K|]}tywrK)r)r|rls r/r}z7CoordSystem._indirect_transformation..s3UW3sc3(K|] }| ywrK)r|rors r/r}z7CoordSystem._indirect_transformation..s1qCF1sr~c3TK|]}|jt!ywrK)subsr)r|ernewsymss r/r}z7CoordSystem._indirect_transformation..s!H!!&&We!45Hs%()rk _dijkstrarrFrarr4)r)rrrelpathrersrtr inv_exprsrrnnewexprsrrrs @@@r/rz$CoordSystem._indirect_transformations nn}}T4( $QR) /FBBx3!!#r2h-0"%r2h-i3d33((tYBG1D11!!4+. /yy|!+ I GXHxHHE I r0c |j}i |jD]C\}}| vr|h |<n |j|| vr|h |<0 |j|E Dcic]}|dgdg c} fd}||j t j dd}d} j D]$\}} d| dcxkr|ksn| dr| d}|}&|n ||d |jd} | j|j| |jgk(r td| Scc}w)Nrcd|d<|D]W}|ddz}|d|k\s |dr"||d<t|d|d<|dj|Yy)Nr:r~r)rrF)rnewsysdistancegraph path_dicts r/visitz$CoordSystem._dijkstra..visits !IcN1 * 5$S>!,q0V$Q'839V;LQ;O+3If%a(+/ #q0A+BIf%a(f%a(//4  5r0c |dSr2r)xs r/z'CoordSystem._dijkstra..s !r0)rur~r:z)Two coordinate systems are not connected.) rkkeysaddr*maxvaluesr`rFKeyError) rrrkrsrtrr min_distancerlstresultrrs @@r/rzCoordSystem._dijkstras` NN nn& "FBDb b b!Db b b! "055S!R^5  5 diiy//1}EaHLF%OO- !Ss1v--c!f#&q6L F !~ &M499%a( dii dii[ FG G ;6s+ Ectdddt||\}}t|t|f|j|<|r|j |||j|<|r|j yy)Nz The CoordSystem.connect_to() method is deprecated. Instead, generate a new instance of CoordSystem with the 'relations' keyword argument (CoordSystem classes are now immutable). rTrUrV)rdummyfyrre _inv_transf_fill_gaps_in_transformations)r6to_sys from_coordsto_exprsinverse fill_in_gapss r/ connect_tozCoordSystem.connect_to s{!  &+'D !( X > X"("5vh7G"G &*&6&6{H&MF  d #   . . 0 r0c |Dcgc]}|j}}tt||Dcgc] }|d|dz c}t|dd}|Dcgc]}|| }}t |t |fScc}wcc}wcc}w)Nrr:Tr)as_dummyrrrr)rrrlinv_fromrinv_tofcs r/rzCoordSystem._inv_transfs+66QAJJL66"%h"9 :QQqTAaD[ :  D**+-(33&*33h// 7 :3sBB B ctrK)rrr0r/rz)CoordSystem._fill_gaps_in_transformations's "!r0cr| |j}||k7r|j|}||}|St|}|S)a Return the result of coordinate transformation from *self* to *sys*. If coordinates are not given, coordinate symbols of *self* are used. Parameters ========== sys : CoordSystem coordinates : Any iterable, optional. Returns ======= sympy.ImmutableDenseMatrix containing CoordinateSymbol Examples ======== >>> from sympy.diffgeom.rn import R2_r, R2_p >>> R2_r.transform(R2_p) Matrix([ [sqrt(x**2 + y**2)], [ atan2(y, x)]]) >>> R2_r.transform(R2_p, [0, 1]) Matrix([ [ 1], [pi/2]]) )rjrr)r6r coordinatestransfs r/rzCoordSystem.transform0sN>  ,,K 3;((-F +.K!-Kr0ctdddt|}||k7rQtt5|j|}ddddj t t|d|}|S#1swY5xYw)z0Transform ``coords`` to coord system ``to_sys``.z The CoordSystem.coord_tuple_transform_to() method is deprecated. Use the CoordSystem.transform() method instead. rTrUrVNr:r)rrrrrerrr)r6rcoordsrs r/coord_tuple_transform_toz$CoordSystem.coord_tuple_transform_toXs|! &+'D   6> !89 10 1AY^^DVAY)?$@AF  1 1s A22A;c|j|j|j}|.|jt t |j|}|S)a Return the jacobian matrix of a transformation on given coordinates. If coordinates are not given, coordinate symbols of *self* are used. Parameters ========== sys : CoordSystem coordinates : Any iterable, optional. Returns ======= sympy.ImmutableDenseMatrix Examples ======== >>> from sympy.diffgeom.rn import R2_r, R2_p >>> R2_p.jacobian(R2_r) Matrix([ [cos(theta), -rho*sin(theta)], [sin(theta), rho*cos(theta)]]) >>> R2_p.jacobian(R2_r, [1, 0]) Matrix([ [1, 0], [0, 1]]) )rjacobianrjrrr)r6rrrs r/rzCoordSystem.jacobianjsJ>$--dll;  "[[c$,, &D!EFF r0cB|j||jS)a6 Return the jacobian determinant of a transformation on given coordinates. If coordinates are not given, coordinate symbols of *self* are used. Parameters ========== sys : CoordSystem coordinates : Any iterable, optional. Returns ======= sympy.Expr Examples ======== >>> from sympy.diffgeom.rn import R2_r, R2_p >>> R2_r.jacobian_determinant(R2_p) 1/sqrt(x**2 + y**2) >>> R2_r.jacobian_determinant(R2_p, [1, 0]) 1 )rdet)r6rrs r/jacobian_determinantz CoordSystem.jacobian_determinants8}}S+.2244r0ct||S)z?Create a ``Point`` with coordinates given in this coord system.)Point)r6rs r/pointzCoordSystem.pointsT6""r0c$|j|S)z:Calculate the coordinates of a point in this coord system.)r)r6rs r/point_to_coordszCoordSystem.point_to_coordss||D!!r0ct||S)zQReturn ``BaseScalarField`` that takes a point and returns one of the coordinates.)BaseScalarFieldr6 coord_indexs r/ base_scalarzCoordSystem.base_scalarst[11r0cpt|jDcgc]}|j|c}Scc}w)zrReturns a list of all coordinate functions. For more details see the ``base_scalar`` method of this class.)rZr+rr6rls r/ base_scalarszCoordSystem.base_scalars+.3488_=  #===3ct||S)zReturn a basis vector field. The basis vector field for this coordinate system. It is also an operator on scalar fields.)BaseVectorFieldrs r/ base_vectorzCoordSystem.base_vectorst[11r0cpt|jDcgc]}|j|c}Scc}w)zjReturns a list of all base vectors. For more details see the ``base_vector`` method of this class.)rZr+rrs r/ base_vectorszCoordSystem.base_vectorsrrc6t|j|S)zReturn a basis 1-form field. The basis one-form field for this coordinate system. It is also an operator on vector fields.) Differentialcoord_functionrs r/ base_oneformzCoordSystem.base_oneformsD// <==r0cpt|jDcgc]}|j|c}Scc}w)zlReturns a list of all base oneforms. For more details see the ``base_oneform`` method of this class.)rZr+rrs r/ base_oneformszCoordSystem.base_oneformss+/4DHHo>!!!$>>>r)TFrK)'r;r<r=r>r&r?r*rgrErjrkr+r staticmethodr classmethodrrrrrrrrrrjacobian_matrixrrrrrrcoord_functionsrrrrr@rAs@r/rOrOsplZ+/"Tl##00#'J  33  ,--^1(00""&P$"FO5F#"2!N>#O2 > > ?r0rOc8eZdZdZfdZdZdZfdZxZS)r{aA symbol which denotes an abstract value of i-th coordinate of the coordinate system with given context. Explanation =========== Each coordinates in coordinate system are represented by unique symbol, such as x, y, z in Cartesian coordinate system. You may not construct this class directly. Instead, use `symbols` method of CoordSystem. Parameters ========== coord_sys : CoordSystem index : integer Examples ======== >>> from sympy import symbols, Lambda, Matrix, sqrt, atan2, cos, sin >>> from sympy.diffgeom import Manifold, Patch, CoordSystem >>> m = Manifold('M', 2) >>> p = Patch('P', m) >>> x, y = symbols('x y', real=True) >>> r, theta = symbols('r theta', nonnegative=True) >>> relation_dict = { ... ('Car2D', 'Pol'): Lambda((x, y), Matrix([sqrt(x**2 + y**2), atan2(y, x)])), ... ('Pol', 'Car2D'): Lambda((r, theta), Matrix([r*cos(theta), r*sin(theta)])) ... } >>> Car2D = CoordSystem('Car2D', p, [x, y], relation_dict) >>> Pol = CoordSystem('Pol', p, [r, theta], relation_dict) >>> x, y = Car2D.symbols ``CoordinateSymbol`` contains its coordinate symbol and index. >>> x.name 'x' >>> x.coord_sys == Car2D True >>> x.index 0 >>> x.is_real True You can transform ``CoordinateSymbol`` into other coordinate system using ``rewrite()`` method. >>> x.rewrite(Pol) r*cos(theta) >>> sqrt(x**2 + y**2).rewrite(Pol).simplify() r c ~|jd|j}t| ||fi|}||_||_|SNr~)r4r*r%r& coord_sysindex)r)rr assumptionsr*r-r.s r/r&zCoordinateSymbol.__new__sD~~a ',,goc47;7!   r0c2|j|jfSrK)rrr5s r/__getnewargs__zCoordinateSymbol.__getnewargs__ s ++r0c|j|jftt|jj zSrK)rrrasorted assumptions0r`r5s r/_hashable_contentz"CoordinateSymbol._hashable_content#s: NNDJJ &**0023 45 5r0c t|tr(|j|j|jSt |||fi|SrK)r$rOrrrr% _eval_rewrite)r6ruler4hintsr.s r/rzCoordinateSymbol._eval_rewrite(s@ dK (>>$..1$**= =w$T49599r0) r;r<r=r>r&rrrr@rAs@r/r{r{s"7p,5 ::r0r{cjeZdZdZfdZedZedZedZddZ edZ xZ S) raPoint defined in a coordinate system. Explanation =========== Mathematically, point is defined in the manifold and does not have any coordinates by itself. Coordinate system is what imbues the coordinates to the point by coordinate chart. However, due to the difficulty of realizing such logic, you must supply a coordinate system and coordinates to define a Point here. The usage of this object after its definition is independent of the coordinate system that was used in order to define it, however due to limitations in the simplification routines you can arrive at complicated expressions if you use inappropriate coordinate systems. Parameters ========== coord_sys : CoordSystem coords : list The coordinates of the point. Examples ======== >>> from sympy import pi >>> from sympy.diffgeom import Point >>> from sympy.diffgeom.rn import R2, R2_r, R2_p >>> rho, theta = R2_p.symbols >>> p = Point(R2_p, [rho, 3*pi/4]) >>> p.manifold == R2 True >>> p.coords() Matrix([ [ rho], [3*pi/4]]) >>> p.coords(R2_r) Matrix([ [-sqrt(2)*rho/2], [ sqrt(2)*rho/2]]) c \t|}t| |||}||_||_|SrK)rr%r& _coord_sys_coords)r)rrr,r-r.s r/r&z Point.__new__^s1goc9f5"  r0c.|jjSrK)r rgr5s r/rgz Point.patches$$$r0c.|jjSrK)r rEr5s r/rEzPoint.manifoldis'''r0c.|jjSrKrLr5s r/r+z Point.dimmrMr0cj| |jS|jj||jS)z Coordinates of the point in given coordinate system. If coordinate system is not passed, it returns the coordinates in the coordinate system in which the point was defined. )r r r)r6rs r/rz Point.coordsqs. ;<< ??,,S$,,? ?r0c.|jjSrK)r  free_symbolsr5s r/rzPoint.free_symbols|s||(((r0rK) r;r<r=r>r&r?rgrEr+rrr@rAs@r/rr.sd-^%%((!! @))r0rceZdZUdZdZfdZedZedZedZ edZ edZ d Z e Zd ed <xZS) raBase scalar field over a manifold for a given coordinate system. Explanation =========== A scalar field takes a point as an argument and returns a scalar. A base scalar field of a coordinate system takes a point and returns one of the coordinates of that point in the coordinate system in question. To define a scalar field you need to choose the coordinate system and the index of the coordinate. The use of the scalar field after its definition is independent of the coordinate system in which it was defined, however due to limitations in the simplification routines you may arrive at more complicated expression if you use unappropriate coordinate systems. You can build complicated scalar fields by just building up SymPy expressions containing ``BaseScalarField`` instances. Parameters ========== coord_sys : CoordSystem index : integer Examples ======== >>> from sympy import Function, pi >>> from sympy.diffgeom import BaseScalarField >>> from sympy.diffgeom.rn import R2_r, R2_p >>> rho, _ = R2_p.symbols >>> point = R2_p.point([rho, 0]) >>> fx, fy = R2_r.base_scalars() >>> ftheta = BaseScalarField(R2_r, 1) >>> fx(point) rho >>> fy(point) 0 >>> (fx**2+fy**2).rcall(point) rho**2 >>> g = Function('g') >>> fg = g(ftheta-pi) >>> fg.rcall(point) g(-pi) Tc \t|}t| |||}||_||_|SrKrr%r&r _indexr)rrr,r-r.s r/r&zBaseScalarField.__new__1goc9e4"  r0c |jdSr2r3r5s r/rzBaseScalarField.coord_sysr7r0c |jdSr9r3r5s r/rzBaseScalarField.indexr7r0c.|jjSrKrrgr5s r/rgzBaseScalarField.patch~~###r0c.|jjSrKrrEr5s r/rEzBaseScalarField.manifold~~&&&r0c.|jjSrKrLr5s r/r+zBaseScalarField.dimrMr0c|d}t|dk7st|ts|S|j|j}t ||j jS)aeEvaluating the field at a point or doing nothing. If the argument is a ``Point`` instance, the field is evaluated at that point. The field is returned itself if the argument is any other object. It is so in order to have working recursive calling mechanics for all fields (check the ``__call__`` method of ``Expr``). rr:)rr$rrr simplifyrdoit)r6r4rrs r/__call__zBaseScalarField.__call__sWQ t9>E5!9Kdoo.t{{+,1133r0zset[Any]r)r;r<r=r>is_commutativer&r?rrrgrEr+r&setr__annotations__r@rAs@r/rrs2hN$$''!! 4 !UL("r0rc|eZdZdZdZfdZedZedZedZ edZ edZ d Z xZ S) raqBase vector field over a manifold for a given coordinate system. Explanation =========== A vector field is an operator taking a scalar field and returning a directional derivative (which is also a scalar field). A base vector field is the same type of operator, however the derivation is specifically done with respect to a chosen coordinate. To define a base vector field you need to choose the coordinate system and the index of the coordinate. The use of the vector field after its definition is independent of the coordinate system in which it was defined, however due to limitations in the simplification routines you may arrive at more complicated expression if you use unappropriate coordinate systems. Parameters ========== coord_sys : CoordSystem index : integer Examples ======== >>> from sympy import Function >>> from sympy.diffgeom.rn import R2_p, R2_r >>> from sympy.diffgeom import BaseVectorField >>> from sympy import pprint >>> x, y = R2_r.symbols >>> rho, theta = R2_p.symbols >>> fx, fy = R2_r.base_scalars() >>> point_p = R2_p.point([rho, theta]) >>> point_r = R2_r.point([x, y]) >>> g = Function('g') >>> s_field = g(fx, fy) >>> v = BaseVectorField(R2_r, 1) >>> pprint(v(s_field)) / d \| |---(g(x, xi))|| \dxi /|xi=y >>> pprint(v(s_field).rcall(point_r).doit()) d --(g(x, y)) dy >>> pprint(v(s_field).rcall(point_p)) / d \| |---(g(rho*cos(theta), xi))|| \dxi /|xi=rho*sin(theta) Fc \t|}t| |||}||_||_|SrKrrs r/r&zBaseVectorField.__new__"rr0c |jdSr2r3r5s r/rzBaseVectorField.coord_sys)r7r0c |jdSr9r3r5s r/rzBaseVectorField.index-r7r0c.|jjSrKrr5s r/rgzBaseVectorField.patch1rr0c.|jjSrKr r5s r/rEzBaseVectorField.manifold5r!r0c.|jjSrKrLr5s r/r+zBaseVectorField.dim9rMr0c t|s t|r td||St|j t }|j j}t|Dcgc]\}}td|z|}}}|jtt||}|j|}|j j}|D cgc]} | j|} } g} |D]R}|j j|j |} | j| |j |j fT|jtt| | }|jtt||} | jtt||j j#} | j%Scc}}wcc} w)zApply on a scalar field. The action of a vector field on a scalar field is a directional differentiation. If the argument is not a scalar field an error is raised. zAOnly scalar fields can be supplied as arguments to vector fields._#_%s)covariant_ordercontravariant_orderrratomsrr rirr rrr rjrrFrrr%)r6 scalar_fieldrd_varrlbd_funcsd_resultrf d_funcs_derivd_funcs_deriv_subjacrs r/r&zBaseVectorField.__call__=s < (,? ,M`a a  KL..?@ &&",/15A)8GaK(/11$$T#lG*D%EF=='((07818 8 AA//**1<<@C  $ $S4;;)>%? @ A==c-9J&K!LMtC$>?@T#fdoo.M.M.O"PQR{{}#19s (GG%)r;r<r=r>r'r&r?rrrgrEr+r&r@rAs@r/rrs~7rN$$''!!"r0rct|jtt}|Dchc]}|jc}Scc}wrK)r5rrr )rcfieldsr;s r/ _find_coordsrAbs* ZZ 9F"( )QALL )) )s5cHeZdZdZfdZedZedZdZxZ S) Commutatora#Commutator of two vector fields. Explanation =========== The commutator of two vector fields `v_1` and `v_2` is defined as the vector field `[v_1, v_2]` that evaluated on each scalar field `f` is equal to `v_1(v_2(f)) - v_2(v_1(f))`. Examples ======== >>> from sympy.diffgeom.rn import R2_p, R2_r >>> from sympy.diffgeom import Commutator >>> from sympy import simplify >>> fx, fy = R2_r.base_scalars() >>> e_x, e_y = R2_r.base_vectors() >>> e_r = R2_p.base_vector(0) >>> c_xy = Commutator(e_x, e_y) >>> c_xr = Commutator(e_x, e_r) >>> c_xy 0 Unfortunately, the current code is not able to compute everything: >>> c_xr Commutator(e_x, e_rho) >>> simplify(c_xr(fy**2)) -2*cos(theta)*y**2/(x**2 + y**2) ct|s't|dk7st|st|dk7r td||k(rtjSt j ||fDcgc] }t|c}}t|dk(rtd||fDrtjS||fDcgc] }t|jt"c}\}}|Dcgc]!}|jj|#}}|Dcgc]!}|jj|#} }d} t||D]9\} } t| |D]%\} }| | | | z|z| || z| zz z } ';| St |E|||}||_||_|Scc}wcc}wcc}wcc}w)Nr:z0Only commutators of vector fields are supported.c3<K|]}t|tywrK)r$r)r|rrs r/r}z%Commutator.__new__..sDa:a1Dsr)r3r4rrZeror(unionrArallrr5rexpandcoeffrr%r&_v1_v2)r)v1v2rrrbases_1bases_2r8coeffs_1coeffs_2resc1b1c2b2r-r.s r/r&zCommutator.__new__s B #6r#:a#?"2&*=b*AQ*FBD D 866MCEKKB8!Da,q/!DE y>Q DB8DDvv *,b 3$%!%QWW_%= > 3 GW6=> ))!,>H>6=> ))!,>H>Ch0 7B!(G47FB2bf9R<"RV)B,66C7 7J'/#r2.CCGCGJ'"E  3>>s.F,<%F1+&F6&F;c |jdSr2r3r5s r/rMz Commutator.v1r7r0c |jdSr9r3r5s r/rNz Commutator.v2r7r0c|j|j||j|j|z S)zcApply on a scalar field. If the argument is not a scalar field an error is raised. )rMrN)r6r6s r/r&zCommutator.__call__s3wwtww|,- 8M0NNNr0) r;r<r=r>r&r?rMrNr&r@rAs@r/rCrChs<!D8Or0rCc<eZdZdZdZfdZedZdZxZ S)raReturn the differential (exterior derivative) of a form field. Explanation =========== The differential of a form (i.e. the exterior derivative) has a complicated definition in the general case. The differential `df` of the 0-form `f` is defined for any vector field `v` as `df(v) = v(f)`. Examples ======== >>> from sympy import Function >>> from sympy.diffgeom.rn import R2_r >>> from sympy.diffgeom import Differential >>> from sympy import pprint >>> fx, fy = R2_r.base_scalars() >>> e_x, e_y = R2_r.base_vectors() >>> g = Function('g') >>> s_field = g(fx, fy) >>> dg = Differential(s_field) >>> dg d(g(x, y)) >>> pprint(dg(e_x)) / d \| |---(g(xi, y))|| \dxi /|xi=x >>> pprint(dg(e_y)) / d \| |---(g(x, xi))|| \dxi /|xi=y Applying the exterior derivative operator twice always results in: >>> Differential(dg) 0 Fct|r tdt|trtj St |||}||_|S)Nz;A vector field was supplied as an argument to Differential.) r4rr$rrrFr%r& _form_field)r) form_fieldr-r.s r/r&zDifferential.__new__sL z *MO O j, /66M'/#z2C(COJr0c |jdSr2r3r5s r/r^zDifferential.form_fieldr7r0c td|Dr tdt|}|dk(r%|dr|dj|jS|S|j}|}d}t |D]}||j|j|d|||dzdz}|d|z|zz }t |dz|D]M}t ||||} | s|j| f|d|z||dz|z||dzdz}|d||zz|zz }O|S)aApply on a list of vector_fields. Explanation =========== If the number of vector fields supplied is not equal to 1 + the order of the form field inside the differential the result is undefined. For 1-forms (i.e. differentials of scalar fields) the evaluation is done as `df(v)=v(f)`. However if `v` is ``None`` instead of a vector field, the differential is returned unchanged. This is done in order to permit partial contractions for higher forms. In the general case the evaluation is done by applying the form field inside the differential on a list with one less elements than the number of elements in the original list. Lowering the number of vector fields is achieved through replacing each pair of fields by their commutator. If the arguments are not vectors or ``None``s an error is raised. c3^K|]%}t|dk7xs t|xr|du'yw)r:N)r4r3r|as r/r}z(Differential.__call__..s9($A&!+Aq/ATqPT}T(s+-zHThe arguments supplied to Differential should be vector fields or Nones.r:rNr)anyrrrcallr]rZrC) r6 vector_fieldsrqr;rrrrlrjcs r/r&zDifferential.__call__sT, (&( (gh h   6Q$Q'--d.>.>??K  AAC1X /aDJJwqww"1!a%& (9:;Qwqy q1ua/A"1Q41.A#AGGaTAbqE\Aa!eAJ%>1q56%JKa!e}Q. / /Jr0) r;r<r=r>r'r&r?r^r&r@rAs@r/rrs.'RN 0r0rc(eZdZdZfdZdZxZS) TensorProductaTensor product of forms. Explanation =========== The tensor product permits the creation of multilinear functionals (i.e. higher order tensors) out of lower order fields (e.g. 1-forms and vector fields). However, the higher tensors thus created lack the interesting features provided by the other type of product, the wedge product, namely they are not antisymmetric and hence are not form fields. Examples ======== >>> from sympy.diffgeom.rn import R2_r >>> from sympy.diffgeom import TensorProduct >>> fx, fy = R2_r.base_scalars() >>> e_x, e_y = R2_r.base_vectors() >>> dx, dy = R2_r.base_oneforms() >>> TensorProduct(dx, dy)(e_x, e_y) 1 >>> TensorProduct(dx, dy)(e_y, e_x) 0 >>> TensorProduct(dx, fx*dy)(fx*e_x, e_y) x**2 >>> TensorProduct(e_x, e_y)(fx**2, fy**2) 4*x*y >>> TensorProduct(e_y, dx)(fy) dx You can nest tensor products. >>> tp1 = TensorProduct(dx, dy) >>> TensorProduct(tp1, dx)(e_x, e_y, e_x) 1 You can make partial contraction for instance when 'raising an index'. Putting ``None`` in the second argument of ``rcall`` means that the respective position in the tensor product is left as it is. >>> TP = TensorProduct >>> metric = TP(dx, dx) + 3*TP(dy, dy) >>> metric.rcall(e_y, None) 3*dy Or automatically pad the args with ``None`` without specifying them. >>> metric.rcall(e_y) 3*dy c "t|Dcgc]}t|t|zdk(s|!c}}|Dcgc]}t|t|zs|}}|r)t|dk(r||dzS|t ||g|zS|Scc}wcc}w)Nrr:)rr3r4rr%r&)r)r4mscalar multifieldsr.s r/r&zTensorProduct.__new__Zs$[Q/!*r&r&r@rAs@r/rjrj$s4j+r0rjceZdZdZdZy) WedgeProductaWedge product of forms. Explanation =========== In the context of integration only completely antisymmetric forms make sense. The wedge product permits the creation of such forms. Examples ======== >>> from sympy.diffgeom.rn import R2_r >>> from sympy.diffgeom import WedgeProduct >>> fx, fy = R2_r.base_scalars() >>> e_x, e_y = R2_r.base_vectors() >>> dx, dy = R2_r.base_oneforms() >>> WedgeProduct(dx, dy)(e_x, e_y) 1 >>> WedgeProduct(dx, dy)(e_y, e_x) -1 >>> WedgeProduct(dx, fx*dy)(fx*e_x, e_y) x**2 >>> WedgeProduct(e_x, e_y)(fy, None) -e_x You can nest wedge products. >>> wp1 = WedgeProduct(dx, dy) >>> WedgeProduct(wp1, dx)(e_x, e_y, e_x) 0 c 6d|jD}dtd|Dz }t|}dttt |D}t |j}|t t||Dcgc]}||d|dzc}zScc}w)z{Apply on a list of vector_fields. The expression is rewritten internally in terms of tensor products and evaluated.c3JK|]}t|t|zywrK)r3r4)r|rs r/r}z(WedgeProduct.__call__..s Q!/!$':1'==Qs!#r:c32K|]}t|ywrKr)r|os r/r}z(WedgeProduct.__call__..s3qil3c3NK|]}t|jywrK)rrb)r|ps r/r}z(WedgeProduct.__call__..s.F ! y{Fs#%r)r4rrrZrrjrr)r6r@rtmulperms perms_par tensor_prodrs r/r&zWedgeProduct.__call__sRtyyQ3F344V$F$0s6{1C$DF #TYY/ 3#eY:OPQad+AaD0PQQQPs;B N)r;r<r=r>r&rr0r/rxrx{s!H Rr0rxcHeZdZdZfdZedZedZdZxZ S) LieDerivativea;Lie derivative with respect to a vector field. Explanation =========== The transport operator that defines the Lie derivative is the pushforward of the field to be derived along the integral curve of the field with respect to which one derives. Examples ======== >>> from sympy.diffgeom.rn import R2_r, R2_p >>> from sympy.diffgeom import (LieDerivative, TensorProduct) >>> fx, fy = R2_r.base_scalars() >>> e_x, e_y = R2_r.base_vectors() >>> e_rho, e_theta = R2_p.base_vectors() >>> dx, dy = R2_r.base_oneforms() >>> LieDerivative(e_x, fy) 0 >>> LieDerivative(e_x, fx) 1 >>> LieDerivative(e_x, e_x) 0 The Lie derivative of a tensor field by another tensor field is equal to their commutator: >>> LieDerivative(e_x, e_rho) Commutator(e_x, e_rho) >>> LieDerivative(e_x + e_y, fx) 1 >>> tp = TensorProduct(dx, dy) >>> LieDerivative(e_x, tp) LieDerivative(e_x, TensorProduct(dx, dy)) >>> LieDerivative(e_x, tp) LieDerivative(e_x, TensorProduct(dx, dy)) ct|}t|dk7s t|r td|dkDr!t||||}||_||_|S|jtr t||S|j|S)Nr:zmLie derivatives are defined only with respect to vector fields. The supplied argument was not a vector field.r) r3r4rr%r&_v_field_exprr5rrCre)r)v_fieldrc expr_form_ordr-r.s r/r&zLieDerivative.__new__s'- w '1 ,0H-. . 1 '/#w5C"CLCIJ ::o &gt, ,==& &r0c |jdSr2r3r5s r/rzLieDerivative.v_fieldr7r0c |jdSr9r3r5s r/rczLieDerivative.exprr7r0c |j}|j}|||}ttt |Dcgc]'}t |d|t |||fz||dzdz)c}}||z Scc}wr9)rrcrrZrrrC)r6r4rrrc lead_termrlrests r/r&zLieDerivative.__call__s LLyydDkN #CI.0$r(jDG&<%>>a!efMN0140s,A4) r;r<r=r>r&r?rrcr&r@rAs@r/rrs;)T'" r0rcXeZdZdZfdZedZedZedZdZ xZ S)BaseCovarDerivativeOpasCovariant derivative operator with respect to a base vector. Examples ======== >>> from sympy.diffgeom.rn import R2_r >>> from sympy.diffgeom import BaseCovarDerivativeOp >>> from sympy.diffgeom import metric_to_Christoffel_2nd, TensorProduct >>> TP = TensorProduct >>> fx, fy = R2_r.base_scalars() >>> e_x, e_y = R2_r.base_vectors() >>> dx, dy = R2_r.base_oneforms() >>> ch = metric_to_Christoffel_2nd(TP(dx, dx) + TP(dy, dy)) >>> ch [[[0, 0], [0, 0]], [[0, 0], [0, 0]]] >>> cvd = BaseCovarDerivativeOp(R2_r, 0, ch) >>> cvd(fx) 1 >>> cvd(fx*e_x) e_x ct|}t|}t| ||||}||_||_||_|SrK)rr r%r&r r _christoffel)r)rr christoffelr-r.s r/r&zBaseCovarDerivativeOp.__new__sE-k: goc9e[A" & r0c |jdSr2r3r5s r/rzBaseCovarDerivativeOp.coord_sysr7r0c |jdSr9r3r5s r/rzBaseCovarDerivativeOp.index r7r0c |jdSrr3r5s r/rz!BaseCovarDerivativeOp.christoffel$r7r0c @t|dk7r tt||j}|jj |j }|jj |j }t|jt}t|Dcgc]\}}td|z|}}}|jtt||}||}|jtt||}g} |D]} tt| jj D cgc]D} |j"| |j | j f| jj | zFc} } | j%| |D cgc] } ||  } } |jtt| | }|jtt||}|j'Scc}}wcc} wcc} w)zApply on a scalar field. The action of a vector field on a scalar field is a directional differentiation. If the argument is not a scalar field the behaviour is undefined. rr2)r3rvectors_in_basisr rrrrr5rrr rrrrZr+rrFr%)r6field wrt_vector wrt_scalarvectorsrlr8r9r:derivsrrrqdto_subsrs r/r&zBaseCovarDerivativeOp.__call__(s 5 !Q &%' ' 8__00= __33DKK@ u{{?34 "'*,:)8GaK(4,,::d3w#89:h'==c'7&;!<= A$Q\\%5%568((J,=,=qxx)GH 003489A MM!    +22Q:a=22tC$89:T#gw"789{{}-,83s%HA H 'H) r;r<r=r>r&r?rrrr&r@rAs@r/rrsN0)r0rcHeZdZdZfdZedZedZdZxZ S)CovarDerivativeOpaNCovariant derivative operator. Examples ======== >>> from sympy.diffgeom.rn import R2_r >>> from sympy.diffgeom import CovarDerivativeOp >>> from sympy.diffgeom import metric_to_Christoffel_2nd, TensorProduct >>> TP = TensorProduct >>> fx, fy = R2_r.base_scalars() >>> e_x, e_y = R2_r.base_vectors() >>> dx, dy = R2_r.base_oneforms() >>> ch = metric_to_Christoffel_2nd(TP(dx, dx) + TP(dy, dy)) >>> ch [[[0, 0], [0, 0]], [[0, 0], [0, 0]]] >>> cvd = CovarDerivativeOp(fx*e_x, ch) >>> cvd(fx) x >>> cvd(fx*e_x) x*e_x c4t|jtDchc]}|jc}dkDr t t |dk7s t |r tdt|}t|)|||}||_ ||_ |Scc}w)Nr:zsCovariant derivatives are defined only with respect to vector fields. The supplied argument was not a vector field.) rr5rr rr4r3rr r%r&_wrtr)r)wrtrrrr-r.s r/r&zCovarDerivativeOp.__new__ms cii&@A A BQ F%' ' s #q (OC,@78 8.k: goc3 4& BsBc |jdSr2r3r5s r/rzCovarDerivativeOp.wrt{r7r0c |jdSr9r3r5s r/rzCovarDerivativeOp.christoffelr7r0cFt|jjt}|Dcgc]-}t |j |j |j/}}|jjtt||j|Scc}wrK) rrr5rrr rrrrre)r6rrrrbase_opss r/r&zCovarDerivativeOp.__call__s|tyy78$&*!,,$BSBST&&yy~~d3w#9:;AA%HH&s2B) r;r<r=r>r&r?rrr&r@rAs@r/rrTs;0 Ir0rNc| tdk7s tr tdfd fd}|r|n j}|j }|Dcgc] }|| } }|rt | D cgc] } t | c} St | D cgc] } t| c} Scc}wcc} wcc} w)a Return the series expansion for an integral curve of the field. Explanation =========== Integral curve is a function `\gamma` taking a parameter in `R` to a point in the manifold. It verifies the equation: `V(f)\big(\gamma(t)\big) = \frac{d}{dt}f\big(\gamma(t)\big)` where the given ``vector_field`` is denoted as `V`. This holds for any value `t` for the parameter and any scalar field `f`. This equation can also be decomposed of a basis of coordinate functions `V(f_i)\big(\gamma(t)\big) = \frac{d}{dt}f_i\big(\gamma(t)\big) \quad \forall i` This function returns a series expansion of `\gamma(t)` in terms of the coordinate system ``coord_sys``. The equations and expansions are necessarily done in coordinate-system-dependent way as there is no other way to represent movement between points on the manifold (i.e. there is no such thing as a difference of points for a general manifold). Parameters ========== vector_field the vector field for which an integral curve will be given param the argument of the function `\gamma` from R to the curve start_point the point which corresponds to `\gamma(0)` n the order to which to expand coord_sys the coordinate system in which to expand coeffs (default False) - if True return a list of elements of the expansion Examples ======== Use the predefined R2 manifold: >>> from sympy.abc import t, x, y >>> from sympy.diffgeom.rn import R2_p, R2_r >>> from sympy.diffgeom import intcurve_series Specify a starting point and a vector field: >>> start_point = R2_r.point([x, y]) >>> vector_field = R2_r.e_x Calculate the series: >>> intcurve_series(vector_field, t, start_point, n=3) Matrix([ [t + x], [ y]]) Or get the elements of the expansion in a list: >>> series = intcurve_series(vector_field, t, start_point, n=3, coeffs=True) >>> series[0] Matrix([ [x], [y]]) >>> series[1] Matrix([ [t], [0]]) >>> series[2] Matrix([ [0], [0]]) The series in the polar coordinate system: >>> series = intcurve_series(vector_field, t, start_point, ... n=3, coord_sys=R2_p, coeffs=True) >>> series[0] Matrix([ [sqrt(x**2 + y**2)], [ atan2(y, x)]]) >>> series[1] Matrix([ [t*x/sqrt(x**2 + y**2)], [ -t*y/(x**2 + y**2)]]) >>> series[2] Matrix([ [t**2*(-x**2/(x**2 + y**2)**(3/2) + 1/sqrt(x**2 + y**2))/2], [ t**2*x*y/(x**2 + y**2)**2]]) See Also ======== intcurve_diffequ r:*The supplied field was not a vector field.c(tdg|z|S)z=Return ``vector_field`` called `i` times on ``scalar_field``.c$|j|SrK)re)rorrs r/rz6intcurve_series..iter_vfield..s1771:r0r)r6rl vector_fields r/ iter_vfieldz$intcurve_series..iter_vfields- /?/A<PPr0ctDcgc],}|z||jzt|z .c}Scc}w)z-Return the series for one of the coordinates.)rZrer)rrlrrmparam start_points r/taylor_terms_per_coordz/intcurve_series..taylor_terms_per_coordsNq#q^Q7==kJJ9UV<W# ##s1A)r4r3rr rrrrq) rrrrmrcoeffsrrr; taylor_termsrrhrs ```` @r/intcurve_seriesrsJ<(A-1NEFFQ#' K,B,BI//1O7FG!*1-GLG #& #56aq 66|4!s1v455 H64sB/8B4B9c zt|dk7s t|r td|r|n |j}t |jj Dcgc]}t d|z|}}t||}|j}|Dcgc]G}tt|j|||j|j|z I} }|Dcgc]>}t|j|j|d|j|z @} }| | fScc}wcc}wcc}w)a5Return the differential equation for an integral curve of the field. Explanation =========== Integral curve is a function `\gamma` taking a parameter in `R` to a point in the manifold. It verifies the equation: `V(f)\big(\gamma(t)\big) = \frac{d}{dt}f\big(\gamma(t)\big)` where the given ``vector_field`` is denoted as `V`. This holds for any value `t` for the parameter and any scalar field `f`. This function returns the differential equation of `\gamma(t)` in terms of the coordinate system ``coord_sys``. The equations and expansions are necessarily done in coordinate-system-dependent way as there is no other way to represent movement between points on the manifold (i.e. there is no such thing as a difference of points for a general manifold). Parameters ========== vector_field the vector field for which an integral curve will be given param the argument of the function `\gamma` from R to the curve start_point the point which corresponds to `\gamma(0)` coord_sys the coordinate system in which to give the equations Returns ======= a tuple of (equations, initial conditions) Examples ======== Use the predefined R2 manifold: >>> from sympy.abc import t >>> from sympy.diffgeom.rn import R2, R2_p, R2_r >>> from sympy.diffgeom import intcurve_diffequ Specify a starting point and a vector field: >>> start_point = R2_r.point([0, 1]) >>> vector_field = -R2.y*R2.e_x + R2.x*R2.e_y Get the equation: >>> equations, init_cond = intcurve_diffequ(vector_field, t, start_point) >>> equations [f_1(t) + Derivative(f_0(t), t), -f_0(t) + Derivative(f_1(t), t)] >>> init_cond [f_0(0), f_1(0) - 1] The series in the polar coordinate system: >>> equations, init_cond = intcurve_diffequ(vector_field, t, start_point, R2_p) >>> equations [Derivative(f_0(t), t), Derivative(f_1(t), t) - 1] >>> init_cond [f_0(0) - 1, f_1(0) - pi/2] See Also ======== intcurve_series r:rzf_%dr) r4r3rr rZr+r rrr$r rer) rrrrrlgammas arbitrary_prcf equations init_conds r/intcurve_diffequrs=X<(A-1NEFF& K,B,BI38""4$%a"hvz"5)%F% 6*K//1O*,$rxx 4e<|?Q?QRT?U?[?[\g?hhi,I,+,"((;/44UA>+AVVW,I, i %,,sD.A D3%AD8ct|Dcgc]}|jc}}tt||}t|Dcgc]}t |j |c}}||fScc}wcc}wrK)rrrrrr)r4rrod_argsrepsrcd_exprss r/rrcsd 40aQZZ\0 1F D&! "DEBDhtn))$/BCG 7?1Bs A2!A7ct|trI|jDcgc] }t|}}t t |dk7r t d|dSt|trY|jDcgc] }t|}}|Dcgc] }|dk7s | }}t |dkDr t d|sdS|dSt|tr6t|jst|jr t dyt|tryt|trtd|jDS|r|jt ryycc}wcc}wcc}w)a`Return the contravariant order of an expression. Examples ======== >>> from sympy.diffgeom import contravariant_order >>> from sympy.diffgeom.rn import R2 >>> from sympy.abc import a >>> contravariant_order(a) 0 >>> contravariant_order(a*R2.x + 2) 0 >>> contravariant_order(a*R2.x*R2.e_y + R2.e_x) 1 r:zFMisformed expression containing contravariant fields of varying order.rz?Misformed expression containing multiplication between vectors.z4Misformed expression containing a power of a vector.c32K|]}t|ywrK)r4rbs r/r}z&contravariant_order..s=a&q)=r}r)r$rr4r4rr(rrr r3baseexprrjrqr5rrc_strictrrtr|not_zeros r/r4r4ms>($26))>> from sympy.diffgeom import covariant_order >>> from sympy.diffgeom.rn import R2 >>> from sympy.abc import a >>> covariant_order(a) 0 >>> covariant_order(a*R2.x + 2) 0 >>> covariant_order(a*R2.x*R2.dy + R2.dx) 1 r:z=Misformed expression containing form fields of varying order.rz=Misformed expression containing multiplication between forms.z2Misformed expression containing a power of a form.c32K|]}t|ywrK)r3rbs r/r}z"covariant_order..s9!?1%9r}r)r$rr4r3rr(rrr rrrrjrqr5rrs r/r3r3sM($.2ii8/!$88 s6{ q \] ]ay D# .2ii8/!$88%0!aA00 x=1 \] ] q1hqk1 D#  499 %)BDF F D, ' *Q.. D- (9tyy999  ?3-9 90sE38E8 E=E=cxt|jt}g}|D]r}|j}|j ||j }|j t|jz|j}|j|t|jtt||S)aTransform all base vectors in base vectors of a specified coord basis. While the new base vectors are in the new coordinate system basis, any coefficients are kept in the old system. Examples ======== >>> from sympy.diffgeom import vectors_in_basis >>> from sympy.diffgeom.rn import R2_r, R2_p >>> vectors_in_basis(R2_r.e_x, R2_p) -y*e_theta/(x**2 + y**2) + x*e_rho/sqrt(x**2 + y**2) >>> vectors_in_basis(R2_p.e_r, R2_r) sin(theta)*e_y + cos(theta)*e_x ) rr5rr rrTrrrrFrr)rcrr new_vectorsrrcsr>news r/rrs"4::o./GK   \\kk&""4"4"67uuVF//122AHH=3  99T#g{34 55r0c |t|dk7s t|r tdt|}t |dk7r td|j }|j }|j}|Dcgc]"}|Dcgc]}|j||c}$}}}t|Scc}wcc}}w)aReturn the matrix representing the twoform. For the twoform `w` return the matrix `M` such that `M[i,j]=w(e_i, e_j)`, where `e_i` is the i-th base vector field for the coordinate system in which the expression of `w` is given. Examples ======== >>> from sympy.diffgeom.rn import R2 >>> from sympy.diffgeom import twoform_to_matrix, TensorProduct >>> TP = TensorProduct >>> twoform_to_matrix(TP(R2.dx, R2.dx) + TP(R2.dy, R2.dy)) Matrix([ [1, 0], [0, 1]]) >>> twoform_to_matrix(R2.x*TP(R2.dx, R2.dx) + TP(R2.dy, R2.dy)) Matrix([ [x, 0], [0, 1]]) >>> twoform_to_matrix(TP(R2.dx, R2.dx) + TP(R2.dy, R2.dy) - TP(R2.dx, R2.dy)/2) Matrix([ [ 1, 0], [-1/2, 1]]) r~z'The input expression is not a two-form.r:zThe input expression concerns more than one coordinate systems, hence there is no unambiguous way to choose a coordinate system for the matrix.) r3r4rrArpoprrIrer)rcrrrNrMmatrix_contents r/twoform_to_matrixrs8t!%8%>BCCT"I 9~MN N I$$&G ;;=D ')5< B8B3 B83B8ct|}|js tdt|j }|j Dcgc]}|j |}}tt|j}|Dcgc]C}|Dcgc]3}|Dcgc]%}||||f||||fz||||fz dz 'c}5c}}E} }}}t| Scc}wcc}wcc}}wcc}}}w)aXReturn the nested list of Christoffel symbols for the given metric. This returns the Christoffel symbol of first kind that represents the Levi-Civita connection for the given metric. Examples ======== >>> from sympy.diffgeom.rn import R2 >>> from sympy.diffgeom import metric_to_Christoffel_1st, TensorProduct >>> TP = TensorProduct >>> metric_to_Christoffel_1st(TP(R2.dx, R2.dx) + TP(R2.dy, R2.dy)) [[[0, 0], [0, 0]], [[0, 0], [0, 0]]] >>> metric_to_Christoffel_1st(R2.x*TP(R2.dx, R2.dx) + TP(R2.dy, R2.dy)) [[[1/2, 0], [0, 0]], [[0, 0], [0, 0]]] z6The two-form representing the metric is not symmetric.r~) r is_symmetricrrArr applyfuncrrZr+r ) rcmatrixrrderiv_matricesrurlrgrqrs r/metric_to_Christoffel_1strs%$t $F     DF FT"&&(I3<3I3I3KLaf&&q)LNL5'(G$%%%&&'%Q'1-q0A!Q$0GG.YZJ[\]_`\`Jaacdd'&%K% #; // M'&%s0C' C7 C1#*C, C1C7,C11C7ct|}t|j}tt |j }t |}t}|D]&}|j|jt(t|}|j}|jtt||jjtt||}|D cgc]H}|D cgc]6} |D cgc]&} t|D cgc]} ||| f|| | | fzc} (c} } 8c} } } J} } } }} t!| Scc} wcc} } wcc} } } wcc} } } }w)a]Return the nested list of Christoffel symbols for the given metric. This returns the Christoffel symbol of second kind that represents the Levi-Civita connection for the given metric. Examples ======== >>> from sympy.diffgeom.rn import R2 >>> from sympy.diffgeom import metric_to_Christoffel_2nd, TensorProduct >>> TP = TensorProduct >>> metric_to_Christoffel_2nd(TP(R2.dx, R2.dx) + TP(R2.dy, R2.dy)) [[[0, 0], [0, 0]], [[0, 0], [0, 0]]] >>> metric_to_Christoffel_2nd(R2.x*TP(R2.dx, R2.dx) + TP(R2.dy, R2.dy)) [[[1/(2*x), 0], [0, 0]], [[0, 0], [0, 0]]] )rrArrrZr+rr(updater5rrjrrinvrr ) rcch_1strrurs_fieldsrdumsrlrgrqlrs r/metric_to_Christoffel_2ndr5sS$'t ,FT"&&(I5'(Gt $FuH 2012H~H   D [[c(D12 3 7 7 9 > >tChDW?X YF $%%%&&&'IA6!Q$<q!Qw7IJ'&%K% #; // J'&%s<5 E$ E EE&/E5E;E$ EEE$ c!t|}t|j}tt |j }|Dcgc]N}|Dcgc]<}|Dcgc],}|j Dcgc]}|||||fc}.c}}>c}}}P}}}}}|D cgc]O} |D cgc]=} |D cgc]-} |D cgc]} || | | | || | | | z !c} /c} } ?c} } } Q} } } } } |D cgc]o} |D cgc][} |D cgc]I} |D cgc]9} t|Dcgc]%}|| || f||| | fz|| || f||| | fzz 'c};c}} Kc}} } ]c}} } } q}} } } } }|D cgc]O} |D cgc]=} |D cgc]-} |D cgc]} | | | | | || | | | z!c} /c} } ?c} } } Q}} } } } t|Scc}wcc}}wcc}}}wcc}}}}wcc} wcc} } wcc} } } wcc} } } } wcc}wcc}} wcc}} } wcc}} } } wcc}} } } } wcc} wcc} } wcc} } } wcc} } } } w)a!Return the components of the Riemann tensor expressed in a given basis. Given a metric it calculates the components of the Riemann tensor in the canonical basis of the coordinate system in which the metric expression is given. Examples ======== >>> from sympy import exp >>> from sympy.diffgeom.rn import R2 >>> from sympy.diffgeom import metric_to_Riemann_components, TensorProduct >>> TP = TensorProduct >>> metric_to_Riemann_components(TP(R2.dx, R2.dx) + TP(R2.dy, R2.dy)) [[[[0, 0], [0, 0]], [[0, 0], [0, 0]]], [[[0, 0], [0, 0]], [[0, 0], [0, 0]]]] >>> non_trivial_metric = exp(2*R2.r)*TP(R2.dr, R2.dr) + R2.r**2*TP(R2.dtheta, R2.dtheta) >>> non_trivial_metric exp(2*rho)*TensorProduct(drho, drho) + rho**2*TensorProduct(dtheta, dtheta) >>> riemann = metric_to_Riemann_components(non_trivial_metric) >>> riemann[0, :, :, :] [[[0, 0], [0, 0]], [[0, exp(-2*rho)*rho], [-exp(-2*rho)*rho, 0]]] >>> riemann[1, :, :, :] [[[0, -1/rho], [1/rho, 0]], [[0, 0], [0, 0]]] ) rrArrrZr+rrr )rcch_2ndrrurlrgrqrderiv_chrhosigmunu riemann_ar riemann_briemanns r/metric_to_Riemann_componentsr\s8't ,FT"&&(I5'(G ! """###$&2246VAq!G_%6$#"H"!( ))%&&%&&'SM#&r*2.#s1CB1G1KK'&&)I)$ %%%&&%&&&'qxylm&a,VAsBJ-??&aQSBTU[\]_bdf\fUgBggyz'&&%I%" ###$$ '($%C.%b)"- #s0CB0G0KK%($#G# #7 ++)6$#" '&&) z'&&% %($#s H  G:G46G/" G4G:H ) H 4 H> H$H "+H0H6H H=  H5! H."+H(*9*H#4#H(*)H."/H56H= I  I I )$I" I II /G44G::H HHH #H(*(H.".H55H= I  II c<t|}t|j}tt |j }|Dcgc]/}|Dcgc]}t |Dcgc] }|||||f c}!c}}1}}}}t|Scc}wcc}}wcc}}}w)a]Return the components of the Ricci tensor expressed in a given basis. Given a metric it calculates the components of the Ricci tensor in the canonical basis of the coordinate system in which the metric expression is given. Examples ======== >>> from sympy import exp >>> from sympy.diffgeom.rn import R2 >>> from sympy.diffgeom import metric_to_Ricci_components, TensorProduct >>> TP = TensorProduct >>> metric_to_Ricci_components(TP(R2.dx, R2.dx) + TP(R2.dy, R2.dy)) [[0, 0], [0, 0]] >>> non_trivial_metric = exp(2*R2.r)*TP(R2.dr, R2.dr) + R2.r**2*TP(R2.dtheta, R2.dtheta) >>> non_trivial_metric exp(2*rho)*TensorProduct(drho, drho) + rho**2*TensorProduct(dtheta, dtheta) >>> metric_to_Ricci_components(non_trivial_metric) [[1/rho, 0], [0, exp(-2*rho)*rho]] )rrArrrZr+rr )rcrrrurlrgrqriccis r/metric_to_Ricci_componentsrs4+40GT"&&(I5'(G   9AGAq!QJ'9:  E  #5 )):  s* BB!B 1B7B BBcBeZdZfdZdZfdZfdZfdZxZS)_deprecated_containerc2t||||_yrK)r%__init__message)r6rdatar.s r/rz_deprecated_container.__init__s  r0c6t|jdddy)NrTrU)rWrX stacklevel)rrr5s r/warnz_deprecated_container.warns! LL%*'D  r0c@|jt| SrK)rr%__iter__)r6r.s r/rz_deprecated_container.__iter__s w!!r0cB|jt| |SrK)rr% __getitem__r6rur.s r/rz!_deprecated_container.__getitem__s w"3''r0cB|jt| |SrK)rr% __contains__rs r/rz"_deprecated_container.__contains__s w#C((r0) r;r<r=rrrrrr@rAs@r/rrs! "())r0rc eZdZy)r'Nr;r<r=rr0r/r'r'r0r'c eZdZy)rdNrrr0r/rdrdrr0rd)r$)NFrK)F)L __future__rtypingr functoolsr itertoolsrsympy.combinatoricsr sympy.corer r r r r rrrrrrsympy.core.cachersympy.core.symbolrrrsympy.core.sympifyrsympy.functionsrsympy.matricesrr sympy.solversrsympy.utilities.exceptionsrrrsympy.tensor.arrayr r"rCrOr{rrrrArCrrjrxrrrrrrr4r3rrrrrrrrr'rrdsympy.simplify.simplifyr$rr0r/rs""+%+!'%99979u9xC!EC!Lz?%z?zK:vK:\P)EP)fb#db#Jydyx* KOKO\k4k\T+DT+n.R=.RbJ DJ ZXDXv3I3Irv6rW z+\+b6<("V0@$0N3,l *L)): ,d  ,d -r0