Here is a concrete example of the behavior that I think would be very useful: (1) variables x{3}' (2) e = sin(x1 - x2) -> (3) e = SIN(x1-x2)
(4) f = x3*e*tan(x2)*sin(e) -> (5) f = x3*TAN(x2)*e*SIN(e) (6) test = dt(f) -> (7) test = TAN(x2)*e*SIN(e)*x3' + x3*e*SIN(e)*x2'/COS(x2)^2 + x3*TAN (x2)*COS(x1-x2)*SIN(e)*(x1'-x2') + x3*TAN(x2)*COS(x1-x2)*e*COS(e)*(x1'- x2') (6) variables The following variables have been declared: x1 x2 x3 x1' x2' x3' (6) This is the output of a program called Autolev. Ignore the annoying things like its capitalization sin, cos, tan, and the way the variables command works by injecting things into the workspace. The main functionality I'm trying to emulate is in its ability to assume time dependence of the variables x1 x2 and x3 upon time, and just use compact notation like x1' to represent D(x(t), t). Things like solve and coeff work just fine in Autolev for these variables: (8) coef(test, x1') Result = x3*TAN(x2)*COS(x1-x2)*(SIN(e)+e*COS(e)) (8) solve(test, x1') -> (9) x1' = -(TAN(x2)*e*SIN(e)*x3'+x3*e*SIN(e)*x2'/COS(x2)^2-x3*TAN (x2)*COS(x1-x2)*SIN(e)*x2'-x3*TAN(x2)*COS(x1-x2)*e*COS(e)*x2')/(x3*TAN (x2)*COS(x1-x2)*(SIN(e)+e*COS(e))) Again, some of the behavior here is sloppy, but hopefully this illustrates some of the behavior that would be useful. I would like to emulate the behavior that allows one to: 1) explicitly declare a Symbol to be a function of some parameters (in my case, just Symbol('t') would be adequate) 2) never have to explicitly use notation like x(t), because x is "Assumed" to be a function of time. 3) have the chain rule work, so that when a symbolic expression has things like sin(x), and you differentiate it, you get, cos(x)*x', rather than 0 (the way sympy works now unless you use Function or Symbol with explicit 'x(t)' notation). 4) have diff(x, t) return another Symbol, some linked to the parent symbol ( i.e. x' is a descendant of x, or something like this) so that it can be used in all the functions that work well with Symbol. This sort of behavior would make many things extremely easy and for the stuff I'm doing, would let one focus on the problem, not on the syntax. Thoughts? ~Luke On May 27, 11:53 am, Luke <hazelnu...@gmail.com> wrote: > Fabian, > I think the example you gave is good, but I think it would be better > if you could imply that x == x(t) upon instantiation, rather than > anytime you need to take the derivative, so that you would have > something like: > In [1]: t = Symbol('t') > In [2]: x = Symbol('x', args=[t]) > In [3]: x.diff(t) > Out[3]: > d > --(x(t)) > dt > > I think making the user type 'x(t).diff(t)' instead of 'x.diff(t)' > would be more error prone (you could easily forget to do it once and > screw everything all up). To me it seems better to just declare that > it is dependent upon some parameter when you create it, and > forevermore you don't have to be explicit about it. > > The next question is with regards to the return value of x.diff(t) in > the above case. Currently, it returns Derivative. For the stuff I am > doing, I need 'x.diff(t)' to have the functionality of Symbol, i.e., I > need to be able to take the derivative of an expression with respect > to x.diff(t), and I don't want to have to perform cumbersome > substitutions back and forth, also, being able to match terms, find > coefficients, solve, etc., all work with Symbol but not necessarily > with other things like Function or Derivative. > > What do you think about the idea of an assumption for Symbol saying > that it is implicitly dependent upon some other Symbols? If this > assumption were set to be True, and the list of other Symbols > specified, there could be some small amount of code in the diff() > method of Symbol that would notice this and return a Symbol instead of > a Derivative. This would still allow for the chain rule to be applied > correctly, so that you could get this kind of behavior: > > In [4]: diff(sin(x), t) > Out[4]: > D(x(t), t)*cos(x(t)) > > but still have the first term, the D(x(t), t), be a Symbol, so that > you could do: > In [4]: dexpr = diff(sin(x), t) > In [5]: solve(dexpr - 1, x.diff(t)) > Out[5]: {D(x(t), t): 1/cos(x(t))} > > The reason it might be nice to subclass it is so that printing could > be more tightly controlled.... things get long and unreadable if you > are always using x(t) instead of x, D(x(t), t) instead of x' (or > something similar). But maybe it could still be done without > subclassing? > > The other approach would be to make everything in Sympy work equally > well with Function, Derivative, and Symbol. I don't know if this is a > good idea or not, but it also seems like it would be a ton of work. > > What do you think? > > ~Luke > > W > > On May 27, 1:44 am, Fabian Pedregosa <fab...@fseoane.net> wrote: > > > Luke wrote: > > > I'm trying to better understand how Sympy is structured with regard to > > > Function and Symbol. > > > > In most problems I have encountered with ODE's (and PDE's, but I'll > > > limit my discussion to ODE's) of the form: > > > dx/dt = f(x, t) x \in R^n, f: R^n x R ---> R^n > > > there simply is no closed form solution for x(t). So if you somehow > > > know f(x) and can hard code it, Symbol works fine as the data type for > > > each x_i (i = 1,....n). This allows you to take partial derivatives > > > of f, linearize the system, study stability, etc... > > > > The problem I am faced with is in the analytic derivation of f(x, t), > > > as it arises from Newtonian dynamics. For simple problems, f(x, t) > > > can be done by determined by 'hand'. For more complicated systems, > > > this becomes cumbersome and intractable. > > > > Typically, the problem starts out with defining the orientations and > > > positions of all masses and rigid bodies. Next, velocities with > > > respect some inertial frame need to be formed, so time derivatives of > > > very complicated expressions are necessary. In these expressions are > > > long trig expressions involving the x_i's which generally represent a > > > position or an angle (generalized coordinates). And this is where my > > > problem lies: if the x_i's are implemented as Symbol, then diff(x, t) > > > == 0, and the expressions involving x won't have the correct > > > derivative. Obviously, I can hand code the chain rule and just take > > > partial derivatives with respect to each x_i, then multiply by another > > > Symbol that represents dx_i / dt, but this seems clumsy and cumbersome > > > to me. > > > > If, instead, each x_i is implemented as Function, implicitly dependent > > > upon time (again, remember, no closed form solution exists) like: > > > t = Symbol('t') > > > x_1 = Function('x_1')(t) > > > then we get nice things like: > > > diff(x_1, t) > > > but then other issues come up, e.g, solve can't solve for anything but > > > symbol (although there is a patch submitted that fixes this), .match() > > > can't match Function types, differentiation with respect to Functions > > > are not currently supported (so no Jacobian of f(x, t) could be done > > > without substitution), and who knows what else. Substitution schemes > > > where Functions are replaced by Symbols and then back again are > > > possible, but it seems fragile and a bit of a hack. > > > > The main point I'm driving at is that it seems that many things seem > > > to be designed to work exclusively with the Symbol type. > > > > Does anybody here have experience with this sort of situation, and how > > > it can be dealt with, or how other packages (Maple, Mathematica, > > > Maxima) might deal with it? > > > > One idea (not necessarily a good one, let me know what you think) is > > > the following. Suppose you have a problem where you need > > > differentiation with respect to a parameter (i.e. time), but for > > > everything else, the behavior of Function is not needed ( i.e., series > > > () is not needed because no closed form solution exists....). Could a > > > special type of Symbol be created that carried along with it its > > > independent variable, something like: > > >>>> t = Symbol('t') > > > t > > >>>> x = Symbol('x', implicitly_dependent_upon=t) > > > Hi Luke! > > > I proposed something like this not long ago > > >http://groups.google.com/group/sympy/browse_thread/thread/5c0d66d518a... > > > so I'm very glad we both arrived to the same conclusion. > > > Definitely Function should not be used as an unknown, and symbol should > > be used instead as you pointed out (maybe with some assumptions, maybe > > that would not be necessary for most cases) > > > > x(t) > > > and then differentiation with respect to that parameter would return > > > another Symbol: > > >>>> x.diff(t) > > > x' > > > Or some other notation instead of the x' could be used, maybe xp (p > > > for prime), and so on: > > >>>> (x.diff(t)).diff(t) > > > x'' > > > the following work well now: > > > In [1]: x = Symbol('x') > > > In [2]: t = Symbol('t') > > > In [3]: x(t).diff(t) > > Out[3]: > > d > > --(x(t)) > > dt > > > And I think this is both elegant and simple. > > > > It seems like this notation could also be useful and applicable to > > > things with spatial dependence, like stress, strain, temperature, > > > things that arise in solid and fluid mechanics. i.e.: > > > v = Symbol('v' implicitly_dependent_upon = [t, x, y, z]) > > > as might be used in the Navier-Stokes equations... > > > > I guess the real need for this is dictated by the case when you need > > > to derive, symbollically, the differential equations you want to work > > > with, be they ODE's or PDE's. That happens to be what I'm working on, > > > and maybe other people might find this functionality useful, or maybe > > > not. > > > > I guess it might just be as simple as subclassing Symbol and adding > > > the functionality I just described, but hopefully this would still > > > allow it to retain the ability to work with all the builtin Sympy > > > functions that work best with Symbol objects. > > > I don't think we just use symbol. Symbol represents an unknown and in > > the same way that we don't subclass when representing an unknown that > > lives in Z or that is not commutative, we should not subclass an unknown > > that lives in the space of functions. > > > > Thoughts? > > > > ~Luke > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sympy" group. To post to this group, send email to sympy@googlegroups.com To unsubscribe from this group, send email to sympy+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/sympy?hl=en -~----------~----~----~----~------~----~------~--~---