123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644 |
- from functools import reduce
- from sympy.core.backend import (sympify, diff, sin, cos, Matrix, symbols,
- Function, S, Symbol)
- from sympy.integrals.integrals import integrate
- from sympy.simplify.trigsimp import trigsimp
- from .vector import Vector, _check_vector
- from .frame import CoordinateSym, _check_frame
- from .dyadic import Dyadic
- from .printing import vprint, vsprint, vpprint, vlatex, init_vprinting
- from sympy.utilities.iterables import iterable
- from sympy.utilities.misc import translate
- __all__ = ['cross', 'dot', 'express', 'time_derivative', 'outer',
- 'kinematic_equations', 'get_motion_params', 'partial_velocity',
- 'dynamicsymbols', 'vprint', 'vsprint', 'vpprint', 'vlatex',
- 'init_vprinting']
- def cross(vec1, vec2):
- """Cross product convenience wrapper for Vector.cross(): \n"""
- if not isinstance(vec1, (Vector, Dyadic)):
- raise TypeError('Cross product is between two vectors')
- return vec1 ^ vec2
- cross.__doc__ += Vector.cross.__doc__ # type: ignore
- def dot(vec1, vec2):
- """Dot product convenience wrapper for Vector.dot(): \n"""
- if not isinstance(vec1, (Vector, Dyadic)):
- raise TypeError('Dot product is between two vectors')
- return vec1 & vec2
- dot.__doc__ += Vector.dot.__doc__ # type: ignore
- def express(expr, frame, frame2=None, variables=False):
- """
- Global function for 'express' functionality.
- Re-expresses a Vector, scalar(sympyfiable) or Dyadic in given frame.
- Refer to the local methods of Vector and Dyadic for details.
- If 'variables' is True, then the coordinate variables (CoordinateSym
- instances) of other frames present in the vector/scalar field or
- dyadic expression are also substituted in terms of the base scalars of
- this frame.
- Parameters
- ==========
- expr : Vector/Dyadic/scalar(sympyfiable)
- The expression to re-express in ReferenceFrame 'frame'
- frame: ReferenceFrame
- The reference frame to express expr in
- frame2 : ReferenceFrame
- The other frame required for re-expression(only for Dyadic expr)
- variables : boolean
- Specifies whether to substitute the coordinate variables present
- in expr, in terms of those of frame
- Examples
- ========
- >>> from sympy.physics.vector import ReferenceFrame, outer, dynamicsymbols
- >>> from sympy.physics.vector import init_vprinting
- >>> init_vprinting(pretty_print=False)
- >>> N = ReferenceFrame('N')
- >>> q = dynamicsymbols('q')
- >>> B = N.orientnew('B', 'Axis', [q, N.z])
- >>> d = outer(N.x, N.x)
- >>> from sympy.physics.vector import express
- >>> express(d, B, N)
- cos(q)*(B.x|N.x) - sin(q)*(B.y|N.x)
- >>> express(B.x, N)
- cos(q)*N.x + sin(q)*N.y
- >>> express(N[0], B, variables=True)
- B_x*cos(q) - B_y*sin(q)
- """
- _check_frame(frame)
- if expr == 0:
- return expr
- if isinstance(expr, Vector):
- # Given expr is a Vector
- if variables:
- # If variables attribute is True, substitute the coordinate
- # variables in the Vector
- frame_list = [x[-1] for x in expr.args]
- subs_dict = {}
- for f in frame_list:
- subs_dict.update(f.variable_map(frame))
- expr = expr.subs(subs_dict)
- # Re-express in this frame
- outvec = Vector([])
- for i, v in enumerate(expr.args):
- if v[1] != frame:
- temp = frame.dcm(v[1]) * v[0]
- if Vector.simp:
- temp = temp.applyfunc(lambda x:
- trigsimp(x, method='fu'))
- outvec += Vector([(temp, frame)])
- else:
- outvec += Vector([v])
- return outvec
- if isinstance(expr, Dyadic):
- if frame2 is None:
- frame2 = frame
- _check_frame(frame2)
- ol = Dyadic(0)
- for i, v in enumerate(expr.args):
- ol += express(v[0], frame, variables=variables) * \
- (express(v[1], frame, variables=variables) |
- express(v[2], frame2, variables=variables))
- return ol
- else:
- if variables:
- # Given expr is a scalar field
- frame_set = set()
- expr = sympify(expr)
- # Substitute all the coordinate variables
- for x in expr.free_symbols:
- if isinstance(x, CoordinateSym) and x.frame != frame:
- frame_set.add(x.frame)
- subs_dict = {}
- for f in frame_set:
- subs_dict.update(f.variable_map(frame))
- return expr.subs(subs_dict)
- return expr
- def time_derivative(expr, frame, order=1):
- """
- Calculate the time derivative of a vector/scalar field function
- or dyadic expression in given frame.
- References
- ==========
- https://en.wikipedia.org/wiki/Rotating_reference_frame#Time_derivatives_in_the_two_frames
- Parameters
- ==========
- expr : Vector/Dyadic/sympifyable
- The expression whose time derivative is to be calculated
- frame : ReferenceFrame
- The reference frame to calculate the time derivative in
- order : integer
- The order of the derivative to be calculated
- Examples
- ========
- >>> from sympy.physics.vector import ReferenceFrame, dynamicsymbols
- >>> from sympy.physics.vector import init_vprinting
- >>> init_vprinting(pretty_print=False)
- >>> from sympy import Symbol
- >>> q1 = Symbol('q1')
- >>> u1 = dynamicsymbols('u1')
- >>> N = ReferenceFrame('N')
- >>> A = N.orientnew('A', 'Axis', [q1, N.x])
- >>> v = u1 * N.x
- >>> A.set_ang_vel(N, 10*A.x)
- >>> from sympy.physics.vector import time_derivative
- >>> time_derivative(v, N)
- u1'*N.x
- >>> time_derivative(u1*A[0], N)
- N_x*u1'
- >>> B = N.orientnew('B', 'Axis', [u1, N.z])
- >>> from sympy.physics.vector import outer
- >>> d = outer(N.x, N.x)
- >>> time_derivative(d, B)
- - u1'*(N.y|N.x) - u1'*(N.x|N.y)
- """
- t = dynamicsymbols._t
- _check_frame(frame)
- if order == 0:
- return expr
- if order % 1 != 0 or order < 0:
- raise ValueError("Unsupported value of order entered")
- if isinstance(expr, Vector):
- outlist = []
- for i, v in enumerate(expr.args):
- if v[1] == frame:
- outlist += [(express(v[0], frame, variables=True).diff(t),
- frame)]
- else:
- outlist += (time_derivative(Vector([v]), v[1]) +
- (v[1].ang_vel_in(frame) ^ Vector([v]))).args
- outvec = Vector(outlist)
- return time_derivative(outvec, frame, order - 1)
- if isinstance(expr, Dyadic):
- ol = Dyadic(0)
- for i, v in enumerate(expr.args):
- ol += (v[0].diff(t) * (v[1] | v[2]))
- ol += (v[0] * (time_derivative(v[1], frame) | v[2]))
- ol += (v[0] * (v[1] | time_derivative(v[2], frame)))
- return time_derivative(ol, frame, order - 1)
- else:
- return diff(express(expr, frame, variables=True), t, order)
- def outer(vec1, vec2):
- """Outer product convenience wrapper for Vector.outer():\n"""
- if not isinstance(vec1, Vector):
- raise TypeError('Outer product is between two Vectors')
- return vec1 | vec2
- outer.__doc__ += Vector.outer.__doc__ # type: ignore
- def kinematic_equations(speeds, coords, rot_type, rot_order=''):
- """Gives equations relating the qdot's to u's for a rotation type.
- Supply rotation type and order as in orient. Speeds are assumed to be
- body-fixed; if we are defining the orientation of B in A using by rot_type,
- the angular velocity of B in A is assumed to be in the form: speed[0]*B.x +
- speed[1]*B.y + speed[2]*B.z
- Parameters
- ==========
- speeds : list of length 3
- The body fixed angular velocity measure numbers.
- coords : list of length 3 or 4
- The coordinates used to define the orientation of the two frames.
- rot_type : str
- The type of rotation used to create the equations. Body, Space, or
- Quaternion only
- rot_order : str or int
- If applicable, the order of a series of rotations.
- Examples
- ========
- >>> from sympy.physics.vector import dynamicsymbols
- >>> from sympy.physics.vector import kinematic_equations, vprint
- >>> u1, u2, u3 = dynamicsymbols('u1 u2 u3')
- >>> q1, q2, q3 = dynamicsymbols('q1 q2 q3')
- >>> vprint(kinematic_equations([u1,u2,u3], [q1,q2,q3], 'body', '313'),
- ... order=None)
- [-(u1*sin(q3) + u2*cos(q3))/sin(q2) + q1', -u1*cos(q3) + u2*sin(q3) + q2', (u1*sin(q3) + u2*cos(q3))*cos(q2)/sin(q2) - u3 + q3']
- """
- # Code below is checking and sanitizing input
- approved_orders = ('123', '231', '312', '132', '213', '321', '121', '131',
- '212', '232', '313', '323', '1', '2', '3', '')
- # make sure XYZ => 123 and rot_type is in lower case
- rot_order = translate(str(rot_order), 'XYZxyz', '123123')
- rot_type = rot_type.lower()
- if not isinstance(speeds, (list, tuple)):
- raise TypeError('Need to supply speeds in a list')
- if len(speeds) != 3:
- raise TypeError('Need to supply 3 body-fixed speeds')
- if not isinstance(coords, (list, tuple)):
- raise TypeError('Need to supply coordinates in a list')
- if rot_type in ['body', 'space']:
- if rot_order not in approved_orders:
- raise ValueError('Not an acceptable rotation order')
- if len(coords) != 3:
- raise ValueError('Need 3 coordinates for body or space')
- # Actual hard-coded kinematic differential equations
- w1, w2, w3 = speeds
- if w1 == w2 == w3 == 0:
- return [S.Zero]*3
- q1, q2, q3 = coords
- q1d, q2d, q3d = [diff(i, dynamicsymbols._t) for i in coords]
- s1, s2, s3 = [sin(q1), sin(q2), sin(q3)]
- c1, c2, c3 = [cos(q1), cos(q2), cos(q3)]
- if rot_type == 'body':
- if rot_order == '123':
- return [q1d - (w1 * c3 - w2 * s3) / c2, q2d - w1 * s3 - w2 *
- c3, q3d - (-w1 * c3 + w2 * s3) * s2 / c2 - w3]
- if rot_order == '231':
- return [q1d - (w2 * c3 - w3 * s3) / c2, q2d - w2 * s3 - w3 *
- c3, q3d - w1 - (- w2 * c3 + w3 * s3) * s2 / c2]
- if rot_order == '312':
- return [q1d - (-w1 * s3 + w3 * c3) / c2, q2d - w1 * c3 - w3 *
- s3, q3d - (w1 * s3 - w3 * c3) * s2 / c2 - w2]
- if rot_order == '132':
- return [q1d - (w1 * c3 + w3 * s3) / c2, q2d + w1 * s3 - w3 *
- c3, q3d - (w1 * c3 + w3 * s3) * s2 / c2 - w2]
- if rot_order == '213':
- return [q1d - (w1 * s3 + w2 * c3) / c2, q2d - w1 * c3 + w2 *
- s3, q3d - (w1 * s3 + w2 * c3) * s2 / c2 - w3]
- if rot_order == '321':
- return [q1d - (w2 * s3 + w3 * c3) / c2, q2d - w2 * c3 + w3 *
- s3, q3d - w1 - (w2 * s3 + w3 * c3) * s2 / c2]
- if rot_order == '121':
- return [q1d - (w2 * s3 + w3 * c3) / s2, q2d - w2 * c3 + w3 *
- s3, q3d - w1 + (w2 * s3 + w3 * c3) * c2 / s2]
- if rot_order == '131':
- return [q1d - (-w2 * c3 + w3 * s3) / s2, q2d - w2 * s3 - w3 *
- c3, q3d - w1 - (w2 * c3 - w3 * s3) * c2 / s2]
- if rot_order == '212':
- return [q1d - (w1 * s3 - w3 * c3) / s2, q2d - w1 * c3 - w3 *
- s3, q3d - (-w1 * s3 + w3 * c3) * c2 / s2 - w2]
- if rot_order == '232':
- return [q1d - (w1 * c3 + w3 * s3) / s2, q2d + w1 * s3 - w3 *
- c3, q3d + (w1 * c3 + w3 * s3) * c2 / s2 - w2]
- if rot_order == '313':
- return [q1d - (w1 * s3 + w2 * c3) / s2, q2d - w1 * c3 + w2 *
- s3, q3d + (w1 * s3 + w2 * c3) * c2 / s2 - w3]
- if rot_order == '323':
- return [q1d - (-w1 * c3 + w2 * s3) / s2, q2d - w1 * s3 - w2 *
- c3, q3d - (w1 * c3 - w2 * s3) * c2 / s2 - w3]
- if rot_type == 'space':
- if rot_order == '123':
- return [q1d - w1 - (w2 * s1 + w3 * c1) * s2 / c2, q2d - w2 *
- c1 + w3 * s1, q3d - (w2 * s1 + w3 * c1) / c2]
- if rot_order == '231':
- return [q1d - (w1 * c1 + w3 * s1) * s2 / c2 - w2, q2d + w1 *
- s1 - w3 * c1, q3d - (w1 * c1 + w3 * s1) / c2]
- if rot_order == '312':
- return [q1d - (w1 * s1 + w2 * c1) * s2 / c2 - w3, q2d - w1 *
- c1 + w2 * s1, q3d - (w1 * s1 + w2 * c1) / c2]
- if rot_order == '132':
- return [q1d - w1 - (-w2 * c1 + w3 * s1) * s2 / c2, q2d - w2 *
- s1 - w3 * c1, q3d - (w2 * c1 - w3 * s1) / c2]
- if rot_order == '213':
- return [q1d - (w1 * s1 - w3 * c1) * s2 / c2 - w2, q2d - w1 *
- c1 - w3 * s1, q3d - (-w1 * s1 + w3 * c1) / c2]
- if rot_order == '321':
- return [q1d - (-w1 * c1 + w2 * s1) * s2 / c2 - w3, q2d - w1 *
- s1 - w2 * c1, q3d - (w1 * c1 - w2 * s1) / c2]
- if rot_order == '121':
- return [q1d - w1 + (w2 * s1 + w3 * c1) * c2 / s2, q2d - w2 *
- c1 + w3 * s1, q3d - (w2 * s1 + w3 * c1) / s2]
- if rot_order == '131':
- return [q1d - w1 - (w2 * c1 - w3 * s1) * c2 / s2, q2d - w2 *
- s1 - w3 * c1, q3d - (-w2 * c1 + w3 * s1) / s2]
- if rot_order == '212':
- return [q1d - (-w1 * s1 + w3 * c1) * c2 / s2 - w2, q2d - w1 *
- c1 - w3 * s1, q3d - (w1 * s1 - w3 * c1) / s2]
- if rot_order == '232':
- return [q1d + (w1 * c1 + w3 * s1) * c2 / s2 - w2, q2d + w1 *
- s1 - w3 * c1, q3d - (w1 * c1 + w3 * s1) / s2]
- if rot_order == '313':
- return [q1d + (w1 * s1 + w2 * c1) * c2 / s2 - w3, q2d - w1 *
- c1 + w2 * s1, q3d - (w1 * s1 + w2 * c1) / s2]
- if rot_order == '323':
- return [q1d - (w1 * c1 - w2 * s1) * c2 / s2 - w3, q2d - w1 *
- s1 - w2 * c1, q3d - (-w1 * c1 + w2 * s1) / s2]
- elif rot_type == 'quaternion':
- if rot_order != '':
- raise ValueError('Cannot have rotation order for quaternion')
- if len(coords) != 4:
- raise ValueError('Need 4 coordinates for quaternion')
- # Actual hard-coded kinematic differential equations
- e0, e1, e2, e3 = coords
- w = Matrix(speeds + [0])
- E = Matrix([[e0, -e3, e2, e1],
- [e3, e0, -e1, e2],
- [-e2, e1, e0, e3],
- [-e1, -e2, -e3, e0]])
- edots = Matrix([diff(i, dynamicsymbols._t) for i in [e1, e2, e3, e0]])
- return list(edots.T - 0.5 * w.T * E.T)
- else:
- raise ValueError('Not an approved rotation type for this function')
- def get_motion_params(frame, **kwargs):
- """
- Returns the three motion parameters - (acceleration, velocity, and
- position) as vectorial functions of time in the given frame.
- If a higher order differential function is provided, the lower order
- functions are used as boundary conditions. For example, given the
- acceleration, the velocity and position parameters are taken as
- boundary conditions.
- The values of time at which the boundary conditions are specified
- are taken from timevalue1(for position boundary condition) and
- timevalue2(for velocity boundary condition).
- If any of the boundary conditions are not provided, they are taken
- to be zero by default (zero vectors, in case of vectorial inputs). If
- the boundary conditions are also functions of time, they are converted
- to constants by substituting the time values in the dynamicsymbols._t
- time Symbol.
- This function can also be used for calculating rotational motion
- parameters. Have a look at the Parameters and Examples for more clarity.
- Parameters
- ==========
- frame : ReferenceFrame
- The frame to express the motion parameters in
- acceleration : Vector
- Acceleration of the object/frame as a function of time
- velocity : Vector
- Velocity as function of time or as boundary condition
- of velocity at time = timevalue1
- position : Vector
- Velocity as function of time or as boundary condition
- of velocity at time = timevalue1
- timevalue1 : sympyfiable
- Value of time for position boundary condition
- timevalue2 : sympyfiable
- Value of time for velocity boundary condition
- Examples
- ========
- >>> from sympy.physics.vector import ReferenceFrame, get_motion_params, dynamicsymbols
- >>> from sympy.physics.vector import init_vprinting
- >>> init_vprinting(pretty_print=False)
- >>> from sympy import symbols
- >>> R = ReferenceFrame('R')
- >>> v1, v2, v3 = dynamicsymbols('v1 v2 v3')
- >>> v = v1*R.x + v2*R.y + v3*R.z
- >>> get_motion_params(R, position = v)
- (v1''*R.x + v2''*R.y + v3''*R.z, v1'*R.x + v2'*R.y + v3'*R.z, v1*R.x + v2*R.y + v3*R.z)
- >>> a, b, c = symbols('a b c')
- >>> v = a*R.x + b*R.y + c*R.z
- >>> get_motion_params(R, velocity = v)
- (0, a*R.x + b*R.y + c*R.z, a*t*R.x + b*t*R.y + c*t*R.z)
- >>> parameters = get_motion_params(R, acceleration = v)
- >>> parameters[1]
- a*t*R.x + b*t*R.y + c*t*R.z
- >>> parameters[2]
- a*t**2/2*R.x + b*t**2/2*R.y + c*t**2/2*R.z
- """
- def _process_vector_differential(vectdiff, condition, variable, ordinate,
- frame):
- """
- Helper function for get_motion methods. Finds derivative of vectdiff
- wrt variable, and its integral using the specified boundary condition
- at value of variable = ordinate.
- Returns a tuple of - (derivative, function and integral) wrt vectdiff
- """
- # Make sure boundary condition is independent of 'variable'
- if condition != 0:
- condition = express(condition, frame, variables=True)
- # Special case of vectdiff == 0
- if vectdiff == Vector(0):
- return (0, 0, condition)
- # Express vectdiff completely in condition's frame to give vectdiff1
- vectdiff1 = express(vectdiff, frame)
- # Find derivative of vectdiff
- vectdiff2 = time_derivative(vectdiff, frame)
- # Integrate and use boundary condition
- vectdiff0 = Vector(0)
- lims = (variable, ordinate, variable)
- for dim in frame:
- function1 = vectdiff1.dot(dim)
- abscissa = dim.dot(condition).subs({variable: ordinate})
- # Indefinite integral of 'function1' wrt 'variable', using
- # the given initial condition (ordinate, abscissa).
- vectdiff0 += (integrate(function1, lims) + abscissa) * dim
- # Return tuple
- return (vectdiff2, vectdiff, vectdiff0)
- _check_frame(frame)
- # Decide mode of operation based on user's input
- if 'acceleration' in kwargs:
- mode = 2
- elif 'velocity' in kwargs:
- mode = 1
- else:
- mode = 0
- # All the possible parameters in kwargs
- # Not all are required for every case
- # If not specified, set to default values(may or may not be used in
- # calculations)
- conditions = ['acceleration', 'velocity', 'position',
- 'timevalue', 'timevalue1', 'timevalue2']
- for i, x in enumerate(conditions):
- if x not in kwargs:
- if i < 3:
- kwargs[x] = Vector(0)
- else:
- kwargs[x] = S.Zero
- elif i < 3:
- _check_vector(kwargs[x])
- else:
- kwargs[x] = sympify(kwargs[x])
- if mode == 2:
- vel = _process_vector_differential(kwargs['acceleration'],
- kwargs['velocity'],
- dynamicsymbols._t,
- kwargs['timevalue2'], frame)[2]
- pos = _process_vector_differential(vel, kwargs['position'],
- dynamicsymbols._t,
- kwargs['timevalue1'], frame)[2]
- return (kwargs['acceleration'], vel, pos)
- elif mode == 1:
- return _process_vector_differential(kwargs['velocity'],
- kwargs['position'],
- dynamicsymbols._t,
- kwargs['timevalue1'], frame)
- else:
- vel = time_derivative(kwargs['position'], frame)
- acc = time_derivative(vel, frame)
- return (acc, vel, kwargs['position'])
- def partial_velocity(vel_vecs, gen_speeds, frame):
- """Returns a list of partial velocities with respect to the provided
- generalized speeds in the given reference frame for each of the supplied
- velocity vectors.
- The output is a list of lists. The outer list has a number of elements
- equal to the number of supplied velocity vectors. The inner lists are, for
- each velocity vector, the partial derivatives of that velocity vector with
- respect to the generalized speeds supplied.
- Parameters
- ==========
- vel_vecs : iterable
- An iterable of velocity vectors (angular or linear).
- gen_speeds : iterable
- An iterable of generalized speeds.
- frame : ReferenceFrame
- The reference frame that the partial derivatives are going to be taken
- in.
- Examples
- ========
- >>> from sympy.physics.vector import Point, ReferenceFrame
- >>> from sympy.physics.vector import dynamicsymbols
- >>> from sympy.physics.vector import partial_velocity
- >>> u = dynamicsymbols('u')
- >>> N = ReferenceFrame('N')
- >>> P = Point('P')
- >>> P.set_vel(N, u * N.x)
- >>> vel_vecs = [P.vel(N)]
- >>> gen_speeds = [u]
- >>> partial_velocity(vel_vecs, gen_speeds, N)
- [[N.x]]
- """
- if not iterable(vel_vecs):
- raise TypeError('Velocity vectors must be contained in an iterable.')
- if not iterable(gen_speeds):
- raise TypeError('Generalized speeds must be contained in an iterable')
- vec_partials = []
- for vec in vel_vecs:
- partials = []
- for speed in gen_speeds:
- partials.append(vec.diff(speed, frame, var_in_dcm=False))
- vec_partials.append(partials)
- return vec_partials
- def dynamicsymbols(names, level=0, **assumptions):
- """Uses symbols and Function for functions of time.
- Creates a SymPy UndefinedFunction, which is then initialized as a function
- of a variable, the default being Symbol('t').
- Parameters
- ==========
- names : str
- Names of the dynamic symbols you want to create; works the same way as
- inputs to symbols
- level : int
- Level of differentiation of the returned function; d/dt once of t,
- twice of t, etc.
- assumptions :
- - real(bool) : This is used to set the dynamicsymbol as real,
- by default is False.
- - positive(bool) : This is used to set the dynamicsymbol as positive,
- by default is False.
- - commutative(bool) : This is used to set the commutative property of
- a dynamicsymbol, by default is True.
- - integer(bool) : This is used to set the dynamicsymbol as integer,
- by default is False.
- Examples
- ========
- >>> from sympy.physics.vector import dynamicsymbols
- >>> from sympy import diff, Symbol
- >>> q1 = dynamicsymbols('q1')
- >>> q1
- q1(t)
- >>> q2 = dynamicsymbols('q2', real=True)
- >>> q2.is_real
- True
- >>> q3 = dynamicsymbols('q3', positive=True)
- >>> q3.is_positive
- True
- >>> q4, q5 = dynamicsymbols('q4,q5', commutative=False)
- >>> bool(q4*q5 != q5*q4)
- True
- >>> q6 = dynamicsymbols('q6', integer=True)
- >>> q6.is_integer
- True
- >>> diff(q1, Symbol('t'))
- Derivative(q1(t), t)
- """
- esses = symbols(names, cls=Function, **assumptions)
- t = dynamicsymbols._t
- if iterable(esses):
- esses = [reduce(diff, [t] * level, e(t)) for e in esses]
- return esses
- else:
- return reduce(diff, [t] * level, esses(t))
- dynamicsymbols._t = Symbol('t') # type: ignore
- dynamicsymbols._str = '\'' # type: ignore
|