[sympy] Identifying repeated subexpressions in systems of equations
I'm working on some code that symbolically generates equations of motion for mechanical systems. I would like the equations to be computationally efficient in that they don't repeatedly calculate quantities that have previously been calculated -- i.e. if cos(theta)*sin(alpha)*L is a subexpression that occurs in multiple places in an equation, it would be identified and computed once and stored in an intermediate variable that then replaces the subexpression everywhere it occurs in the equation. Does anybody know a good algorithm for searching equations and building up a list of subexpressions? There could be many levels of subexpressions -- in the example above, cos(theta) and sin(theta) themselves would like be used in other subexpressions, so they could be considered subexpressions themselves. I have used a symbolic manipulator that has this feature but it is a small closed source project and I don't know how they did it. It is very valuable though -- the difference in the file size for the right hand sides of the differential equations for the system we are studying is several orders of magnitude -- this makes integration times *much* faster when this common subexpression replacement method is used. Any ideas or references on this subject? Thanks, ~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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sympy?hl=en -~--~~~~--~~--~--~---
[sympy] Re: Identifying repeated subexpressions in systems of equations
, but basically 'P_NO_RO' denotes the position vector (hence the 'P'), from the point NO, to the point RO. Autolev recognizes 'NO' as the origin of a Newtonian reference frame that I declared earlier (not shown), and 'RO' as the center of mass location of the rigid body 'R' (also declared earlier). Anything with a '' at the end of it denotes that it is a vector, and most of the vectors here are the body fixed vectors of each rigid body (they are created automatically upon declaration of a rigid body). Once the orientations of all of the bodies has been declared, you can work with whichever coordinate system is most convenient when describing the location of a center of mass or a point. Lines 163-202: This best illustrates the behavior I am trying to achieve. Upon entering the definition of 'P_FO_NF' (the position vector from the center of the front wheel to the front wheel - ground contact point), the Autolev interpreter generates 28 intermediate 'Z' variables before finally forming the final expression. All of these intermediate variables somehow involve the generalized coordinates of the problem at hand (most happen to be angles) and hence they would vary throughout the course of a numerical integration. For comparison, if P_FO_NF is expressed in the Newtonian frame and no substitution is used, it looks like: - (224) P_FO_NF = rf*(SIN(q4)*COS(q7)+SIN(q7)*COS(q4)*SIN(lambda +q6))*(SIN(q7) *COS(q3)*COS(lambda+q6)+SIN(q3)*(COS(q4)*COS(q7)- SIN(q4)*SIN(q7)*SIN(lambda+q6)) )/(1-(SIN(q4)*COS(q7)+SIN(q7)*COS(q4)*SIN(lambda+q6))^2)^0.5*N1 + rf*(SIN(q4)*C OS(q7)+SIN(q7)*COS(q4)*SIN(lambda+q6))*(SIN(q3)*SIN(q7)*COS(lambda+q6)- COS(q3)*( COS(q4)*COS(q7)-SIN(q4)*SIN(q7)*SIN(lambda+q6)))/(1- (SIN(q4)*COS(q7)+SIN(q7)*COS (q4)*SIN(lambda+q6))^2)^0.5*N2 + (rft+rf*(1- (SIN(q4)*COS(q7)+SIN(q7)*COS(q4)*SI N(lambda+q6))^2)^0.5)*N3 It is easy to see that there are many repeated quantities in the above expression and it makes sense that they only be computed once. When forming expressions for the velocities and accelerations, one can imagine how long the expressions get after the application of the chain rule many pages long. I don't know if the method Autolev is identifying and creating intermediate variables is the best way to do it because I have seen cases that don't seem to actually simplify the equations much, but for the most part, it seems to work well. And, as was mentioned by somebody else, there must be a trade off between memory usage and flop usage. I the problems I have worked on, using extra memory used has been worth the savings in flops by a large factor. For example, the equations of motion for the Whipple bicycle generated by Autolev are about 77kb, while those same equations generated by another author's method are about 3.5mb, almost 2 orders of magnitude larger. Needless to say, numerical integration times are much faster with the smaller more compact representation of the equations of motion. Essentially what I need to do is parse every equation and identify subexressions (and then parse those subexpression and identify subsubexpressions), and introduce variables for any that are used more than once. If a subexpression is found, but doesn't occur more than once in any of the preceding equations, but then later shows up in another equation, it would then be introduced as an intermediate variable. If they aren't used more than once, then it doesn't make sense to introduce an intermediate variable for them, unless the goal is simply just readability. Any ideas on how to start parsing each equation and accumulating a list of subexpressions? I haven't had time to start coding this up in python yet, hopefully I'll get started on this over the summer. Thanks, ~Luke On Jun 15, 11:28 pm, Robert Kern [EMAIL PROTECTED] wrote: On Sun, Jun 15, 2008 at 17:46, Ondrej Certik [EMAIL PROTECTED] wrote: Anyway, I created an issue for this: http://code.google.com/p/sympy/issues/detail?id=891 I've attached some nominally working code to the issue. Playing with it, I see some suboptimal results. First, it's quadratic, but I'm not clever enough to think of a way around that. Second, sympy's default representation of expressions isn't well-suited for this algorithm (or the other way around). For example: In [1]: from cse import cse In [2]: cse((x-y)*(z-y) + sqrt((x-y)*(z-y))) Out[2]: ⎛ ⎞ ⎝[(x₀, -y), (x₁, x + x₀), (x₂, x₀ + z)], x₁*x₂ + ╲╱ x₁ *╲╱ x₂ ⎠ We see that -y gets picked up as term that should be pulled out although it only shows up in the context of (x-y). For the typical use case, subtraction is an atomic operation, and the representation of (x-y) as Add(Mul(NegativeOne(-1), Symbol('y')), Symbol('x')) gets in the way. Although the input expression has both x1 and x2 under the same sqrt(), it gets broken out before the cse() function gets to look at it. It would be nice to stuff everything in that term
[sympy] Re: Identifying repeated subexpressions in systems of equations
Robert, The Mathematica link you provided is exactly what I'm trying to do. I haven't tried your python code yet but after reading it I think it should work great. I really appreciate your comments and your help! Thanks, ~Luke On Jun 16, 12:14 pm, Robert Kern [EMAIL PROTECTED] wrote: On Mon, Jun 16, 2008 at 12:13, Luke [EMAIL PROTECTED] wrote: Essentially what I need to do is parse every equation and identify subexressions (and then parse those subexpression and identify subsubexpressions), and introduce variables for any that are used more than once. If a subexpression is found, but doesn't occur more than once in any of the preceding equations, but then later shows up in another equation, it would then be introduced as an intermediate variable. If they aren't used more than once, then it doesn't make sense to introduce an intermediate variable for them, unless the goal is simply just readability. Any ideas on how to start parsing each equation and accumulating a list of subexpressions? Look at the code I provided attached to the issue. http://sympy.googlecode.com/issues/attachment?aid=3304519749492286715... -- Robert Kern I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth. -- Umberto Eco --~--~-~--~~~---~--~~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sympy?hl=en -~--~~~~--~~--~--~---
[sympy] Symbolic dot and cross products with implicit rotation matrices
I'm trying to figure out how I could implement in Sympy a way to take dot and cross products of unit vectors in different reference frames. For example, suppose I have a reference frame 'A', along with 3 dextral orthonormal vectors: a1, a2, a3. I think I can figure out how to code up something so that dot and cross products in the same reference frame would give the following results: In[1]: dot(a1,a2) Out[1]: 0 In[2]: dot(a1,a1) Out[2]: 1 In[3]: cross(a1,a2) Out[3]: a3 I haven't done this yet, but I think it should be pretty straightforward. What I would like to extend this to is to be able to dot and cross multiply unit vectors from different reference frames. For example, suppose I introduce a second reference frame 'B', along with 3 dextral orthonormal vectors: b1, b2, b3, and I orient B by aligning B with A then performing a simple rotation of B about the a3=b3 axis by an angle q1. Then: b1 = cos(q1)*a1 + sin(q1)*a2 b2 = -sin(q1)*a1 + cos(q1)*a2 b3 = a3 I would like to then be able to do: In[4]: dot(a1,b1) Out[4]: cos(q1) etc... I guess what I'm not sure about is how to structure all the objects so that if a rotation matrix hasn't been defined between two reference frames, an exception is raised and you can't take the dot or cross product. It would be ideal to be able to handle long chains of simple rotations so that every possible rotation matrix wouldn't need to be defined explicitly, i.e., if I specify the orientation of B relative to A (as above), and then the orientation of another reference frame C relative to B, and then try to take a dot product between a1 and c1, the two rotation matrices (C to B, B to A) get multplied and then used to compute the dot product. I'm familiar with classes and python fairly well, and I know the kinematics well, but I'm by no means an experience object oriented programmer, so I'm not sure about how the best way to structure things would be. Any suggestions on how I might start on something like this? Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Re: Symbolic dot and cross products with implicit rotation matrices
I would like everything to be symbolic. If you have two reference frames, say A and B, you can only take the dot product of a vector expressed using the A coordinates with a vector expressed in the B coordinates if you know the rotation matrix that relates the two reference frames. For example: Take A and B to be two reference frames that have a set of 3 dextral orthonormal vectors ( i.e, dot(a1,a2)=dot(a2,a3)=dot(a1,a3)=0, cross (a1,a2)=a3, cross(a2,a3)=a1, and cross(a3,a1)=a2). Define the orientation of B relative to A by initially aligning a1 with b1, a2 with b2, a3 with b3, then performing a right handed rotation of B relative to A by an angle q1 about an axis parallel to a3 (and b3). Then: b1 = cos(q1)*a1 + sin(q1)*a2 b2 = -sin(q1)*a1 + cos(q1)*a2 b3 = a3 Normally I would write a1,a2,a3,b1,b2,b3 in bold or with a carat above them, the way you might see them in a physics class or a dynamics class, but I think you get the idea. Now, in order to take a dot product of two vectors that are expressed in the same reference frame coordinates, we use the following rules: dot(a1,a2) = 0 dot(a1,a3) = 0 dot(a2, a3) = 0 dot(a1,a1)=1 dot(a2,a2)=1 dot(a3,a3)=1 So any vector expression that only involves terms with a1,a2,a3, we can easily a dot() function to implement the above rules for the dot product. But what if we need to dot multiply a1 and b1? Then we need to either 1) express a1 in terms of B coordinate basis vectors, or 2) express b1 in terms of A coordinate basis vectors. Here is where we need to rotation matrix defined above, and here is how I'm not sure of how to best implement things. I'm looking for a good way to store the rotation matrices with the reference frame objects If one defines successive rotations, say, starting with A, then orienting B relative to A, then C relative to B, then D relative to C, we want to have the dot() function be able to resolve the dot product of say d1 and a1, even though the rotation matrix between D and A wasn't explicitly defined (instead is it is implicitly defined through a series of matrix multiplications). One could imagine a long chain of rotations, with various branches (as is common in the case of multi-body systems). How to best store the and resolve the various rotations is what I'm after. The reason I would like to do this is to be ably to use the following syntax to define the position of one point q relative to another p: p_q_p = q2*a1 + q3*b2 and the be able to do: dot(p_q_p,a1) and get: q2 - sin(q1)*q3 (recall, b2 = -sin(q1)*a1+cos(q1)*a2) Hopefully this clarifies what I'm trying to do. Thanks, ~Luke On Jan 17, 5:12 am, Alan Bromborsky abro...@verizon.net wrote: Luke wrote: I'm trying to figure out how I could implement in Sympy a way to take dot and cross products of unit vectors in different reference frames. For example, suppose I have a reference frame 'A', along with 3 dextral orthonormal vectors: a1, a2, a3. I think I can figure out how to code up something so that dot and cross products in the same reference frame would give the following results: In[1]: dot(a1,a2) Out[1]: 0 In[2]: dot(a1,a1) Out[2]: 1 In[3]: cross(a1,a2) Out[3]: a3 I haven't done this yet, but I think it should be pretty straightforward. What I would like to extend this to is to be able to dot and cross multiply unit vectors from different reference frames. For example, suppose I introduce a second reference frame 'B', along with 3 dextral orthonormal vectors: b1, b2, b3, and I orient B by aligning B with A then performing a simple rotation of B about the a3=b3 axis by an angle q1. Then: b1 = cos(q1)*a1 + sin(q1)*a2 b2 = -sin(q1)*a1 + cos(q1)*a2 b3 = a3 I would like to then be able to do: In[4]: dot(a1,b1) Out[4]: cos(q1) etc... I guess what I'm not sure about is how to structure all the objects so that if a rotation matrix hasn't been defined between two reference frames, an exception is raised and you can't take the dot or cross product. It would be ideal to be able to handle long chains of simple rotations so that every possible rotation matrix wouldn't need to be defined explicitly, i.e., if I specify the orientation of B relative to A (as above), and then the orientation of another reference frame C relative to B, and then try to take a dot product between a1 and c1, the two rotation matrices (C to B, B to A) get multplied and then used to compute the dot product. I'm familiar with classes and python fairly well, and I know the kinematics well, but I'm by no means an experience object oriented programmer, so I'm not sure about how the best way to structure things would be. Any suggestions on how I might start on something like this? Thanks, ~Luke Do you want to do this purely symbolically or are you going to put in specific values? That is do you want sympy only to generate symbolic formulas that you will later use in a program or do you want
[sympy] Identifying additive terms in an expression
If I have a symbolic expression like: expr = a*sin(x) + b*cos(y) - c*tan(z) I can get each individual additive term, sort of like: In[1]: terms(expr) Out[1]: [a*sin(x), b*cos(y), -c*tan(z)] ? Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Fwd: Confused about something
I'm working on equality comparisons for a class I call 'Vector'. Really this class is to represent Vectors in R^3, but in a way that allows for both symbolic and numeric evaluation, and to allow for Vectors to be defined as linear combinations of UnitVectors (another class) that a fixed in ReferenceFrames (another class, oriented through rotations). Anyway, Ondrej and I have had some discussion of how to check for equality between a Vector/UnitVector and another Vector/UnitVector. Below is the discussion Ondrej and I were having. Here is my question: How should the ._args attribute be implemented in the Vector class? Ondrej mentioned making it a list of all the aruguments, but I'm a little confused about this. The way I have implemented the Vector class is to have an attribute .dict which is a dictionary that contains as the keys all the UnitVectors and for the corresponding values, the coefficient of the UnitVector which is the key of that value. For example: A = ReferenceFrame('A') v1 = Vector(5*A[1] + 6*A[2]) then: v1.dict == {A[1]: 5, A[2]: 6} Perhaps this isn't the best way to do things, but in my mind this made sense so this is how I implemented it. Should the ._args list for the above example then be: v1._args == [5*A[1], 6*A[2]] ? Thanks, ~Luke -- Forwarded message -- From: Ondrej Certik ond...@certik.cz Date: Thu, Apr 16, 2009 at 9:37 PM Subject: Re: Confused about something To: Luke hazelnu...@gmail.com On Thu, Apr 16, 2009 at 8:00 PM, Luke hazelnu...@gmail.com wrote: Ondrej, My responses below. On Thu, Apr 16, 2009 at 6:57 PM, Ondrej Certik ond...@certik.cz wrote: On Thu, Apr 16, 2009 at 4:51 PM, Luke hazelnu...@gmail.com wrote: Ondrej, I'm a little confused about this: assert cross(A[1], A[3]) == Vector(-A[2]) AssertionError: begin captured stdout - cross(A[1], A[3]): -a2 class 'pydy.Vector' {a2: -1} Vector(-A[2]): -a2 class 'pydy.Vector' {a2: -1} ^^^ well, those two results above are the same, aren't they? So it should return True. I agree. But it doesn't, even though they are the same. I am not sure why. If I implement a __eq__() method, I can do quick comparison of the dictionaries and return the result, but I was under the impression I shouldn't define my own __eq__() method, but rather a separate equal() method. I think I know why -- you need to store all the arguments of the Vector in ._args list. Then the standard sympy comparisons will automatically compare this list and it should start working. I think it has to be hashable though, so just store the dict in some variable as it is now and create a list out of the dict and store that in the ._args. All should work because the dict is never modified once the Vector instance is created. -A[2] -a2 class 'sympy.core.mul.Mul' This is the case when the Vector class has no __eq__() method. My guess is that since Vector is subclassed from Basic, it tries to compare them that way and somehow fails. I'm not sure if I should bother trying to get this to be True, since I already have: (cross(A[1], A[3])).equal(-A[2]) == True This is fine, it just means I need to rewrite a lot of tests if this is the case. What do you think? I think that the == (or __eq__) should return quickly True/False and it should just compare the expressions (no matter their mathematical equivalence). And then you can have .equal() or simplify() or whatever, that will try to convert the vectors to the same frame and simplify them and compare them. So I should write my own __eq__() for both the UnitVector class and the Vector class? For comparisons between two Vectors or between two See above, just implement ._args. UnitVectors, this fast comparison would be fairly trivial, and the .equal() one isn't much worse. In fact, I have already implemented the code for this, but I just am unclear where I should put it. does: cross(A[1], A[3])) == -A[2] No. cross(A[1], A[3]) returns a UnitVector object. -A[2] is a sympy expression, a Mul object. I could however, implement in the __eq__() Then it it ok that it returns False. Imho. of the UnitVector and Vector classes the ability to check if the RHS of the == is a sympy expression, and if so, make it a Vector, which then can be compared by comparing the dictionaries. work? and what about -A[2] == Vector(-A[2]) Nope. Same reasons as above. Here, __eq__() is being called for a Then it it ok that it returns False, same reasons. Mul Object, so unless we put code in there that knows about the Vector class, I don't think we can make the above statement work. Or am I wrong on this? sympy expression and a Vector should always compare as False, because it's a different thing. For mathematical comparison, let's implement the .equal(). Btw, let's discuss this on the sympy list from now on. So that other people can join in and we can build a community. Thanks, Ondrej
[sympy] Printing of functions
I am working with some sympy Functions that are dependent upon a sympy Symbol 't'. For example: t = Symbol('t') q1 = Function('q1')(t) When q1 is printed I get: q1(t) Similarly, when q1.diff(t) is printed I get: D(q1(t), t) I would instead like the following behavior: In: print q1 Out: q1 In: print q1.diff(t) Out: q1' Basically, the Functions that I am working with are generalized coordinates, and their time dependence is implied so having the (t) just makes all the expressions really long and hard to look at. Similarly for q1.diff(t). How would I go about tackling this? Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Re: Trigsimp error
Incidentally, trying trigsimp with recursive=True, deep=True, or both True didn't give the desired result. On Tue, Apr 28, 2009 at 12:22 AM, Luke hazelnu...@gmail.com wrote: I'm writing some tests for some code that expresses a Vector expression in the coordinates of a different frame. I am using Sympy's trigsimp to simplify expressions, but the following Sympy expression isn't trigsimplifying: cos(q4)**2 + sin(q3)**2*sin(q4)**2 + cos(q3)**2*cos(q4)**2*tan(q4)**2 It should simplify to 1, instead it trigsimplifies to: cos(q4)**2 + sin(q3)**2*sin(q4)**2 + cos(q3)**2*sin(q4)**2 So, I tried trigsimplifying, then factoring, but I got the following error: In [10]: factor(trigsimp(cos(q4)**2 + sin(q3)**2*sin(q4)**2 + cos(q3)**2*cos(q4)**2*tan(q4)**2)) ERROR: An unexpected error occurred while tokenizing input The following traceback may be corrupted or invalid The error message is: ('EOF in multi-line statement', (33, 0)) --- PolynomialError Traceback (most recent call last) /home/luke/Documents/PythonDynamics/ipython console in module() /usr/lib/pymodules/python2.5/sympy/polys/factortools.pyc in factor(f, *symbols, **flags) 78 return f 79 --- 80 coeff, factors = poly_factors(f, *symbols, **flags) 81 82 result = 1 # XXX: don't include coeff in the leading factor /usr/lib/pymodules/python2.5/sympy/polys/factortools.pyc in poly_factors(f, *symbols, **flags) 18 19 if not isinstance(f, Poly): --- 20 f = Poly(f, *symbols) 21 elif symbols: 22 raise SymbolsError(Redundant symbols were given) /usr/lib/pymodules/python2.5/sympy/polys/polynomial.pyc in __new__(cls, poly, *symbols, **flags) 400 terms = Poly._permute(poly, *symbols) 401 else: -- 402 terms = Poly._decompose(poly, *symbols) 403 404 if terms: /usr/lib/pymodules/python2.5/sympy/polys/polynomial.pyc in _decompose(poly, *symbols) 543 continue 544 -- 545 raise PolynomialError(Can't decompose %s % factor) 546 else: 547 coeff *= factor PolynomialError: Can't decompose cos(q4)**2 I'm dealing with stuff that is going to make heavy use of trigsimp, so I'm willing to dig into it a bit. Should this be filed as a bug, or is there something obvious that I am missing. Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Injecting symbols/variables into the workspace
I would like to write something that works similarly to var(), but injects implicit functions of a symbol (in my case 't'), i.e.: gc('q1 q2 q3') (q1, q2, q3) q1 q1(t) gc stands for Generalized Coordinate in mechanics these are typically always functions of time. Even better would be something that allows for syntax such as: gc('q', 3) But has the same behavior as above. Is there a way to do this but *not* inject it into the *global* namespace, only the local one? ~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 -~--~~~~--~~--~--~---
[sympy] Re: Trigsimp error
It isn't too pressing for PyDy, I just ran into it when creating some tests that would ensure PyDy gave the same output as Autolev. In Autolev, if you express a UnitVector from one reference in the coordinates of another reference frame that is 3 or more simple rotations away, when you convert the expression back to the original frame, you won't just get a UnitVector. This isn't a huge deal and I don't see immediately a situation where you would go back and forth between frames just for fun, but it would be nice to know that you could if you wanted to :) I'll file the bug report, and I'll try to look at the paper Akshay mentioned. Akshay, if you need more examples that should simplify, I can provide you with a handful more :) ~Luke On Apr 28, 8:28 am, Akshay Srinivasan akshaysriniva...@gmail.com wrote: I think trigsimp is too hack-ish. I'll try implementing the algorithm given athttp://vv.cn/d/d.aspx?Id=21987_1.0.42119- I guess this is the one Ondrej was talking about - in the coming weeks. I'm still not sure how good it is, does anyone know of anything better ? Akshay On Apr 28, 6:52 pm, Alan Bromborsky abro...@verizon.net wrote: Ondrej Certik wrote: On Tue, Apr 28, 2009 at 12:22 AM, Luke hazelnu...@gmail.com wrote: I'm writing some tests for some code that expresses a Vector expression in the coordinates of a different frame. I am using Sympy's trigsimp to simplify expressions, but the following Sympy expression isn't trigsimplifying: cos(q4)**2 + sin(q3)**2*sin(q4)**2 + cos(q3)**2*cos(q4)**2*tan(q4)**2 It should simplify to 1, instead it trigsimplifies to: cos(q4)**2 + sin(q3)**2*sin(q4)**2 + cos(q3)**2*sin(q4)**2 It's a bug. Could you please file an issue for it? There is a nice article how to implement robust trigsimp somewhere in our issues, but noone found time for it yet. Is it very pressing for pydy? If not, let's keep this in mind and continue --- I think at the end of the summer it will be clear what sympy bugs should be fixed first and which later, so that pydy works reasonably well. Ondrej Program: from sympy import * q3,q4 = symbols('q3,q4') f = cos(q4)**2 + sin(q3)**2*sin(q4)**2 + cos(q3)**2*cos(q4)**2*tan(q4)**2 print f f = trigsimp(f,deep=True,recursive=True) f = trigsimp(f,deep=True,recursive=True) print f Output: cos(q4)**2 + sin(q3)**2*sin(q4)**2 + cos(q3)**2*cos(q4)**2*tan(q4)**2 1 Note on strange behavior. When I ran this program from SPE I did not need the second f = trigsimp(f,deep=True,recursive=True) to simplify to 1, but when I ran it from a shell I did. Shell results without second f = trigsimp(f,deep=True,recursive=True) : cos(q4)**2 + sin(q3)**2*sin(q4)**2 + cos(q3)**2*cos(q4)**2*tan(q4)**2 cos(q4)**2 + cos(q3)**2*sin(q4)**2 + sin(q3)**2*sin(q4)**2 Perhaps what trigsimp needs to do is convert all expressions to sin and cos and do algebraic simplification and then do trigsimp! --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Trigsimp error
I just finished reading this paper. It seems pretty reasonable, and not to difficult to implement. Does anybody know of any other papers on this subject that might offer alternative methods that would be worth looking at? If there was some sort of gold standard paper on the subject, that might be what we want to implement. I don't have much time to start coding on it for a few weeks, but I could probably look at a few papers and let it soak in ~Luke On Apr 28, 12:35 pm, Ondrej Certik ond...@certik.cz wrote: On Tue, Apr 28, 2009 at 12:32 PM, Ondrej Certik ond...@certik.cz wrote: On Tue, Apr 28, 2009 at 11:44 AM, Akshay Srinivasan akshaysriniva...@gmail.com wrote: Freddie Witherden wrote: Hi all, I think trigsimp is too hack-ish. I'll try implementing the algorithm given athttp://vv.cn/d/d.aspx?Id=21987_1.0.42119- I guess this is the one Ondrej was talking about - in the coming weeks. I'm still not sure how good it is, does anyone know of anything better ? Look at my proposal to switch to Maxima like simplification functions. Might be worth implementing them for trig functions (using the same algorithms as Maxima). The functions and algorithms are both well tested as a result. Regards, Freddie. I couldn't find the algorithm on the webpage, do you know where it is ? I can't remember now. The issue with the links is here: http://code.google.com/p/sympy/issues/detail?id=935#c8 Ok, the paper is: Automated and readable simplification of trigonometric expressions Hongguang Fu a,1 , Xiuqin Zhong a,* , Zhenbing Zeng b Mathematical and Computer Modelling 44 (2006) 1169-1177 and I just sent you a copy offlist. Ondrej --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] solve() and diff() with Symbol versus Function
Would there be any reason that the following should not be implemented: t = Symbol('t') q1 = Function('q1')(t) solve(q1 - 1, q1) Currently, the solve function gives: --- TypeError Traceback (most recent call last) /home/luke/Documents/PythonDynamics/ipython console in module() /var/lib/python-support/python2.6/sympy/solvers/solvers.pyc in solve(f, *symbols, **flags) 73 74 if any(not s.is_Symbol for s in symbols): --- 75 raise TypeError('not a Symbol') 76 77 if not isinstance(f, (tuple, list, set)): TypeError: not a Symbol In classical mechanics, the generalised coordinates are often treated as symbols implicitly dependent upon time. Not being able to solve for their time derivatives using solve requires tedious .subs() calls to replace them with symbols, solve, then replace them back with Functions. Similarly, is there a reason we can't differentiate with respect to a Function? For example, when using Lagrange's method for formulating equations of motion, we need to differentiate the Lagrangian with respect to the coordinates and with respect to the time derivatives of the coordinates, and then take the time derivative Not being able to differentiate with respect to q1.diff(t) means that one has to create a dummy symbol for q1.diff(t), replace all occurances of it in the Lagrangian, then take the derivative with respect to that symbol, then back substitute to replace the symbol with the function, then differentiate with respect to time a very burdensome approach indeed. This is what happens currently: In [12]: diff(q3-1, q3) --- ValueErrorTraceback (most recent call last) /home/luke/Documents/PythonDynamics/ipython console in module() /var/lib/python-support/python2.6/sympy/core/multidimensional.pyc in wrapper(*args, **kwargs) 125 result = apply_on_element(wrapper, args, kwargs, n) 126 return result -- 127 return f(*args, **kwargs) 128 wrapper.__doc__ = f.__doc__ 129 wrapper.__name__ = f.__name__ /var/lib/python-support/python2.6/sympy/core/function.pyc in diff(f, x, times, evaluate) 693 694 -- 695 return Derivative(f,x,times, **{'evaluate':evaluate}) 696 697 @vectorize(0) /var/lib/python-support/python2.6/sympy/core/function.pyc in __new__(cls, expr, *symbols, **assumptions) 476 s = sympify(s) 477 if not isinstance(s, Symbol): -- 478 raise ValueError('Invalid literal: %s is not a valid variable' % s) 479 if not expr.has(s): 480 return S.Zero ValueError: Invalid literal: q3(t) is not a valid variable Or is there another way this can be done easily that I'm not aware of? Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Re: solve() and diff() with Symbol versus Function
I'll work on it in the next week or so, I think should be able to get something that does the job. ~Luke On May 11, 11:06 pm, Ondrej Certik ond...@certik.cz wrote: On Mon, May 11, 2009 at 9:23 PM, Luke hazelnu...@gmail.com wrote: Would there be any reason that the following should not be implemented: t = Symbol('t') q1 = Function('q1')(t) solve(q1 - 1, q1) Currently, the solve function gives: --- TypeError Traceback (most recent call last) /home/luke/Documents/PythonDynamics/ipython console in module() /var/lib/python-support/python2.6/sympy/solvers/solvers.pyc in solve(f, *symbols, **flags) 73 74 if any(not s.is_Symbol for s in symbols): --- 75 raise TypeError('not a Symbol') 76 77 if not isinstance(f, (tuple, list, set)): TypeError: not a Symbol In classical mechanics, the generalised coordinates are often treated as symbols implicitly dependent upon time. Not being able to solve for their time derivatives using solve requires tedious .subs() calls to replace them with symbols, solve, then replace them back with Functions. Yes, I think this should be fixed. Could you please try to create a preliminary patch that fixes this in solve()? We'll cook it in sympy-patches for a while and get this in. Similarly, is there a reason we can't differentiate with respect to a Function? For example, when using Lagrange's method for formulating equations of motion, we need to differentiate the Lagrangian with respect to the coordinates and with respect to the time derivatives of the coordinates, and then take the time derivative Not being able to differentiate with respect to q1.diff(t) means that one has to create a dummy symbol for q1.diff(t), replace all occurances of it in the Lagrangian, then take the derivative with respect to that symbol, then back substitute to replace the symbol with the function, then differentiate with respect to time a very burdensome approach indeed. Yep, I think this was requested in the past too. Let's fix it. This is what happens currently: In [12]: diff(q3-1, q3) --- ValueError Traceback (most recent call last) /home/luke/Documents/PythonDynamics/ipython console in module() /var/lib/python-support/python2.6/sympy/core/multidimensional.pyc in wrapper(*args, **kwargs) 125 result = apply_on_element(wrapper, args, kwargs, n) 126 return result -- 127 return f(*args, **kwargs) 128 wrapper.__doc__ = f.__doc__ 129 wrapper.__name__ = f.__name__ /var/lib/python-support/python2.6/sympy/core/function.pyc in diff(f, x, times, evaluate) 693 694 -- 695 return Derivative(f,x,times, **{'evaluate':evaluate}) 696 697 @vectorize(0) /var/lib/python-support/python2.6/sympy/core/function.pyc in __new__(cls, expr, *symbols, **assumptions) 476 s = sympify(s) 477 if not isinstance(s, Symbol): -- 478 raise ValueError('Invalid literal: %s is not a valid variable' % s) 479 if not expr.has(s): 480 return S.Zero ValueError: Invalid literal: q3(t) is not a valid variable Or is there another way this can be done easily that I'm not aware of? Currently you have to do it by hand. Try to implement this in the Derivative class, so that it works. It may not be obvious how to do it so that it looks good, but try to implement it somehow so that it works and we'll then refine the patch, so that it can be pushed in. E.g. my first try would be to just do all the substitutions automatically inside Derivative, e.g. something like if isinstance(s, Function): substitute, differentiate, substitute, return the result Ondrej --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] trigsimp
Last night I was deriving the moment of inertia for a solid torus using Sympy. It mostly worked, except for the step where the determinant of the Jacobian for the change of variables mapping was to be computed, the result was unable to be simplified by trigsimp. I gave it a shot anyway, and it resulted in integrate() stalling on the triple integral that is necessary. Using other means to compute the Jacobian of the determinant, then using that result in integrate() resulted in the correct solution for the moment of inertia, which is comforting, but at the same time, really makes me want to get trigsimp to work better. I know of the paper by Fu, Zhong, and Zeng, but I was wondering if anybody had any other recommendations for approaches to trigonometric simplification. It would be really nice if this part of sympy worked better. If there is somebody else out there who would like to tackle this together, let me know and we could figure out a reasonable approach. Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Poll on usage of solve()
Does anybody use solve() by passing the function and/or the symbol arguments as a set, rather than a list or a tuple? I can't see a reason why using it with a set would be beneficial, and without support for sets, there are some aspects of solve that would become easier with regard to being able to solve equation(s) for both Symbol objects and Function objects. It makes the most sense to me that it should only support lists and tuples. ~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 -~--~~~~--~~--~--~---
[sympy] Enhancing functionality of diff()
I would like to add code that would allow for diff() to differentiate with respect to not just Symbol instances, but also with respect to Function and Derivative instances. An example of why this would be useful would be when forming Lagrange's equations, on needs to differentiate the Lagrangian with respect to the generalized coordinates, the time derivative of the generalized coordinates, and also with respect to time, and the generalized coordinates themselves are implicit functions of time. My question is: Where should I add the code that allows for this? I can see two options: 1) in diff() of sympy/core/basic.py 2) in Derivative of sympy/core/function.py It seems to me option 1 is the right choice but I'd like to hear input on this. Maybe it doesn't matter or maybe it could another place? Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Re: sympy vs matlab integrate, get 'final' result?
I get a slightly different result when integrating in Matlab (2008a): [matlab] syms X Y L H K; int(int(2*X*X+2*Y*Y-1, Y, -sqrt(1-X*X), sqrt(1-X*X)), X, L, 1) ans = -2/3*(1-L^2)^(1/2)*L*(L-1)*(1+L) expand(ans) ans = 2/3*(1-L^2)^(1/2)*L-2/3*(1-L^2)^(1/2)*L^3 [/matlab] In sympy, it seems like if you do the first integral, there are two additive terms: integrate(2*X*X+2*Y*Y-1, (Y, -(1-X**2)**Rational(1,2), (1-X**2)**Rational(1,2)) ) -2*(1 - X**2)**(1/2)*(1 - 2*X**2) + 4*(1 - X**2)**(3/2)/3 t1 = integrate(4*(1 - X**2)**(3/2)/3, (X,L,1)) 8/9 - 4*L/3 + 4*L**3/9 t2 = integrate(-2*(1 - X**2)**(1/2)*(1 - 2*X**2), (X,L,1)) -2/3 + 2*L - 4*L**3/3 t1+t2 2/9 + 2*L/3 - 8*L**3/9 So if you perform the second integration on each term, one at a time, it is fine, but when you try to do the whole thing, it doesn't like it, as you pointed out. I'm not sure why this would happen, it seems like integrate should parse each additive term and try to integrate it, if this were the case, the above example should work like Matlab. Additionally, it doesn't seem that the results are the same, so there must be some sort of bug in integrate. ~Luke On May 22, 2:27 am, Oyster lepto.pyt...@gmail.com wrote: please note the dual-integrate result how can I get an advanced value in sympy? thanx [smypy] from sympy import * X,Y=symbols('XY', real=True) integrate(2*X*X+2*Y*Y-1, (Y, -(1-X**2)**Rational(1,2), (1-X**2)**Rational(1,2)) ) -2*(1 - X**2)**(1/2)*(1 - 2*X**2) + 4*(1 - X**2)**(3/2)/3 integrate(integrate(2*X*X+2*Y*Y-1, (Y, -(1-X**2)**Rational(1,2), (1-X**2)**Rational(1,2)) ), (X,L,1)) Integral(-2*(1 - X**2)**(1/2)*(1 - 2*X**2) + 4*(1 - X**2)**(3/2)/3, (X, L, 1)) simplify(integrate(integrate(2*X*X+2*Y*Y-1, (Y, -(1-X**2)**Rational(1,2), (1-X**2)**Rational(1,2)) ), (X,L,1))) Traceback (most recent call last): File interactive input, line 1, in ? File h:\pure_pylib\math\sympy\sympy\simplify\simplify.py, line 1079, in simplify File h:\pure_pylib\math\sympy\sympy\polys\polynomial.py, line 607, in cancel File h:\pure_pylib\math\sympy\sympy\core\basic.py, line 1437, in expand File h:\pure_pylib\math\sympy\sympy\core\basic.py, line 1372, in _eval_expand_basic File h:\pure_pylib\math\sympy\sympy\core\basic.py, line 374, in new File h:\pure_pylib\math\sympy\sympy\integrals\integrals.py, line 48, in __new__ ValueError: Invalid integration variable or limits: (((X, (L, 1)),),) [/sympy] [matlab] syms X Y L H K; int(int(2*X*X+2*Y*Y-1, Y, -sqrt(1-X*X), sqrt(1-X*X)), X, L, 1) ans = 2/3*L*(1-L^2)^(3/2) int(2*X*X+2*Y*Y-1, Y, -sqrt(1-X*X), sqrt(1-X*X)) ans = 4*X^2*(1-X^2)^(1/2)+4/3*(1-X^2)^(3/2)-2*(1-X^2)^(1/2) int(int(2*X*X+2*Y*Y-1, Y, -sqrt(1-X*X), sqrt(1-X*X)), X, L, 1) ans = 2/3*L*(1-L^2)^(3/2) [/matlab] --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Motion equation generation script sharing
This is cool, it is good to see other people who are familiar with Kane's method, there aren't many of us :) Are you familiar with Autolev? With PyDy, I am working to achieve some of the same behavior as Autolev, but make it even better, and have a lot more features. I'd love to hear your input on design choices for PyDy if you have the time. Right now I'm working on extending it to allow for the 12 different Euler angles, and the 12 different space fixed angles, Euler parameters, Rodrigues parameters, and axis/angle rotations. The major work to take care of kinematics automatically is in place, but there is definitely more to do in regards to how to deal with constraints, definitions of generalized speeds, etc... What sort of systems do you use Kane's method to study? My own area of research is two wheeled vehicle (bicycle/motorcycle) dynamics and control. ~Luke On May 23, 6:06 am, 2006.uchida 2006.uch...@gmail.com wrote: I made a small script in MuPAD few years ago but I had to say goodbye to MuPAD last November, so I found Sympy and have translated it into Sympy now. I want to share it and I'm happy if I get some comments. What I made is the small script that generates motion equations for multibody dynamics by using Kane's method. It handles multibody dynamics, the dynamic behavior created with several rigid bodies that are interconnected, for instance, double pendulum, robot arms, crank mechanism, etc. The script allows you to get the equation easily by setting some information of masses, positions, forces, etc. available for download from here:http://www.esnips.com/doc/0960cb0a-8820-4169-b582-d58a2d6c5f28/MoEqGe... Here is a sample code and results. More details, please see the file smple.py which you can download above. [Code] import sympy import motionequation def main(): # Sample for Newton's second law mat = sympy.Matrix t, x, m, f = sympy.symbols( t, x, m, f) pos_vec = mat([x(t),0,0]) force_vec = mat([f(t),0,0]) I_mat = sympy.zeros(3) ome_vec = sympy.zeros([3,1]) torque_vec = sympy.zeros([3,1]) result = motionequation.get_withKane( t, [x(t).diff(t)], [m], [pos_vec], [I_mat], [ome_vec], [pos_vec], [force_vec], [ome_vec], [torque_vec]) print Newton's second law: sympy.pprint(result) main() [/Code] [Console] Newton's second law: 2 d [m*-(x(t)) = f(t)] dt dt [/Console] You can use the feature by calling the function get_withKane in the module motionequation. I tried and confirmed that it will return several kinds of the motion equations, for example, Newton's second law, Euler's equations of rigid body, etc. ondrej.certik provided me with useful information on the project for such a feature which is found at:http://code.google.com/p/pydy/ I'm going to write more about how to specify the arguments of the function to use for your own project. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: sympy vs matlab integrate, get 'final' result?
It seems there is a bug: [matlab] integrand = 2*X*X + 2*Y*Y - 1 integrand = 2*X^2+2*Y^2-1 res = int(integrand, Y, -sqrt(1-X*X), sqrt(1-X*X)) res = 4*X^2*(1-X^2)^(1/2)+4/3*(1-X^2)^(3/2)-2*(1-X^2)^(1/2) subs(res, X, 1) ans = 0 subs(res, X, 2) ans = 0. +17.3205i [/matlab] [sympy] In [1]: from sympy import * In [2]: X,Y,L = symbols('XYL') In [3]: integrand = 2*X*X+2*Y*Y-1 In [4]: res = integrate(integrand, (Y, -sqrt(1-X**2), sqrt(1-X**2))) In [5]: res Out[5]: -2*(1 - X**2)**(1/2)*(1 - 2*X**2) + 4*(1 - X**2)**(3/2)/3 In [6]: res.subs({X: 1}) Out[6]: 0 In [7]: res.subs({X: 2}) Out[7]: 4*3**(1/2) + 14*I*3**(1/2) In [8]: 14.0*3.0**(1./2.) Out[8]: 24.248711305964282 [/sympy] Note the real part of result is nonzero, and that the imaginary part is different from the result that Matlab gives (really Maple under the hood, at least in 2008a). I'll file it under the issues. ~Luke In [9]: res.subs({X: 2.}) Out[9]: 4*3**(1/2) + 14*I*3**(1/2) On May 23, 7:31 am, Oyster lepto.pyt...@gmail.com wrote: that is a bad news :( I have thought to use py+sympy in my research work, but think I'd better turn to matlab now. On May 23, 2:57 am, Luke hazelnu...@gmail.com wrote: I get a slightly different result when integrating in Matlab (2008a): [matlab] syms X Y L H K; int(int(2*X*X+2*Y*Y-1, Y, -sqrt(1-X*X), sqrt(1-X*X)), X, L, 1) ans = -2/3*(1-L^2)^(1/2)*L*(L-1)*(1+L) expand(ans) ans = 2/3*(1-L^2)^(1/2)*L-2/3*(1-L^2)^(1/2)*L^3 [/matlab] In sympy, it seems like if you do the first integral, there are two additive terms: integrate(2*X*X+2*Y*Y-1, (Y, -(1-X**2)**Rational(1,2), (1-X**2)**Rational(1,2)) ) -2*(1 - X**2)**(1/2)*(1 - 2*X**2) + 4*(1 - X**2)**(3/2)/3 t1 = integrate(4*(1 - X**2)**(3/2)/3, (X,L,1)) 8/9 - 4*L/3 + 4*L**3/9 t2 = integrate(-2*(1 - X**2)**(1/2)*(1 - 2*X**2), (X,L,1)) -2/3 + 2*L - 4*L**3/3 t1+t2 2/9 + 2*L/3 - 8*L**3/9 So if you perform the second integration on each term, one at a time, it is fine, but when you try to do the whole thing, it doesn't like it, as you pointed out. I'm not sure why this would happen, it seems like integrate should parse each additive term and try to integrate it, if this were the case, the above example should work like Matlab. Additionally, it doesn't seem that the results are the same, so there must be some sort of bug in integrate. ~Luke On May 22, 2:27 am, Oyster lepto.pyt...@gmail.com wrote: please note the dual-integrate result how can I get an advanced value in sympy? thanx [smypy] from sympy import * X,Y=symbols('XY', real=True) integrate(2*X*X+2*Y*Y-1, (Y, -(1-X**2)**Rational(1,2), (1-X**2)**Rational(1,2)) ) -2*(1 - X**2)**(1/2)*(1 - 2*X**2) + 4*(1 - X**2)**(3/2)/3 integrate(integrate(2*X*X+2*Y*Y-1, (Y, -(1-X**2)**Rational(1,2), (1-X**2)**Rational(1,2)) ), (X,L,1)) Integral(-2*(1 - X**2)**(1/2)*(1 - 2*X**2) + 4*(1 - X**2)**(3/2)/3, (X, L, 1)) simplify(integrate(integrate(2*X*X+2*Y*Y-1, (Y, -(1-X**2)**Rational(1,2), (1-X**2)**Rational(1,2)) ), (X,L,1))) Traceback (most recent call last): File interactive input, line 1, in ? File h:\pure_pylib\math\sympy\sympy\simplify\simplify.py, line 1079, in simplify File h:\pure_pylib\math\sympy\sympy\polys\polynomial.py, line 607, in cancel File h:\pure_pylib\math\sympy\sympy\core\basic.py, line 1437, in expand File h:\pure_pylib\math\sympy\sympy\core\basic.py, line 1372, in _eval_expand_basic File h:\pure_pylib\math\sympy\sympy\core\basic.py, line 374, in new File h:\pure_pylib\math\sympy\sympy\integrals\integrals.py, line 48, in __new__ ValueError: Invalid integration variable or limits: (((X, (L, 1)),),) [/sympy] [matlab] syms X Y L H K; int(int(2*X*X+2*Y*Y-1, Y, -sqrt(1-X*X), sqrt(1-X*X)), X, L, 1) ans = 2/3*L*(1-L^2)^(3/2) int(2*X*X+2*Y*Y-1, Y, -sqrt(1-X*X), sqrt(1-X*X)) ans = 4*X^2*(1-X^2)^(1/2)+4/3*(1-X^2)^(3/2)-2*(1-X^2)^(1/2) int(int(2*X*X+2*Y*Y-1, Y, -sqrt(1-X*X), sqrt(1-X*X)), X, L, 1) ans = 2/3*L*(1-L^2)^(3/2) [/matlab]- Hide quoted text - - Show quoted text - --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: trigsimp
Here is the link for the Maxima trigsimp() code. It was written in 1981, according to the comments!!! http://maxima.cvs.sourceforge.net/viewvc/maxima/maxima/share/trigonometry/trgsmp.mac?revision=1.4view=markup I emailed the authors of the Fu et al. paper to see if they would be willing to share their implementation of the algorithm -- maybe we can save ourselves some work this way. I want to start coding for this, because much of the stuff I am doing in PyDy is heavy on kinematics and the expressions become excessively long unless intelligent trigsimplification is possible. Many of my unittests simply will not work because some results I know to be true cannot be achieved with the current state of trigsimp, so this has become a significant limitation for me. What should be the general framework for implementing the 'rules' that are laid out in the Fu paper? There are certainly other rules we could find, either on Wikipedia, Mathworld, or in a engineering/ mathematics reference manual. I have read over how trigsimp() and trigsimp_nonrecursive() are currently implemented, and I think I get the gyst of what the approach is. Can somebody explain what this is doing exactly: for pattern, simp in matchers: res = result.match(pattern) I'm not 100% clear on the use of the .match() method, does somebody have a quick example of use? It seems like the flow of trigsimp (in the case of recursive==False and deep==False): 1) call trigsimp_nonrecursive(expr, deep==False), store the result in 'result' 2) do some final pattern matching on 'result', currently this will only simplify a*sin(b)**c/cos(b)**c -- a*tan(b)**c So, should all the rules in Fu et al. be implemented as a tuple of length 2 tuples, similar to the existing matchers tuple? I'm kind of thinking out loud right now and trying to figure out the next step to take ~Luke On May 21, 7:42 am, Akshay Srinivasan akshaysriniva...@gmail.com wrote: Luke wrote: I tried both of those options and had no luck :( Have you looked at the paper by Fu, Zhong, and Zeng: http://vv.cn/d/d.aspx?Id=21987_1.0.42119 I read it, and think it seemed reasonable, but I'm no expert and want to see what else was out there... maybe there are other approaches worth considering. Before investing in a lot of coding time, it would nice to be sure that a good algorithm is being used, although I must say their comparisons with the other popular packages out there seem favorable. ~Luke On May 20, 7:50 am, Alan Bromborsky abro...@verizon.net wrote: Luke wrote: Last night I was deriving the moment of inertia for a solid torus using Sympy. It mostly worked, except for the step where the determinant of the Jacobian for the change of variables mapping was to be computed, the result was unable to be simplified bytrigsimp. I gave it a shot anyway, and it resulted in integrate() stalling on the triple integral that is necessary. Using other means to compute the Jacobian of the determinant, then using that result in integrate() resulted in the correct solution for the moment of inertia, which is comforting, but at the same time, really makes me want to gettrigsimp to work better. I know of the paper by Fu, Zhong, and Zeng, but I was wondering if anybody had any other recommendations for approaches to trigonometric simplification. It would be really nice if this part of sympy worked better. If there is somebody else out there who would like to tackle this together, let me know and we could figure out a reasonable approach. Thanks, ~Luke Did you try the deep and recursive switches on the most recent version oftrigsimp. I also would liketrigsimpto do better for the same reasons you gave and would also like it to apply to hyperbolic trig functions. One thing I would do fortrigsimpis to convert all trig functions in the expression to sin's and cos's before simplifying. I have started implementing the algorithm, although I haven't really got much done. I couldn't find any other algorithm to do the simplification. I wonder what Maxima does to simplify trigonometric expressions. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Behavior of trig functions
I noticed the following behavior: In [9]: sin(x) Out[9]: sin(x) In [10]: sin(-x) Out[10]: -sin(x) In [11]: cos(x) Out[11]: cos(x) In [12]: cos(-x) Out[12]: cos(x) In [13]: tan(-x) Out[13]: -tan(x) In [14]: cot(-x) Out[14]: -cot(x) In [15]: sin(pi-x) Out[15]: sin(x) In [18]: sin(2*pi + x) Out[18]: sin(x + 2⋅π) This last command *could* just result in: sin(x) similarly for cos(2*pi+/-x), tan(2*pi +/- x) etc. So it seems that some simplification is being done within the trig definitions themselves, but only for some of the cases. More generally, should the trig functions be smart enough to recognize arguments of the following form: x+/- n*pi and then return the correct result based upon some rule based lookup? Or would it better to require the user to call trigsimp(sin(n*pi +/- x)) to return the simplified result? 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 -~--~~~~--~~--~--~---
[sympy] .is_Number .is_number and .is_NumberSymbol attributes
I'm curious about this: In [29]: e = S(2) In [30]: e.is_number Out[30]: True In [31]: e.is_Number Out[31]: True In [32]: e.is_NumberSymbol Out[32]: False In [33]: pi.is_number Out[33]: True In [34]: pi.is_Number Out[34]: False In [35]: pi.is_NumberSymbol Out[35]: True In [36]: e_over_pi = e/pi In [37]: e_over_pi.is_number Out[37]: True In [38]: e_over_pi.is_Number Out[38]: False In [39]: e_over_pi.is_NumberSymbol Out[39]: False 1) Why are there both 'is_Number' and a 'is_number' methods, and why do they return different results? 2) It seems to me that if something is NumberSymbol, it should also be a Number (or number), but this isn't how pi currently is. I'm guessing this part is a work in progress with the assumptions system, but I'm not sure. ~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 -~--~~~~--~~--~--~---
[sympy] Re: .is_Number .is_number and .is_NumberSymbol attributes
Ok, that makes more sense now. Thanks for the clarification. ~Luke On May 25, 1:05 pm, Abderrahim Kitouni a.kito...@gmail.com wrote: On Mon, 25 May 2009 12:48:09 -0700 (PDT)Luke hazelnu...@gmail.com wrote: 1) Why are there both 'is_Number' and a 'is_number' methods, and why do they return different results? is_number == True means that this is a number (in the mathematical sense). is_Number == True means that this is a Number (or subclass) instance. same here, (i.e. an instance of NumberSymbol), generally is_SomeThing means an instance of SomeThing, ans is_something means 'something' in the mathematical sense. 2) It seems to me that if something is NumberSymbol, it should also be a Number (or number), but this isn't how pi currently is. pi.is_number returns True. I'm guessing this part is a work in progress with the assumptions system, but I'm not sure. HTH, Abderrahim --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: trigsimp
Aaron, Thanks for the clarification. I think I get the idea, but I'm having trouble matching expressions of the following form: a = Wild('a') b = Wild('b') x = Symbol('x') e1 = pi + x e2 = pi - x e3 = -pi + x e4 = -pi - x I would think that for e{1,2,3,4} that I could get the following behavior: e1.match(a*pi + b) {a: 1, b: x} e2.match(a*pi + b) {a: 1, b: -x} e3.match(a*pi + b) {a: -1, b: x} e4.match(a*pi + b) {a: -1, b: -x} But instead, I get: In [61]: e1.match(a*pi + b) Out[61]: ⎧ x ⎫ ⎨a: ─, b: π⎬ ⎩ π ⎭ In [65]: e2.match(a*pi+b) Out[65]: {a: 1, b: -x} In [66]: e3.match(a*pi+b) Out[66]: ⎧ x ⎫ ⎨a: ─, b: -π⎬ ⎩ π ⎭ In [67]: e4.match(a*pi+b) Out[67]: {a: -1, b: -x} The results for e2 and e4 makes sense to me, but I don't understand the behavior for e1 and e3. Is there another simpler approach, or am I missing something fundamental here? Thanks, ~Luke On May 25, 4:07 pm, Aaron S. Meurer asmeu...@gmail.com wrote: On May 25, 2009, at 11:56 AM, Luke wrote: Here is the link for the Maxima trigsimp() code. It was written in 1981, according to the comments!!! http://maxima.cvs.sourceforge.net/viewvc/maxima/maxima/share/trigonom... I emailed the authors of the Fu et al. paper to see if they would be willing to share their implementation of the algorithm -- maybe we can save ourselves some work this way. I want to start coding for this, because much of the stuff I am doing in PyDy is heavy on kinematics and the expressions become excessively long unless intelligent trigsimplification is possible. Many of my unittests simply will not work because some results I know to be true cannot be achieved with the current state of trigsimp, so this has become a significant limitation for me. What should be the general framework for implementing the 'rules' that are laid out in the Fu paper? There are certainly other rules we could find, either on Wikipedia, Mathworld, or in a engineering/ mathematics reference manual. I have read over how trigsimp() and trigsimp_nonrecursive() are currently implemented, and I think I get the gyst of what the approach is. Can somebody explain what this is doing exactly: for pattern, simp in matchers: res = result.match(pattern) I'm not 100% clear on the use of the .match() method, does somebody have a quick example of use? This should be res = ret.match(pattern). match() takes a wildcard expression and matches it into a dictionary. In the code above, pattern is each of the items in the list ((a*sin(b)**2, a - a*cos(b)**2),(a*tan(b)**2, a*(1/cos(b))**2 - a), (a*cot(b)**2, a*(1/sin(b))**2 - a)) (it runs a for loop). a, b and c are wild cards, to it will try to take the expression result and find what a, b, and c are equal to. For example, consider the first one: a*sin(b)**2. If your ret == 4*x*sin(x**2)**2, then running res = ret.match(a*sin(b)**2) will return the dictionary {a: 4*x, b: x**2}. You can then access a and b from res[a] and res[b]. You should also probably be aware of the exclude option on Wild. If you do a = Wild('a', exclude=[sin(x)]), then a will not match anything with sin(x) in it. Do help(x.matches) for another example. It seems like the flow of trigsimp (in the case of recursive==False and deep==False): 1) call trigsimp_nonrecursive(expr, deep==False), store the result in 'result' 2) do some final pattern matching on 'result', currently this will only simplify a*sin(b)**c/cos(b)**c -- a*tan(b)**c So, should all the rules in Fu et al. be implemented as a tuple of length 2 tuples, similar to the existing matchers tuple? I'm kind of thinking out loud right now and trying to figure out the next step to take ~Luke On May 21, 7:42 am, Akshay Srinivasan akshaysriniva...@gmail.com --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: trigsimp
Thanks. On May 25, 9:02 pm, Aaron S. Meurer asmeu...@gmail.com wrote: You need to use the exclude option I was telling you about. Do, a = Wild('a', exclude=[pi]) and b = Wild('a', exclude=[pi]). and you get e1.match(a*pi + b) {a_: 1, b_: x} b = Wild('b', exclude=[pi]) e2.match(a*pi + b) {b_: -x, a_: 1} e3.match(a*pi + b) {b_: x, a_: -1} e4.match(a*pi + b) {b_: -x, a_: -1} just as you expected. Aaron Meurer On May 25, 2009, at 7:46 PM, Luke wrote: Aaron, Thanks for the clarification. I think I get the idea, but I'm having trouble matching expressions of the following form: a = Wild('a') b = Wild('b') x = Symbol('x') e1 = pi + x e2 = pi - x e3 = -pi + x e4 = -pi - x I would think that for e{1,2,3,4} that I could get the following behavior: e1.match(a*pi + b) {a: 1, b: x} e2.match(a*pi + b) {a: 1, b: -x} e3.match(a*pi + b) {a: -1, b: x} e4.match(a*pi + b) {a: -1, b: -x} But instead, I get: In [61]: e1.match(a*pi + b) Out[61]: ⎧ x ⎫ ⎨a: ─, b: π⎬ ⎩ π ⎭ In [65]: e2.match(a*pi+b) Out[65]: {a: 1, b: -x} In [66]: e3.match(a*pi+b) Out[66]: ⎧ x ⎫ ⎨a: ─, b: -π⎬ ⎩ π ⎭ In [67]: e4.match(a*pi+b) Out[67]: {a: -1, b: -x} The results for e2 and e4 makes sense to me, but I don't understand the behavior for e1 and e3. Is there another simpler approach, or am I missing something fundamental here? Thanks, ~Luke On May 25, 4:07 pm, Aaron S. Meurer asmeu...@gmail.com wrote: On May 25, 2009, at 11:56 AM, Luke wrote: Here is the link for the Maxima trigsimp() code. It was written in 1981, according to the comments!!! http://maxima.cvs.sourceforge.net/viewvc/maxima/maxima/share/trigonom ... I emailed the authors of the Fu et al. paper to see if they would be willing to share their implementation of the algorithm -- maybe we can save ourselves some work this way. I want to start coding for this, because much of the stuff I am doing in PyDy is heavy on kinematics and the expressions become excessively long unless intelligent trigsimplification is possible. Many of my unittests simply will not work because some results I know to be true cannot be achieved with the current state of trigsimp, so this has become a significant limitation for me. What should be the general framework for implementing the 'rules' that are laid out in the Fu paper? There are certainly other rules we could find, either on Wikipedia, Mathworld, or in a engineering/ mathematics reference manual. I have read over how trigsimp() and trigsimp_nonrecursive() are currently implemented, and I think I get the gyst of what the approach is. Can somebody explain what this is doing exactly: for pattern, simp in matchers: res = result.match(pattern) I'm not 100% clear on the use of the .match() method, does somebody have a quick example of use? This should be res = ret.match(pattern). match() takes a wildcard expression and matches it into a dictionary. In the code above, pattern is each of the items in the list ((a*sin(b)**2, a - a*cos(b)**2),(a*tan(b)**2, a*(1/cos(b))**2 - a), (a*cot(b)**2, a*(1/sin(b))**2 - a)) (it runs a for loop). a, b and c are wild cards, to it will try to take the expression result and find what a, b, and c are equal to. For example, consider the first one: a*sin(b)**2. If your ret == 4*x*sin(x**2)**2, then running res = ret.match(a*sin(b)**2) will return the dictionary {a: 4*x, b: x**2}. You can then access a and b from res[a] and res[b]. You should also probably be aware of the exclude option on Wild. If you do a = Wild('a', exclude=[sin(x)]), then a will not match anything with sin(x) in it. Do help(x.matches) for another example. It seems like the flow of trigsimp (in the case of recursive==False and deep==False): 1) call trigsimp_nonrecursive(expr, deep==False), store the result in 'result' 2) do some final pattern matching on 'result', currently this will only simplify a*sin(b)**c/cos(b)**c -- a*tan(b)**c So, should all the rules in Fu et al. be implemented as a tuple of length 2 tuples, similar to the existing matchers tuple? I'm kind of thinking out loud right now and trying to figure out the next step to take ~Luke On May 21, 7:42 am, Akshay Srinivasan akshaysriniva...@gmail.com --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Strange simplification
I get the same behavior on my machine. It seems like a bug to me. Not sure if the bug is in integrate or in simplify, but could you file this in the issues? Thanks, ~Luke On May 26, 12:16 pm, Neal Becker ndbeck...@gmail.com wrote: Out[80]: (-2*s**2*w**2 + w**4)/(s**4 + w**4) In [81]: _.subs(s,2*pi*I*f) Out[81]: (8*pi**2*f**2*w**2 + w**4)/(w**4 + 16*pi**4*f**4) In [82]: simplify(_) Out[82]: (8*pi**2*f**2*w**2 + w**4)/(w**4 + 16*pi**4*f**4) Notice that this integrand should be strictly positive. It also should give a simple closed form, if I'm not mistaken. In [83]: integrate(_,(f,0,oo)) Out[83]: -(w**(-12))**(1/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(1/2)*log(11*(w**(-12))**(1/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(1/2)/(120*pi) + (w**(-12))**(3/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(3/2)/(960*pi*w**2))/(32*pi) - (w**(-12))**(1/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(1/2)*log(oo - 11*(w**(-12))**(1/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(1/2)/(120*pi) - (w**(-12))**(3/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(3/2)/(960*pi*w**2))/(32*pi) - (w**(-12))**(1/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(1/2)*log(11*(w**(-12))**(1/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(1/2)/(120*pi) + (w**(-12))**(3/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(3/2)/(960*pi*w**2))/(32*pi) - (w**(-12))**(1/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(1/2)*log(oo - 11*(w**(-12))**(1/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(1/2)/(120*pi) - (w**(-12))**(3/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(3/2)/(960*pi*w**2))/(32*pi) + (w**(-12))**(1/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(1/2)*log(-11*(w**(-12))**(1/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(1/2)/(120*pi) - (w**(-12))**(3/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(3/2)/(960*pi*w**2))/(32*pi) + (w**(-12))**(1/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(1/2)*log(oo + 11*(w**(-12))**(1/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(1/2)/(120*pi) + (w**(-12))**(3/2)*(-48*I*(w**28)**(1/2) - 64*w**14)**(3/2)/(960*pi*w**2))/(32*pi) + (w**(-12))**(1/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(1/2)*log(-11*(w**(-12))**(1/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(1/2)/(120*pi) - (w**(-12))**(3/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(3/2)/(960*pi*w**2))/(32*pi) + (w**(-12))**(1/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(1/2)*log(oo + 11*(w**(-12))**(1/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(1/2)/(120*pi) + (w**(-12))**(3/2)*(48*I*(w**28)**(1/2) - 64*w**14)**(3/2)/(960*pi*w**2))/(32*pi) In [84]: simplify(_) Out[84]: 0 If the integrand was strickly positive, I don't think it should simplify to 0. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: trigsimp
Aaron, It seems like this only works for Symbol instances, not FunctionClass instances, i.e: from sympy import * x = Function('x') a = Wild('a', exclude=[pi]) b = Wild('b') e = pi/S(2) + x e.match(a*pi + b) Traceback (most recent call last): File stdin, line 1, in module File sympy/core/basic.py, line 1317, in match return pattern.matches(self, {}) File sympy/core/operations.py, line 111, in _matches_commutative if (not p in repl_dict) and (not p in expr): File sympy/core/basic.py, line 1046, in __contains__ if what in x: TypeError: argument of type 'FunctionClass' is not iterable a = WildFunction('a', exclude=[pi]) Traceback (most recent call last): File stdin, line 1, in module File sympy/core/function.py, line 399, in __new__ obj = Function.__new__(cls, name, **assumptions) File sympy/core/multidimensional.py, line 127, in wrapper return f(*args, **kwargs) File sympy/core/cache.py, line 82, in wrapper return func_cache_it_cache[k] TypeError: unhashable type: 'list' a = WildFunction('a', exclude=pi) b = WildFunction('b') e.match(a*pi + b) Traceback (most recent call last): File stdin, line 1, in module File sympy/core/basic.py, line 1317, in match return pattern.matches(self, {}) File sympy/core/operations.py, line 111, in _matches_commutative if (not p in repl_dict) and (not p in expr): File sympy/core/basic.py, line 1046, in __contains__ if what in x: TypeError: argument of type 'FunctionClass' is not iterable a = Wild('a', exclude=[pi]) e.match(a*pi + b) Traceback (most recent call last): File stdin, line 1, in module File sympy/core/basic.py, line 1317, in match return pattern.matches(self, {}) File sympy/core/operations.py, line 111, in _matches_commutative if (not p in repl_dict) and (not p in expr): File sympy/core/basic.py, line 1046, in __contains__ if what in x: TypeError: argument of type 'FunctionClass' is not iterable The reason I see this being a problem is that people might not always be using Symbol instances, they may instead want to use a Function that is implicitly dependent upon one or more other variables (case in point, generalized coordinates in classical mechanics). Ondrej, I'm told you are the only one who understands .match(), can you shed any light on this? Maybe we just need to extend .match() to work with other things besides Symbol? ~Luke On May 26, 9:33 am, Luke hazelnu...@gmail.com wrote: Thanks. On May 25, 9:02 pm, Aaron S. Meurer asmeu...@gmail.com wrote: You need to use the exclude option I was telling you about. Do, a = Wild('a', exclude=[pi]) and b = Wild('a', exclude=[pi]). and you get e1.match(a*pi + b) {a_: 1, b_: x} b = Wild('b', exclude=[pi]) e2.match(a*pi + b) {b_: -x, a_: 1} e3.match(a*pi + b) {b_: x, a_: -1} e4.match(a*pi + b) {b_: -x, a_: -1} just as you expected. Aaron Meurer On May 25, 2009, at 7:46 PM, Luke wrote: Aaron, Thanks for the clarification. I think I get the idea, but I'm having trouble matching expressions of the following form: a = Wild('a') b = Wild('b') x = Symbol('x') e1 = pi + x e2 = pi - x e3 = -pi + x e4 = -pi - x I would think that for e{1,2,3,4} that I could get the following behavior: e1.match(a*pi + b) {a: 1, b: x} e2.match(a*pi + b) {a: 1, b: -x} e3.match(a*pi + b) {a: -1, b: x} e4.match(a*pi + b) {a: -1, b: -x} But instead, I get: In [61]: e1.match(a*pi + b) Out[61]: ⎧ x ⎫ ⎨a: ─, b: π⎬ ⎩ π ⎭ In [65]: e2.match(a*pi+b) Out[65]: {a: 1, b: -x} In [66]: e3.match(a*pi+b) Out[66]: ⎧ x ⎫ ⎨a: ─, b: -π⎬ ⎩ π ⎭ In [67]: e4.match(a*pi+b) Out[67]: {a: -1, b: -x} The results for e2 and e4 makes sense to me, but I don't understand the behavior for e1 and e3. Is there another simpler approach, or am I missing something fundamental here? Thanks, ~Luke On May 25, 4:07 pm, Aaron S. Meurer asmeu...@gmail.com wrote: On May 25, 2009, at 11:56 AM, Luke wrote: Here is the link for the Maxima trigsimp() code. It was written in 1981, according to the comments!!! http://maxima.cvs.sourceforge.net/viewvc/maxima/maxima/share/trigonom ... I emailed the authors of the Fu et al. paper to see if they would be willing to share their implementation of the algorithm -- maybe we can save ourselves some work this way. I want to start coding for this, because much of the stuff I am doing in PyDy is heavy on kinematics and the expressions become excessively long unless intelligent trigsimplification is possible. Many of my unittests simply will not work because some results I know to be true cannot be achieved with the current state of trigsimp, so this has become a significant limitation for me. What should be the general framework for implementing the 'rules' that are laid out
[sympy] Re: Strange simplification
I'm using the latest pull from git://git.sympy.org/sympy.git, and this is the response I get: In [1]: from sympy import * In [2]: f, w = symbols('fw') In [3]: s = 2*pi*I*f In [4]: ia = (-2*s**2*w**2 + w**4)/(s**4 + w**4) In [5]: simplify(integrate(ia, (f, 0, infty))) --- NameError Traceback (most recent call last) /home/luke/lib/python/sympy/ipython console in module() NameError: name 'infty' is not defined In [6]: simplify(integrate(ia, (f, 0, oo))) Out[6]: 0 In [10]: oo.__class__ Out[10]: class 'sympy.core.numbers.Infinity' I'm guessing 'infty' is something you've defined on your own machine for convenience. What exactly does it mean to be using the 'trunk'? Thanks, ~Luke On May 26, 4:04 pm, Neal Becker ndbeck...@gmail.com wrote: On Tuesday 26 May 2009, Robert Kern wrote: On Tue, May 26, 2009 at 17:04, Neal Becker ndbeck...@gmail.com wrote: On Tuesday 26 May 2009, Robert Kern wrote: On Tue, May 26, 2009 at 15:08, Luke hazelnu...@gmail.com wrote: I get the same behavior on my machine. Hmm, I don't. I'm using 0.6.4, are you using something newer perhaps? Yes, the trunk. Here's what maxima says: (%o33) (w^4+8*%pi^2*f^2*w^2)/(w^4+16*%pi^4*f^4) (%i35) integrate(%o33,f,0,inf); Is w positive or negative? positive; (%o35) (3*w)/(4*sqrt(2)) --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Strange simplification
Ok, so there is some sort of bug. Here is what Matlab (maple) 2008a gives: int((8*pi^2*f^2*w^2+w^4)/(16*pi^4*f^4+w^4), f, 0, inf) ans = PIECEWISE([NaN, And(0 (w^4)^(1/4)*2^(1/2)*pi+pi*(-2*csgn(w^2)*w^2)^ (1/2),(w^4)^(1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2)*w^2)^(1/2) 0,(w^4)^ (1/4)*2^(1/2)*pi+pi*(-2*csgn(w^2)*w^2)^(1/2) 0,0 (w^4)^(1/4)*2^ (1/2)*pi-pi*(-2*csgn(w^2)*w^2)^(1/2))],[NaN, And(0 (w^4)^(1/4)*2^ (1/2)*pi+pi*(-2*csgn(w^2)*w^2)^(1/2),(w^4)^(1/4)*2^(1/2)*pi+pi*(-2*csgn (w^2)*w^2)^(1/2) 0,0 (w^4)^(1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2)*w^2)^ (1/2))],[NaN, And((w^4)^(1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2)*w^2)^(1/2) 0,(w^4)^(1/4)*2^(1/2)*pi+pi*(-2*csgn(w^2)*w^2)^(1/2) 0,0 (w^4)^ (1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2)*w^2)^(1/2))],[NaN, And((w^4)^(1/4)*2^ (1/2)*pi+pi*(-2*csgn(w^2)*w^2)^(1/2) 0,0 (w^4)^(1/4)*2^(1/2)*pi-pi* (-2*csgn(w^2)*w^2)^(1/2))],[NaN, And(0 (w^4)^(1/4)*2^(1/2)*pi+pi* (-2*csgn(w^2)*w^2)^(1/2),(w^4)^(1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2)*w^2)^ (1/2) 0,(w^4)^(1/4)*2^(1/2)*pi+pi*(-2*csgn(w^2)*w^2)^(1/2) 0)], [NaN, And(0 (w^4)^(1/4)*2^(1/2)*pi+pi*(-2*csgn(w^2)*w^2)^(1/2),(w^4)^ (1/4)*2^(1/2)*pi+pi*(-2*csgn(w^2)*w^2)^(1/2) 0)],[NaN, And((w^4)^ (1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2)*w^2)^(1/2) 0,(w^4)^(1/4)*2^(1/2)*pi +pi*(-2*csgn(w^2)*w^2)^(1/2) 0)],[NaN, (w^4)^(1/4)*2^(1/2)*pi+pi* (-2*csgn(w^2)*w^2)^(1/2) 0],[NaN, And(0 (w^4)^(1/4)*2^(1/2)*pi+pi* (-2*csgn(w^2)*w^2)^(1/2),(w^4)^(1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2)*w^2)^ (1/2) 0,0 (w^4)^(1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2)*w^2)^(1/2))], [NaN, And(0 (w^4)^(1/4)*2^(1/2)*pi+pi*(-2*csgn(w^2)*w^2)^(1/2),0 (w^4)^(1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2)*w^2)^(1/2))],[NaN, And((w^4)^ (1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2)*w^2)^(1/2) 0,0 (w^4)^(1/4)*2^ (1/2)*pi-pi*(-2*csgn(w^2)*w^2)^(1/2))],[NaN, 0 (w^4)^(1/4)*2^(1/2) *pi-pi*(-2*csgn(w^2)*w^2)^(1/2)],[NaN, And(0 (w^4)^(1/4)*2^(1/2)*pi +pi*(-2*csgn(w^2)*w^2)^(1/2),(w^4)^(1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2) *w^2)^(1/2) 0)],[NaN, 0 (w^4)^(1/4)*2^(1/2)*pi+pi*(-2*csgn(w^2) *w^2)^(1/2)],[NaN, (w^4)^(1/4)*2^(1/2)*pi-pi*(-2*csgn(w^2)*w^2)^(1/2) 0],[1/8*2^(1/2)*w^2*(2+csgn(w^2))/(w^4)^(1/4), otherwise]) And here is what Mathematica's web integral gives (with 'x' in place of 'f'): Integrate[(8*Pi^2*x^2*w^2 + w^4)/(16*Pi^4*x^4 + w^4), x] == (w*(-6*ArcTan[1 - (2*Sqrt[2]*Pi*x)/w] + 6*ArcTan[1 + (2*Sqrt[2]*Pi*x)/ w] + Log[-w^2 + 2*Sqrt[2]*Pi*w*x - 4*Pi^2*x^2] - Log[w^2 + 2*Sqrt[2] *Pi*w*x + 4*Pi^2*x^2]))/ (8*Sqrt[2]*Pi) They don't let you do definite integrals there. And the computation timed out on Wolfram Alpha. Anybody actually *know* what this integral should be? ~Luke On May 26, 5:25 pm, Robert Kern robert.k...@gmail.com wrote: On Tue, May 26, 2009 at 19:22, Luke hazelnu...@gmail.com wrote: I'm using the latest pull from git://git.sympy.org/sympy.git, and this is the response I get: In [1]: from sympy import * In [2]: f, w = symbols('fw') In [3]: s = 2*pi*I*f In [4]: ia = (-2*s**2*w**2 + w**4)/(s**4 + w**4) In [5]: simplify(integrate(ia, (f, 0, infty))) --- NameError Traceback (most recent call last) /home/luke/lib/python/sympy/ipython console in module() NameError: name 'infty' is not defined In [6]: simplify(integrate(ia, (f, 0, oo))) Out[6]: 0 In [10]: oo.__class__ Out[10]: class 'sympy.core.numbers.Infinity' I'm guessing 'infty' is something you've defined on your own machine for convenience. No, I'm just dumb. That's from numpy. In [3]: from sympy import * In [4]: %sym -r f w Adding real variables: f w In [5]: s = 2*pi*I*f In [6]: ia = (-2*s**2*w**2 + w**4)/(s**4 + w**4) In [7]: simplify(powsimp(integrate(ia, (f, 0, oo Out[7]: 0 What exactly does it mean to be using the 'trunk'? the latest pull from git://git.sympy.org/sympy.git -- Robert Kern I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth. -- Umberto Eco --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Function vs. Symbol
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) 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'' 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. 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 -~--~~~~--~~--~--~---
[sympy] Re: Function vs. Symbol
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
[sympy] Re: Function vs. Symbol
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
[sympy] Re: Function vs. Symbol
I like the first way for the fact that it just has 'x' instead of 'x (t)', but I like the second way because it is simpler and easier to implement. Is there a way to redefined how x = Symbol('x')(t) would print? I guess subclassing would be one option, take care of it there, and then use the second approach for the auto substitution stuff. ~Luke On May 27, 4:49 pm, Ondrej Certik ond...@certik.cz wrote: We discuss this on IRC with Luke and Fabian. Now I understand -- Luke wants the result of differentiating not to be instances of Derivative() class, but rather some other symbols, e.g it should substitute them for symbols at the end. One way to do it is to subclass the Symbol() class that does the right thing, proof of concept is attached. I had to comment out some lines in the Function class that were returning 0 immediately if the expression didn't depend on t (the symbol we are differentiating with respect to). After applying the patch, you get: $ python t.py x'*cos(x) Another approach may be to create some decorator around Basic.diff() or even create a new function diff, along these lines: from sympy import * t = Symbol(t) x = Function(x)(t) print current way:, diff(sin(x), t) x_diff = Symbol(x') derivs_dict = {x.diff(t): x_diff} def diff(a, b): return a.diff(b).subs(derivs_dict) print new way:, diff(sin(x), t) - This prints: current way: D(x(t), t)*cos(x(t)) new way: x'*cos(x(t)) Luke, isn't the second approach cleaner? No need to create new classes, etc. Ondrej 0001-Proof-of-concept.patch 1KViewDownload --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Function vs. Symbol
I'm a little unclear about a few things with regards to how to properly subclass StrPrinter. On May 27, 5:08 pm, Ondrej Certik ond...@certik.cz wrote: On Wed, May 27, 2009 at 6:05 PM, Luke hazelnu...@gmail.com wrote: I like the first way for the fact that it just has 'x' instead of 'x (t)', but I like the second way because it is simpler and easier to implement. The first way needs patching sympy, exactly because it things that x is just x and thus if the expression doesn't depend on t, it return 0 immediately. Is there a way to redefined how x = Symbol('x')(t) would print? I guess subclassing would be one option, take care of it there, and then use the second approach for the auto substitution stuff. In fact, just subclassStrPrinterand override _print_Symbol() or _print_Function(). You have your own printer in pydy anyway, so just add there one more method. Ondrej --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Function vs. Symbol
Sorry, I accidentally clicked send before I had finished. A few questions: So here is part of my PyDyPrinter class: class PyDyPrinter(StrPrinter): printmethod = _pydystr_ ... def _print_sin(self, e): name = str(e.args[0]) if name[0] == q: index = name[1] return s%s % index else: return str(e) ... And here is a convenience function. def print_pydy(e): pp = PyDyPrinter() return pp.doprint(e) Question 1) What does printmethod do / control? Does this control what the name of my print methods in each of my classes needs to be? Question 2) Do I need to have _sympystr_ defined in the classes I wish to customize the printing for? Or should it be: _pydystr_, since that is what is printmethod is defined to be. Question 3) Do I put the printing code for my class into myclassname._sympystr_ (or ._pydystr_), or does it go inside my subclass of StrPrinter, PyDyPrinter? Question 4) If the printing code goes in my subclass of StrPrinter (in my case PyDyPrinter), then do I just put in the _sympystr_ method of my class something like: return print_pydy(self)? I've read the printing documentation, and the wiki, and the mailing list, and I'm still not clear how the Printing system works. In some examples I have seen there is no printingmethod variable set, and I'm not clear what it does exactly. Maybe somebody could post a complete example, that would show their subclassing of StrPrinter, as well as the code inside their cusstom class, and any other relevant code as a complete example of how to properly customize the printing? Thanks, ~Luke On May 28, 3:23 pm, Luke hazelnu...@gmail.com wrote: I'm a little unclear about a few things with regards to how to properly subclassStrPrinter. On May 27, 5:08 pm, Ondrej Certik ond...@certik.cz wrote: On Wed, May 27, 2009 at 6:05 PM, Luke hazelnu...@gmail.com wrote: I like the first way for the fact that it just has 'x' instead of 'x (t)', but I like the second way because it is simpler and easier to implement. The first way needs patching sympy, exactly because it things that x is just x and thus if the expression doesn't depend on t, it return 0 immediately. Is there a way to redefined how x = Symbol('x')(t) would print? I guess subclassing would be one option, take care of it there, and then use the second approach for the auto substitution stuff. In fact, just subclassStrPrinterand override _print_Symbol() or _print_Function(). You have your own printer in pydy anyway, so just add there one more method. Ondrej --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Function vs. Symbol
One thing I forgot to ask: I'm getting weird error messages when I try to use the xsym(*) character. I had put it in my _sympystr_ method of one of my classes, and I keep getting the following error: File t.py, line 53, in module print 'print A[1]', Vector(sin(q1)*A[1] + cos(q1)*A[1]) File /var/lib/python-support/python2.6/sympy/core/basic.py, line 689, in __str__ return StrPrinter.doprint(self) File /var/lib/python-support/python2.6/sympy/printing/printer.py, line 118, in doprint return self._str(self._print(expr)) File /var/lib/python-support/python2.6/sympy/printing/printer.py, line 132, in _print res = getattr(expr, self.printmethod)() File /home/luke/lib/python/pydy/pydy.py, line 266, in _sympystr_ xsym('*') + k._sympystr_() UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 11: ordinal not in range(128) when I go to ipython and do: print xsym('*') it works just fine, even if I concatenate it with some other non unicode things. What do I do to fix the above error? Thanks, ~Luke On May 28, 3:33 pm, Luke hazelnu...@gmail.com wrote: Sorry, I accidentally clicked send before I had finished. A few questions: So here is part of my PyDyPrinter class: class PyDyPrinter(StrPrinter): printmethod = _pydystr_ ... def _print_sin(self, e): name = str(e.args[0]) if name[0] == q: index = name[1] return s%s % index else: return str(e) ... And here is a convenience function. def print_pydy(e): pp = PyDyPrinter() return pp.doprint(e) Question 1) What does printmethod do / control? Does this control what the name of my print methods in each of my classes needs to be? Question 2) Do I need to have _sympystr_ defined in the classes I wish to customize the printing for? Or should it be: _pydystr_, since that is what is printmethod is defined to be. Question 3) Do I put the printing code for my class into myclassname._sympystr_ (or ._pydystr_), or does it go inside my subclass ofStrPrinter, PyDyPrinter? Question 4) If the printing code goes in my subclass ofStrPrinter (in my case PyDyPrinter), then do I just put in the _sympystr_ method of my class something like: return print_pydy(self)? I've read the printing documentation, and the wiki, and the mailing list, and I'm still not clear how the Printing system works. In some examples I have seen there is no printingmethod variable set, and I'm not clear what it does exactly. Maybe somebody could post a complete example, that would show their subclassing ofStrPrinter, as well as the code inside their cusstom class, and any other relevant code as a complete example of how to properly customize the printing? Thanks, ~Luke On May 28, 3:23 pm, Luke hazelnu...@gmail.com wrote: I'm a little unclear about a few things with regards to how to properly subclassStrPrinter. On May 27, 5:08 pm, Ondrej Certik ond...@certik.cz wrote: On Wed, May 27, 2009 at 6:05 PM, Luke hazelnu...@gmail.com wrote: I like the first way for the fact that it just has 'x' instead of 'x (t)', but I like the second way because it is simpler and easier to implement. The first way needs patching sympy, exactly because it things that x is just x and thus if the expression doesn't depend on t, it return 0 immediately. Is there a way to redefined how x = Symbol('x')(t) would print? I guess subclassing would be one option, take care of it there, and then use the second approach for the auto substitution stuff. In fact, just subclassStrPrinterand override _print_Symbol() or _print_Function(). You have your own printer in pydy anyway, so just add there one more method. Ondrej --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Function vs. Symbol
Sebastian, Thanks for the reply. I have read printer.py, str.py, and repr.py, and am still confused as to how to properly customize Sympy's printing system. Suppose I want to put the _print_myclass(self, e) code into my subclass of StrPrinter. What methods should I keep in the classes themselves? Anything? _sympystr_, _repr_, or _str_, or none of them? Finally, suppose I do put all the printing code for each of my classes into my sublcass of StrPrinter. Will inst = MyClass() print inst automatically look into my subclass of StrPrinter for a method called _print_MyClass()? Or do I need to define something like: def print_pydy(e): pp = PyDyPrinter() pp.doprint(e) And then call: print_pydy(inst) ? I don't feel the use of the printing system is clearly conveyed in the documentation. More explicit examples would be helpful. I'm happy to do this once I get to the point of understand how it works, but I'm not there yet. Thanks, ~Luke On May 28, 4:00 pm, Sebastian basti...@gmail.com wrote: Hi Luke, I think all your questions are answered in the docstring of printing/printer.py. There it tells you in which order it is tried to print an object. 1) Let the object print itself if it has the method defined as printmethod. 2) Use the method defined in the Printer if available. 3) Use some fallback printer. Luke wrote: Sorry, I accidentally clicked send before I had finished. A few questions: So here is part of my PyDyPrinter class: class PyDyPrinter(StrPrinter): printmethod = _pydystr_ ... def _print_sin(self, e): name = str(e.args[0]) if name[0] == q: index = name[1] return s%s % index else: return str(e) ... And here is a convenience function. def print_pydy(e): pp = PyDyPrinter() return pp.doprint(e) Question 1) What does printmethod do / control? Does this control what the name of my print methods in each of my classes needs to be? Is explained above. Question 2) Do I need to have _sympystr_ defined in the classes I wish to customize the printing for? Or should it be: _pydystr_, since that is what is printmethod is defined to be. If all your classes are handled in your own printer you don't need any additional methods. Question 3) Do I put the printing code for my class into myclassname._sympystr_ (or ._pydystr_), or does it go inside my subclass of StrPrinter, PyDyPrinter? That's your choice, use what you like more. Question 4) If the printing code goes in my subclass of StrPrinter (in my case PyDyPrinter), then do I just put in the _sympystr_ method of my class something like: return print_pydy(self)? Okay this influences question3. If you have one (or only a few) common base class, you can just overwrite the __str__ and __repr__ methods there. For an example look into core/basic.py into the Base class. Otherwise it may be better to just write the printing code into _sympystr_ methods in every class. I've read the printing documentation, and the wiki, and the mailing list, and I'm still not clear how the Printing system works. In some examples I have seen there is no printingmethod variable set, and I'm not clear what it does exactly. Maybe somebody could post a complete example, that would show their subclassing of StrPrinter, as well as the code inside their cusstom class, and any other relevant code as a complete example of how to properly customize the printing? Just go through the printers implemented in the printing directory. Especially printer.py is useful and for some full implementation examples you can go through str.py and repr.py. I hope this helps, Sebastian --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Function vs. Symbol
Also, how can I get the xsym(*) character to display correctly? When I do print xsym(*) it works fine, i.e., I get the small dot that looks nice. But in my printing methods where I build the string for the outputs, and I do something like: s += print_pydy(e.dict[k]) + xsym('*') + k.__str__() It gives me an error because of the xsym('*') part: s += print_pydy(e.dict[k]) + xsym('*') + k.__str__() UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 11: ordinal not in range(128) Any suggestions on how to fix this? Thanks, ~Luke On May 28, 4:35 pm, Luke hazelnu...@gmail.com wrote: Sebastian, Thanks for the reply. I have read printer.py, str.py, and repr.py, and am still confused as to how to properly customize Sympy's printing system. Suppose I want to put the _print_myclass(self, e) code into my subclass of StrPrinter. What methods should I keep in the classes themselves? Anything? _sympystr_, _repr_, or _str_, or none of them? Finally, suppose I do put all the printing code for each of my classes into my sublcass of StrPrinter. Will inst = MyClass() print inst automatically look into my subclass of StrPrinter for a method called _print_MyClass()? Or do I need to define something like: def print_pydy(e): pp = PyDyPrinter() pp.doprint(e) And then call: print_pydy(inst) ? I don't feel the use of the printing system is clearly conveyed in the documentation. More explicit examples would be helpful. I'm happy to do this once I get to the point of understand how it works, but I'm not there yet. Thanks, ~Luke On May 28, 4:00 pm, Sebastian basti...@gmail.com wrote: Hi Luke, I think all your questions are answered in the docstring of printing/printer.py. There it tells you in which order it is tried to print an object. 1) Let the object print itself if it has the method defined as printmethod. 2) Use the method defined in the Printer if available. 3) Use some fallback printer. Luke wrote: Sorry, I accidentally clicked send before I had finished. A few questions: So here is part of my PyDyPrinter class: class PyDyPrinter(StrPrinter): printmethod = _pydystr_ ... def _print_sin(self, e): name = str(e.args[0]) if name[0] == q: index = name[1] return s%s % index else: return str(e) ... And here is a convenience function. def print_pydy(e): pp = PyDyPrinter() return pp.doprint(e) Question 1) What does printmethod do / control? Does this control what the name of my print methods in each of my classes needs to be? Is explained above. Question 2) Do I need to have _sympystr_ defined in the classes I wish to customize the printing for? Or should it be: _pydystr_, since that is what is printmethod is defined to be. If all your classes are handled in your own printer you don't need any additional methods. Question 3) Do I put the printing code for my class into myclassname._sympystr_ (or ._pydystr_), or does it go inside my subclass of StrPrinter, PyDyPrinter? That's your choice, use what you like more. Question 4) If the printing code goes in my subclass of StrPrinter (in my case PyDyPrinter), then do I just put in the _sympystr_ method of my class something like: return print_pydy(self)? Okay this influences question3. If you have one (or only a few) common base class, you can just overwrite the __str__ and __repr__ methods there. For an example look into core/basic.py into the Base class. Otherwise it may be better to just write the printing code into _sympystr_ methods in every class. I've read the printing documentation, and the wiki, and the mailing list, and I'm still not clear how the Printing system works. In some examples I have seen there is no printingmethod variable set, and I'm not clear what it does exactly. Maybe somebody could post a complete example, that would show their subclassing of StrPrinter, as well as the code inside their cusstom class, and any other relevant code as a complete example of how to properly customize the printing? Just go through the printers implemented in the printing directory. Especially printer.py is useful and for some full implementation examples you can go through str.py and repr.py. I hope this helps, Sebastian --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Function vs. Symbol
Well, print xsym(*) works, i.e. it prings a nice small *, i.e., when you do x*y in isympy, this is the default behavior. but when I put xsym(*) into a string that is used in the _print_Vector(self, e) function in my subclass of StrPrinter, it doesn't print, instead it generates the UnicodeDecodeError. I know my terminal is unicode enabled, the error is something else, I just don't know how to fix it. ~Luke On May 28, 6:34 pm, Sebastian basti...@gmail.com wrote: Luke wrote: Ok, thanks. Any ideas regarding the xsym(*) error? Not really, I don't even know where this xsym comes from and what it does, but maybe you are printing unicode to a non-unicode terminal? Sebastian --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] UnicodeDecodeError when using xsym(*)
I subclassed StrPrinter to define my own printing of some of my classes, and I can't seem to make xsym(*) work. I keep getting a UnicodeDecodeError. Here is a code snippet of what I'm doing: else: if i == 0: if isinstance(e.dict[k], Add): s += '(' + print_pydy(e.dict[k])+\ ')' + xsym('*') + k.__str__() else: s += print_pydy(e.dict[k]) + '*' + k.__str__() i += 1 else: And here is the error I'm getting: File t.py, line 56, in module print 'print A[1]', Vector((1+sin(q1))*A[1]) File /home/luke/lib/python/pydy/pydy.py, line 254, in __str__ return print_pydy(self) File /home/luke/lib/python/pydy/pydy.py, line 1157, in print_pydy return pp.doprint(e) File /var/lib/python-support/python2.6/sympy/printing/printer.py, line 118, in doprint return self._str(self._print(expr)) File /var/lib/python-support/python2.6/sympy/printing/printer.py, line 143, in _print res = getattr(self, printmethod)(expr, *args) File /home/luke/lib/python/pydy/pydy.py, line 1102, in _print_Vector unicode(')') + xsym('*') + unicode(k.__str__()) UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 11: ordinal not in range(128) Removing the xsym('*') gets ride of the error, but then I don't get the small dot. I tried calling unicode() on each of the other terms in the concatenation, but that didn't fix it. I have search a lot online and have found many pages acknowledging this error but none discussing how to fix it. Does anybody know what I need to do in order to take care of this? Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] cos(x - y) == cos(y - x)
It is late, but it seems to me that [2] should evaluate true, for any x and y, not just real x and y. Should also work for functions. In [1]: cos(x - 1) == cos(1 - x) Out[1]: True In [2]: cos(x - y) == cos(y - x) Out[2]: False In [3]: x = Symbol('x', real=True) In [4]: y = Symbol('y', real=True) In [5]: cos(x - y) == cos(y - x) Out[5]: True In [10]: x = Function('x')(z) In [11]: y = Function('y')(z) In [12]: cos(x - y) == cos(y - x) Out[12]: False In [13]: Fabian, are your assumptions going to have an is_even_function and is_odd_function attributes for Function? ~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 -~--~~~~--~~--~--~---
[sympy] Re: cos(x - y) == cos(y - x)
Aaron was correct, it was late at night (or early in the morning). Ondrej, can you elaborate on what you mean by canonical form? Do you mean something should be done in cos.canonize? Currently canonize just call cls.eval(arg). I'm unclear why it works for 1 and x, i.e. cos(1-x)==cos(x-1), but not with x and y? It seems like there must be some logic that has been coded in a way that only works with specific types, when it really should work for any reasonable type. Is this something that would be fixed in cos.eval? Or should the fix go elsewhere? In cos.eval there is some code that is supposed to take care of normalizing cos(-x-y) to cos(x+y), but obviously the logic in there isn't catching this. ~Luke On May 29, 9:06 am, Aaron S. Meurer asmeu...@gmail.com wrote: On May 29, 2009, at 9:25 AM, Ondrej Certik wrote: On Fri, May 29, 2009 at 2:24 AM, Luke hazelnu...@gmail.com wrote: It is late, but it seems to me that [2] should evaluate true, for any Why is it late? I think because he sent it at 2:30 in the morning. Aaron Meurer --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Motion equation generation script sharing
Alan, I've browsed this text a little, but to be honest, I was unable to see the direct advantage of such an approach, at least for the type of work I'm involved with. I'm willing to trust that the mathematics are cleaner and more complete, but I'm curious what the advantage is in the end. Do you know specific types of systems that really benefit from this approach? I am currently studying the rolling torus and the Whipple bicycle model, and I would be curious to see how the GA approach would compare to a more classical approach. Have you seen the GA approach applied to classical examples like the rolling disc or torus, or any other nonholonomic systetms? Also, I have another text in electronic format called Geometric Algebra with Applications in Engineering, by Christian Perwass. Are you familiar with it? If so, do you recommend it as an alternative to the book by Doran and Lasenby? Or is Doran and Lasenby available electronically? Thanks, ~Luke On Jun 1, 2:25 pm, Alan Bromborsky abro...@verizon.net wrote: Luke wrote: If you are familiar with Autolev, then you are probably familiar with some of the behavior that makes it very convenient and easy to derive equations of motion in. You might also be familiar with some of its limitations. One of the main goals of PyDy is to replicate (in a more Pythonic way) the features of Autolev, and improve upon its deficiencies. One of the main things I have implemented so far that is very useful is the 12 Euler and 12 Space fixed rotation conventions, into a convenient framework for working with vector expressions without having to deal with the rotation matrices / transformations explicitly. This makes many things much simpler when defining your problem. I would love to hear your input on feature requests or overall design approaches for PyDy. Here is all the group information: *http://groups.google.com/group/pydy * p...@googlegroups.com *http://dlpeterson.com/blog I have classes for ReferenceFrame and am working on the Point class, my idea is to implement methods for each of these classes that can assign inertia and/or torque (ReferenceFrame) and mass and/or force (Point), which, combined with the kinematics of the problem, will allow for Kane's method to be utilized and the equations of motion generated in a very algorithmic and systematic fashion. There are already a few example problems up there, but if you think any others, I'd be happy to put them up -- the more the better. ~Luke On May 29, 9:56 pm, 2006.uchida 2006.uch...@gmail.com wrote: Thank you for your response. I first knew Autolev. I took a look at one of the sample test codes of Pydy named simplependulum.py and didn't look into the details but it appears that it allows us to obtain motion equations and simulations by only connecting the class instances that represent rigid bodies, sorry if I misunderstand. It is a cool idea! We no longer need to transform the coordinates nor to calculate the absolute positions of the rigid objects one by one, which is a hard part for me in using Kane's method. Moreover, it also provides the dynamics simulations as well as the equations. We can do a simulation without thinking about programming for the integration of the simulation. I think it would be good to design the interface using a class that represent a kind of rigid bodies, links, forces, or any other extentions with understandable, short names and to make the setup for the usage easy like all that we have to do to use the feature is only to make up the relations of the class instances. Anyway, it would already make our life easier. On 5月24日, 午前6:06, Luke hazelnu...@gmail.com wrote: This is cool, it is good to see other people who are familiar with Kane's method, there aren't many of us :) Are you familiar with Autolev? With PyDy, I am working to achieve some of the same behavior as Autolev, but make it even better, and have a lot more features. I'd love to hear your input on design choices for PyDy if you have the time. Right now I'm working on extending it to allow for the 12 different Euler angles, and the 12 different space fixed angles, Euler parameters, Rodrigues parameters, and axis/angle rotations. The major work to take care of kinematics automatically is in place, but there is definitely more to do in regards to how to deal with constraints, definitions of generalized speeds, etc... What sort of systems do you use Kane's method to study? My own area of research is two wheeled vehicle (bicycle/motorcycle) dynamics and control. ~Luke On May 23, 6:06 am, 2006.uchida 2006.uch...@gmail.com wrote: I made a small script in MuPAD few years ago but I had to say goodbye to MuPAD last November, so I found Sympy and have translated it into Sympy now. I want to share it and I'm happy if I get some comments. What I made is the small
[sympy] Re: .is_Number .is_number and .is_NumberSymbol attributes
Fabian, I'm working on the eval methods of the trig functions. There is some inconsistent behavior here with regard to checking if the argument of the function 1) .is_Number and 2) .is_number. For example, sin only has: if arg.is_Number: ... but for example, asin has: if arg.is_Number: ... if arg.is_number You mentioned that the lower case version would be gotten rid of. I would like to write the trig stuff in a way that will work with your assumptions with minimal effort, so should I rewrite all this so that it only uses the arg.is_Number if statement? If so, things like tan (pi/2), won't get screened because currently (pi/2).is_Number==False, but (pi/2).is_number==True. Or should I keep both sets of if statements? I want to make all the trig functions have consistent behavior, so I just need some input on how this should be designed. Thanks, ~Luke On May 25, 9:15 pm, Ondrej Certik ond...@certik.cz wrote: On Mon, May 25, 2009 at 3:25 PM, Fabian Pedregosa fab...@fseoane.net wrote: Luke wrote: Ok, that makes more sense now. Thanks for the clarification. ~Luke On May 25, 1:05 pm, Abderrahim Kitouni a.kito...@gmail.com wrote: On Mon, 25 May 2009 12:48:09 -0700 (PDT)Luke hazelnu...@gmail.com wrote: 1) Why are there both 'is_Number' and a 'is_number' methods, and why do they return different results? is_number== True means that this is a number (in the mathematical sense). is_Number== True means that this is a Number (or subclass) instance. same here, (i.e. an instance of NumberSymbol), generally is_SomeThing means an instance of SomeThing, ans is_something means 'something' in the mathematical sense. 2) It seems to me that if something is NumberSymbol, it should also be a Number (or number), but this isn't how pi currently is. pi.is_numberreturns True. Hopefully the .is_* with lowercase will be removed when the new assumption system is merged. That'd be really awesome. Ondrej --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Complex Infinity
Ondrej and I have had some discussion about what the trigonometric functions tan, cot, sec, csc should return at singular points. It seems there are a couple of options: 1) Return S.ComplexInfinity for things like tan(pi/2), tan(-pi/2), tanh(pi/2*I), tanh(-pi/2*I), etc. 2) Raise an exception of some sort. Mathematica returns ComplexInfinity for all the examples mentioned in 1) above. What do people think about this? I'd like to see what people think would be the right choice. An interesting subtlety of this is that in sympy, currently things like S(1)/S(0) return oo (Infinity). By this rationale, tan(pi/2) = sin(pi/2)/cos(pi/2) = 1/0 = oo (Infinity), but this doesn't seem the right approach. If an exception should be raised, what kind? ZeroDivisionError? PoleError (not sure what this really is, but Ondrej suggested it)? Whatever the consensus, I just want to make the trig functions all consistent. Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Re: Complex Infinity
Is there a reason it returns complex infinity versus just infinity? Does it have to do with the assumptions about the variables? Does anybody know an example where Mathematica returns just regular infinity? ~Luke On Jun 23, 10:23 am, Ondrej Certik ond...@certik.cz wrote: 2009/6/23 Roberto Nobrega rwnobr...@gmail.com: In [2]: S(1)/0 Out[2]: ∞ Btw, so does wolframalpha: http://www.wolframalpha.com/input/?i=1%2F0 In fact it returns ComplexInfinity for 1/0, and not Infinity as SymPy currently does. Yes, I forgot to mention that. So to get some conclusion, I suggest we go the 3) way return ComplexInfinity for everything and emit warnings, that are off by default. Ondrej --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Complex Infinity
Here is the link to the Wolfram Documentation for ComplexInfinity: http://reference.wolfram.com/mathematica/ref/ComplexInfinity.html Their one line documentation is: represents a quantity with infinite magnitude, but undetermined complex phase. Everything I've tried in Wolfram returns ComplexInfinity, but I'm still not understanding why this behavior is more desirable than regular infinity. I'm fine with implementing it this way, but it would be nice to understand why this way is more correct or general, if indeed it is. Thanks, ~Luke On Jun 24, 8:27 am, Luke hazelnu...@gmail.com wrote: Is there a reason it returns complex infinity versus just infinity? Does it have to do with the assumptions about the variables? Does anybody know an example where Mathematica returns just regular infinity? ~Luke On Jun 23, 10:23 am, Ondrej Certik ond...@certik.cz wrote: 2009/6/23 Roberto Nobrega rwnobr...@gmail.com: In [2]: S(1)/0 Out[2]: ∞ Btw, so does wolframalpha: http://www.wolframalpha.com/input/?i=1%2F0 In fact it returns ComplexInfinity for 1/0, and not Infinity as SymPy currently does. Yes, I forgot to mention that. So to get some conclusion, I suggest we go the 3) way return ComplexInfinity for everything and emit warnings, that are off by default. Ondrej --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] How to properly subclass the pretty printer
I'm trying to subclass the StrPrinter and PrettyPrinter so that I can customize the display of some classes I have created for PyDy. I have had success with getting StrPrinter, but I found it to have some weird unicode issues, so I am using plain old strings for my sublcass of StrPrinter, and would like to reserve all unicode stuff for the PrettyPrinter. The way I am subclassing StrPrinter is as follows: 1) My PyDy classes are subclassed from Basic. I override the __str__() method of each of my PyDy classes to look like: def __str__(self): return pydy_str(self) where pydy_str(self) looks like: def pydy_str(e): p = PyDyStrPrinter() return p.doprint(e) 2) I subclass StrPrinter, and add methods entitled _print_MyPyDyClass, as follows: def _print_UnitVector(self, e): These _print_*** methods return a string of how I want each class to be displayed. Nowhere in any of my classes, or in my subclassing of StrPrinter, do I have printmethod defined. Everything above works just fine. The problem is when I try the same approach with subclassing PrettyPrinter. I created class methods entitled _sympypretty_() for each of my classes, then define a pydy_pretty() function, and then subclass PrettyPrinter, analogously to my approach above. It doesn't work. Specifically, I get infinite recursion runtime errors. I tried adding the printmethod class attribute to my PyDyPrettyPrinter, but it didn't make any difference, I still get infinite recursion errors. I have spent many hours on this and I am sure it is probably a very simple fix and that I am just not using things correctly. Does anybody have any recommendations on how this should be done properly? Ideally, some example code would be the best that way there would be no confusion as to how this should be done. It seems to me that the approach that should be taken to subclassing either StrPrinter or PrettyPrinter should be conceptually the same, but perhaps this isn't the case? Also, is the approach I am using above for customizing the StrPrinter the recommended way to do it? Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Re: How to properly subclass the pretty printer
This code will replicate the problem when run using the latest sympy pull: from sympy import Basic from sympy.printing.str import StrPrinter from sympy.printing.pretty.pretty import PrettyPrinter, xsym, pprint class GreenEggsAndHam(Basic): def __init__(self, string): self.s = string def _pretty_(self): return print_GreenEggsAndHam(self) class HamPrinter(PrettyPrinter): printmethod = '_pretty_' def _print_GreenEggsAndHam(self, e): return e.s.lower() + xsym('*') + \xC2\xB7 def print_GreenEggsAndHam(e): pp = HamPrinter() return pp.doprint(e) MyBreakfast = GreenEggsAndHam('I LOVE SYMPY') print_GreenEggsAndHam(MyBreakfast) pprint(MyBreakfast) ~Luke On Jun 25, 11:58 am, Ondrej Certik ond...@certik.cz wrote: On Thu, Jun 25, 2009 at 12:50 PM, Lukehazelnu...@gmail.com wrote: I'm trying to subclass the StrPrinter and PrettyPrinter so that I can customize the display of some classes I have created for PyDy. I have had success with getting StrPrinter, but I found it to have some weird unicode issues, so I am using plain old strings for my sublcass of StrPrinter, and would like to reserve all unicode stuff for the PrettyPrinter. The way I am subclassing StrPrinter is as follows: 1) My PyDy classes are subclassed from Basic. I override the __str__() method of each of my PyDy classes to look like: def __str__(self): return pydy_str(self) where pydy_str(self) looks like: def pydy_str(e): p = PyDyStrPrinter() return p.doprint(e) 2) I subclass StrPrinter, and add methods entitled _print_MyPyDyClass, as follows: def _print_UnitVector(self, e): These _print_*** methods return a string of how I want each class to be displayed. Nowhere in any of my classes, or in my subclassing of StrPrinter, do I have printmethod defined. Everything above works just fine. The problem is when I try the same approach with subclassing PrettyPrinter. I created class methods entitled _sympypretty_() for each of my classes, then define a pydy_pretty() function, and then subclass PrettyPrinter, analogously to my approach above. It doesn't work. Specifically, I get infinite recursion runtime errors. I tried adding the printmethod class attribute to my PyDyPrettyPrinter, but it didn't make any difference, I still get infinite recursion errors. I have spent many hours on this and I am sure it is probably a very simple fix and that I am just not using things correctly. Does anybody have any recommendations on how this should be done properly? Ideally, some example code would be the best that way there would be no confusion as to how this should be done. It seems to me that the approach that should be taken to subclassing either StrPrinter or PrettyPrinter should be conceptually the same, but perhaps this isn't the case? Also, is the approach I am using above for customizing the StrPrinter the recommended way to do it? Please create a new branch in your repository with the above problem and show here how to reproduce it, so that people can have a look. Ondrej --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Solving equation sets in Mathematica
I would recommend looking at scipy.optimize.fsolve(), as Alan suggested. If you have a decent initial guess, it should work. ~Luke On Jun 26, 9:43 am, Alan Bromborsky abro...@verizon.net wrote: nandan jha wrote: Hello I am trying to solve a set of non-linear equations in Mathematica 7.0 and every time it shows a error message : FindRoot::jsing: Encountered a singular Jacobian at the point {B1,B2,B3,Ea1,Ea2,Ea3} = {31.501,0.9004,38.5013,-1000.1,-1000.01,-2000.1}. Try perturbing the initial point(s). . Sometimes it also shows this error message: FindRoot::lstol: The line search decreased the step size to within tolerance specified by AccuracyGoal and PrecisionGoal but was unable to find a sufficient decrease in the merit function. You may need more than MachinePrecision digits of working precision to meet these tolerances. . The equations that I am trying to solve are: -- FindRoot[{Exp[B1 + Ea1*0.000374526] + Exp[B2 + Ea2*0.000374526] + Exp[B3 + Ea3*0.000374526] == 0.0183, Exp[B1 + Ea1*0.00037925] + Exp[B2 + Ea2*0.00037925] + Exp[B3 + Ea3*0.00037925] == 0.00995, Exp[B1 + Ea1*0.00038287] + Exp[B2 + Ea2*0.00038287] + Exp[B3 + Ea3*0.00038287] == 0.0075, Exp[2*B1 + 2*Ea1*0.000374526] + Exp[2*B2 + 2*Ea2*0.000374526] + Exp[2*B3 + 2*Ea3*0.000374526] + 2*Exp[B1 + B2 + (Ea1 + Ea2)*0.000374526] + 2*Exp[B2 + B3 + (Ea3 + Ea2)*0.000374526] - 2*Exp[B1 + B3 + (Ea1 + Ea3)*0.000374526] == 0.01784*0.01784, Exp[2*B1 + 2*Ea1*0.00037925] + Exp[2*B2 + 2*Ea2*0.00037925] + Exp[2*B3 + 2*Ea3*0.00037925] + 2*Exp[B1 + B2 + (Ea1 + Ea2)*0.00037925] + 2*Exp[B2 + B3 + (Ea3 + Ea2)*0.00037925] - 2*Exp[B1 + B3 + (Ea1 + Ea3)*0.00037925] == 0.00983*0.00983, Exp[2*B1 + 2*Ea1*0.00038287] + Exp[2*B2 + 2*Ea2*0.00038287] + Exp[2*B3 + 2*Ea3*0.00038287] + 2*Exp[B1 + B2 + (Ea1 + Ea2)*0.00038287] + 2*Exp[B2 + B3 + (Ea3 + Ea2)*0.00038287] - 2*Exp[B1 + B3 + (Ea1 + Ea3)*0.00038287] == 0.00742*0.00742}, {B1, 40.001}, {B2, 110.9004}, {B3, 47.001309}, {Ea1, -1000.1}, {Ea2, -1000.01}, {Ea3, -2000.1}, MaxIterations - Infinity, AccuracyGoal - Infinity] - Can someone tell me if this can be solved in sympy and shouldn't the Mathematica itself change the initial value and do a computation to get the answer. Thanks for any help in advance. Nandan You might want to look at the root finders in scipy. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: who still uses python2.4
I use 2.6 and have never used 2.4 since I started using python 2 years ago. Breaking sympy compatibility with python 2.4 is ok by me. It seems like the users of sympy are probably the type who can update more frequently than once every 3 years, so it doesn't seem like too much of an issue. On Jun 26, 6:47 pm, Aaron S. Meurer asmeu...@gmail.com wrote: I am +1 for removing support for Python 2.4, if no one uses it. Python 2.5 added quite a few language changes aside from just any() and all() that could be useful [0], like the ternary operator and better try syntax. By the way, the latest version of Mac OS X (10.5, Leopard) comes with at least Python 2.5, so you are good there [1]. I believe that the previous version (10.4, Tiger) came with Python 2.4 or less, but 10.5 was released long enough ago that I think it is ok to break compatibility there (10.6 is scheduled to ship in September!). At any rate, Python 2.5 was released in 2006 [2], almost three years ago, so any OS that doesn't support it yet should expect to break compatibility with python applications and packages by now. [0] -http://docs.python.org/whatsnew/2.5.html [1] -http://www.apple.com/opensource/ [2] -http://www.python.org/dev/peps/pep-0356/ Aaron Meurer On Jun 26, 2009, at 7:29 PM, Ondrej Certik wrote: Hi, I just wanted to make a quick survey how many sympy users still use python2.4? Now even the stable version of Debian uses python2.5. Is there still a major linux distribution that uses python2.4? The real problem with python2.4 is that it doesn't support relative imports and as such it's a realy pain to include libraries like mpmath. Fredrik mentioned here http://code.google.com/p/mpmath/issues/detail?id=138#c30 that he would like to reintroduce hierarchy of modules in mpmath, which is really tedious to make it work inside sympy with python2.4. With sympy itself, it's not a big problem to support python2.4, one just needs to take care of things like any(), SKIP in doctest etc., so my plan is to support python2.4 at least one more year if possible. What do you think? Ondrej --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Difierentiating With Respect to a Function
Alan, I brought this issue up a while back and submitted a patch that fixed the same issue in solve. I haven't gotten around to writing the same piece of code for diff, but this is on my to do list for the same reasons as yours. I think the fundamental issue is that Symbols are treated as constants when it comes to differentiation, so we have to use Function if we want things like the chain rule to work. The issue, however, is that this use of Function is distinct from the more typical use of function: creating user defined symbolic functions (e.g., the sin and cos functions), by subclassing Function, where all the behavior is known with certainty. This is very distinct from the case of generalized coordinates, which are functions of time (or some other scalar parameter), but typically don't have an analytic representation, since they often arise from ODE's without analytic solutions. I have been playing around with how to subclass Function or Symbol in a way that would give the behavior that would be desired for a generalized coordinate. The argument for subclassing from Symbol would be to ensure all the things you can do with Symbols could be done with generalized coordinates, which I could see being a lot of things. There are many things that one would like to to be able to do with generalized coordinates that can't (currently) be done on sympy Function objects (diff is one example) A few things on my list would be: 1) Customized printing so that the '(t)' isn't displayed after each one. 2) Differentiation w.r.t the independent variable (often Symbol('t')) would return another type: perhaps a Generalized Speed, rather than a Derivative object. This generalized speed would also be subclassed from Symbol, so that all the same manipulations could be performed on it. Here is one issue that I don't really know how to handle: In [24]: t = Symbol('t') In [25]: x = Function('x')(t) In [26]: x Out[26]: x(t) In [27]: type(x) Out[27]: x In [28]: y = Function('y')(t) In [29]: y Out[29]: y(t) In [30]: type(y) Out[30]: y Note that they type of x and y are both different. What I'm envisioning is something with the following behavior: In [1]: x = GeneralizedCoordinate('x') In [2]: type(x) Out[2]: GeneralizedCoordinate In [3]: xp = x.dt() In [4]: print xp Out[4]: x' In [5]: type(xp) Out[5]: GeneralizedSpeed We could also take this one step further and create a GeneralizedAcceleration. The main goal is to avoid having to do the annoying substitutions back and forth as you mentioned. What other behavior do you think this class should have, and do you think we can do it by subclassing from Symbol, rather than Function? That to me seems the most logical, we just need to ensure we can make the chain rule work, so this behavior is preserved: In[1]: sin(x).diff(t) Out[2]: x'*cos(x) ~Luke On Jun 28, 8:53 am, Aaron S. Meurer asmeu...@gmail.com wrote: The routines in solve() for solving for a function or a derivative could probably be adapted to diff (and others?) pretty easily. See commit 5e5a333da78a3af743e5dc5f0130448aaea7c85a. Aaron Meurer On Jun 28, 2009, at 7:11 AM, Alan Bromborsky wrote: I tried this: from sympy import * x = Symbol('x') print x f = Function('f')(x) print f y = cos(x) dydx = diff(y,x) print dydx y = cos(f) dfdx = diff(y,f) print dfdx and got: x f(x) -sin(x) Traceback (most recent call last): File /home/brombo/diff.py, line 11, in module dfdx = diff(y,f) File /usr/local/lib/python2.6/dist-packages/sympy-0.6.5_beta2_git- py2.6.egg/sympy/core/multidimensional.py, line 127, in wrapper return f(*args, **kwargs) File /usr/local/lib/python2.6/dist-packages/sympy-0.6.5_beta2_git- py2.6.egg/sympy/core/function.py, line 708, in diff return Derivative(f,x,times, **{'evaluate':evaluate}) File /usr/local/lib/python2.6/dist-packages/sympy-0.6.5_beta2_git- py2.6.egg/sympy/core/function.py, line 486, in __new__ raise ValueError('Invalid literal: %s is not a valid variable' % s) ValueError: Invalid literal: f(x) is not a valid variable There was a discussion about this topic a while back. Is anything being done about it? Is the only current workaround to substitue a dummy variable for 'f', differentiate, and substitute 'f' for the dummy variable? I too wish to work with Lagragians and generalized coordinates. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Unicode combining diacritical characters
I'm trying to get the Unicode 'COMBINING DOT ABOVE' character to work. This is used for the Newtonian shorthand notation for a time derivative: http://www.fileformat.info/info/unicode/char/0307/index.htm As far as I can tell, you would follow any unicode character with the above character, and it should put the dot above it: print(uq\u0307) should print q with a dot above it. Other diacriticals seems to work, for example, the 'COMBINING FERMATA': print(uq\u0352) prints the q with a weird little fermata above it. I tried python3 and it does the same thing, so it seems that perhaps my terminal, or the font I'm using in my terminal, doesn't support that particular character. I am using Konsole in Kubuntu 9.04, with the character encoding set to: Unicode-- UTF-8. Can anybody else get the 'COMBINING DOT ABOVE' character to work in their terminals? ~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 -~--~~~~--~~--~--~---
[sympy] Re: Working with sets
Python has a builtin set data type. For example: x= [1,2,3,5,2,1] set(x) set(1, 2, 3, 5) Sympy has an Interval class, but it seems at the moment it doesn't have things like the intersection / union operators, nor whether the interval is open or closed. I'm not sure if this Interval class was intended for the application you mentioned, but if so, we should add some functionality, it wouldn't be very hard. The file is: sympy/core/interval.py Useful methods to add that I can think of: -- union / intersection / difference -- open / closed -- force start to be = end ??? so that you couldn't make an interval like: [2, 1]? ~Luke On Jul 3, 10:44 am, Christophe projet...@gmail.com wrote: Hello, I would like to know if it is possible to work with sets. A second question. Is the a way to do something like intersection([1 ; 2];[1.5 ; 5]) and union([1 ; 2];[1.5 ; 5]) where [a ; b]:={x | a=x=b}? Best regards. Christophe --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: sphinx documentation for the rc1 release
I don't know if this will change when you push to the docs.sympy.org server, but the links for the books by Hestenes and Lasenby at the bottom of the GA Module currently don't work. Just thought I'd let you know. ~Luke On Jul 13, 7:59 pm, Alan Bromborsky abro...@verizon.net wrote: Ondrej Certik wrote: On Sun, Jul 12, 2009 at 12:15 PM, Ondrej Certikond...@certik.cz wrote: On Sun, Jul 12, 2009 at 11:47 AM, Alan Bromborskyabro...@verizon.net wrote: [...] At least for the geometric algebra documentation math mode is not working! That's right, thanks for checking it! I'll look into this later today and fix it. It was because dvipng was missing on my system. I have reuploaded to: http://certik.github.com/sympy/ Alan, could you please check that everything is ok now? (be sure to refresh your browser) If so, we are ready to release. Ondrej Looks OK to me now. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Automatic distribution of numbers versus symbols
I'm exploring Sympy's behavior with regard to automatic distribution of expressions. Purely from experimenting, I noticed a few things: In [1]: exp1 = x*(x-y) In [2]: exp2 = x*x-x*y In [3]: exp3 = 4*(x-y) In [4]: exp4 = 4*x-4*y In [5]: exp1 Out[5]: x⋅(x - y) In [6]: exp2 Out[6]: 2 -x⋅y + x In [7]: exp3 Out[7]: -4⋅y + 4⋅x In [8]: exp4 Out[8]: -4⋅y + 4⋅x In [9]: factor(exp1) Out[9]: x⋅(x - y) In [10]: factor(exp2) Out[10]: x⋅(x - y) In [11]: factor(exp3) Out[11]: -4⋅y + 4⋅x In [12]: factor(exp4) Out[12]: -4⋅y + 4⋅x I compared these four expressions in Sympy, Mathematica 7, Matlab 2008a (Maple under the hood), Matlab 2008b (Mupad under the hood). The results are as follows: Mathematica 7 In[5]:= x*(x-y) Out[5]= x (x-y) In[6]:= x*x-x*y Out[6]= x^2-x y In[7]:= 4*(x-y) Out[7]= 4 (x-y) In[8]:= 4*x-4*y Out[8]= 4 x-4 y In[9]:= Factor[In[5]] Out[9]= x (x-y) In[10]:= Factor[In[6]] Out[10]= x (x-y) In[11]:= Factor[In[7]] Out[11]= 4 (x-y) In[12]:= Factor[In[8]] Out[12]= 4 (x-y) Matlab 2008a (Maple) exp1 = x*(x-y) exp1 = x*(x-y) exp2 = x*x-x*y exp2 = x^2-x*y exp3 = 4*(x-y) exp3 = 4*x-4*y exp4=4*x-4*y exp4 = 4*x-4*y factor(exp1) ans = x*(x-y) factor(exp2) ans = x*(x-y) factor(exp3) ans = 4*x-4*y factor(exp4) ans 4*x-4*y Matlab 2008b (MuPad): exp1 = x*(x-y) exp1 = x*(x - y) exp2=x*x-x*y exp2 = x^2 - x*y exp3=4*(x-y) exp3 = 4*x - 4*y exp4=4*x-4*y exp4 = 4*x - 4*y factor(exp1) ans = x*(x - y) factor(exp2) ans = x*(x - y) factor(exp3) ans = 4*(x - y) factor(exp4) ans = 4*(x - y) So three out of 4 automatically distribute things like 4*(x-y), but not things like x*(x-y). In the case of Sympy and Matlab 2008a, this automatic distribution is not easily reversible by a simple call to factor. It seems to me that: 1) there should be a way to control whether or not distribution occurs automatically, and 2) that if distribution does occur automatically, it should be easily reversible, i.e. through something like factor Is there a way to keep 4*(x-y) as 4*(x-y) instead of -4*y+4*x? 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 -~--~~~~--~~--~--~---
[sympy] Add combine question
I am trying to get the following two expressions to combine under addition: e1 = rf*(1 - (c5*s2 + c2*s4*s5)**2)**(-0.5) e2 = rf*(-c5*s2 - c2*s4*s5)*(1 - (c5*s2 + c2*s4*s5)**2)**(-0.5) Is there a way to make the add combine these to obtain the result: rf*(1 - (c5*s2 + c2*s4*s5))*(1 - (c5*s2 + c2*s4*s5))**(-0.5) which would automatically simpify even further to: rf*(1 - (c5*s2 + c2*s4*s5))**(0.5) It seems like this could be made automatic if Add could look at the hash of each of the arguments of its arguments, and if any of them were equal, they could be made to combine 'automatically'. It is interesting that Mul can auto combine things like: rf*(1 - (c5*s2 + c2*s4*s5))*(1 - (c5*s2 + c2*s4*s5))**(-0.5), but Add does not. Would this be hard to implement in Add? Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Re: Add combine question
Here is a simpler example of the behavior I would like: (2) variables x,y,z (3) e1 = x*(y+z)^.5 - (4) e1 = x*(y+z)^0.5 (5) e2 = x*y*(y+z)^0.5 - (6) e2 = x*y*(y+z)^0.5 (7) e1+e2 Result = x*(1+y)*(y+z)^0.5 (7) In the simplest case of an Add with two terms, it seems like if: 1) Both Add terms (a1 and a2, say) are Mul instances and (set(a1.args) set(a2.args)) != set([]) or 2) One Mul (a1) and one Symbol (a2) and (set(a1.args) set(a2)) != set([]) then they have common factors and could be combined. Any thoughts? ~Luke On Aug 14, 9:49 pm, Luke hazelnu...@gmail.com wrote: I am trying to get the following two expressions to combine under addition: e1 = rf*(1 - (c5*s2 + c2*s4*s5)**2)**(-0.5) e2 = rf*(-c5*s2 - c2*s4*s5)*(1 - (c5*s2 + c2*s4*s5)**2)**(-0.5) Is there a way to make the add combine these to obtain the result: rf*(1 - (c5*s2 + c2*s4*s5))*(1 - (c5*s2 + c2*s4*s5))**(-0.5) which would automatically simpify even further to: rf*(1 - (c5*s2 + c2*s4*s5))**(0.5) It seems like this could be made automatic if Add could look at the hash of each of the arguments of its arguments, and if any of them were equal, they could be made to combine 'automatically'. It is interesting that Mul can auto combine things like: rf*(1 - (c5*s2 + c2*s4*s5))*(1 - (c5*s2 + c2*s4*s5))**(-0.5), but Add does not. Would this be hard to implement in Add? Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Issue 1616
I don't know what changed, but this issue is now causing a lot of my code in pydy to not be able to use .subs() on a bunch of expressions. http://code.google.com/p/sympy/issues/detail?id=1616 I did a git blame and it looks like it was done by Bill Flynn on 2009-08-22. I think this was during the sprint on Saturday at the Scipy conference. Can Bill or Ondrej look into this when you get a chance? It looks like sympy/core/mul.py:811 is the culprit, it looks like your logic in the for loop might not be checking things correctly before trying to removing elements from the list. This is a show stopper for PyDy. I'll be on IRC all day tomorrow and can help debug the problem so we can resolve it ASAP. Here is a test case that causes the error: In [1]: a, b, c, d, e, f, g, h, i, j, k, l = symbols('a b c d e f g h i j k l') In [2]: test = a*b*c**2 + d*b*e**2*f**2 + c*h*i*e**2 In [3]: test.subs({e**2:1-g**2, c**2:1-g**2}) ERROR: An unexpected error occurred while tokenizing input The following traceback may be corrupted or invalid The error message is: ('EOF in multi-line statement', (22, 0)) ERROR: An unexpected error occurred while tokenizing input The following traceback may be corrupted or invalid The error message is: ('EOF in multi-line statement', (96, 0)) --- ValueErrorTraceback (most recent call last) /home/luke/lib/python/pydy/examples/ipython console in module() /home/luke/lib/python/sympy/sympy/core/basic.pyc in subs(self, *args) 1021 sequence = args[0] 1022 if isinstance(sequence, dict): - 1023 return self._subs_dict(sequence) 1024 elif isinstance(sequence, (list, tuple)): 1025 return self._subs_list(sequence) /home/luke/lib/python/sympy/sympy/core/basic.pyc in _subs_dict(self, sequence) subst.append(pattern) 1112 subst.reverse() - 1113 return self._subs_list(subst) 1114 1115 def _seq_subs(self, old, new): /home/luke/lib/python/sympy/sympy/core/basic.pyc in _subs_list(self, sequence) 1064 for old, new in sequence: 1065 if hasattr(result, 'subs'): - 1066 result = result.subs(old, new) 1067 return result 1068 /home/luke/lib/python/sympy/sympy/core/basic.pyc in subs(self, *args) 1028 elif len(args) == 2: 1029 old, new = args - 1030 return self._subs_old_new(old, new) 1031 else: 1032 raise TypeError(subs accepts either 1 or 2 arguments) /home/luke/lib/python/sympy/sympy/core/cache.pyc in wrapper(*args, **kw_args) 83 except KeyError: 84 pass --- 85 func_cache_it_cache[k] = r = func(*args, **kw_args) 86 return r 87 /home/luke/lib/python/sympy/sympy/core/basic.pyc in _subs_old_new(self, old, new) 1037 old = sympify(old) 1038 new = sympify(new) - 1039 return self._eval_subs(old, new) 1040 1041 def _eval_subs(self, old, new): /home/luke/lib/python/sympy/sympy/core/add.pyc in _eval_subs(self, old, new) 310 ret_set = self_set - old_set 311 return Add(new, coeff_self, -coeff_old, *[s._eval_subs(old, new) for s in ret_set]) -- 312 return self.__class__(*[s._eval_subs(old, new) for s in self.args]) 313 314 @cacheit /home/luke/lib/python/sympy/sympy/core/mul.pyc in _eval_subs(self, old, new) 809 # collect commutative terms 810 else: -- 811 comms_final.remove(ele) 812 813 # continue only if all commutative terms in old are present ValueError: list.remove(x): x not in list In [4]: --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Issue 1616
Bill has posted a patch to the Issue page on Google code. It fixes this problem for everything I could throw at it. ~Luke On Aug 25, 12:47 am, Luke hazelnu...@gmail.com wrote: I don't know what changed, but this issue is now causing a lot of my code in pydy to not be able to use .subs() on a bunch of expressions. http://code.google.com/p/sympy/issues/detail?id=1616 I did a git blame and it looks like it was done by Bill Flynn on 2009-08-22. I think this was during the sprint on Saturday at the Scipy conference. Can Bill or Ondrej look into this when you get a chance? It looks like sympy/core/mul.py:811 is the culprit, it looks like your logic in the for loop might not be checking things correctly before trying to removing elements from the list. This is a show stopper for PyDy. I'll be on IRC all day tomorrow and can help debug the problem so we can resolve it ASAP. Here is a test case that causes the error: In [1]: a, b, c, d, e, f, g, h, i, j, k, l = symbols('a b c d e f g h i j k l') In [2]: test = a*b*c**2 + d*b*e**2*f**2 + c*h*i*e**2 In [3]: test.subs({e**2:1-g**2, c**2:1-g**2}) ERROR: An unexpected error occurred while tokenizing input The following traceback may be corrupted or invalid The error message is: ('EOF in multi-line statement', (22, 0)) ERROR: An unexpected error occurred while tokenizing input The following traceback may be corrupted or invalid The error message is: ('EOF in multi-line statement', (96, 0)) --- ValueError Traceback (most recent call last) /home/luke/lib/python/pydy/examples/ipython console in module() /home/luke/lib/python/sympy/sympy/core/basic.pyc in subs(self, *args) 1021 sequence = args[0] 1022 if isinstance(sequence, dict): - 1023 return self._subs_dict(sequence) 1024 elif isinstance(sequence, (list, tuple)): 1025 return self._subs_list(sequence) /home/luke/lib/python/sympy/sympy/core/basic.pyc in _subs_dict(self, sequence) subst.append(pattern) 1112 subst.reverse() - 1113 return self._subs_list(subst) 1114 1115 def _seq_subs(self, old, new): /home/luke/lib/python/sympy/sympy/core/basic.pyc in _subs_list(self, sequence) 1064 for old, new in sequence: 1065 if hasattr(result, 'subs'): - 1066 result = result.subs(old, new) 1067 return result 1068 /home/luke/lib/python/sympy/sympy/core/basic.pyc in subs(self, *args) 1028 elif len(args) == 2: 1029 old, new = args - 1030 return self._subs_old_new(old, new) 1031 else: 1032 raise TypeError(subs accepts either 1 or 2 arguments) /home/luke/lib/python/sympy/sympy/core/cache.pyc in wrapper(*args, **kw_args) 83 except KeyError: 84 pass --- 85 func_cache_it_cache[k] = r = func(*args, **kw_args) 86 return r 87 /home/luke/lib/python/sympy/sympy/core/basic.pyc in _subs_old_new(self, old, new) 1037 old = sympify(old) 1038 new = sympify(new) - 1039 return self._eval_subs(old, new) 1040 1041 def _eval_subs(self, old, new): /home/luke/lib/python/sympy/sympy/core/add.pyc in _eval_subs(self, old, new) 310 ret_set = self_set - old_set 311 return Add(new, coeff_self, -coeff_old, *[s._eval_subs(old, new) for s in ret_set]) -- 312 return self.__class__(*[s._eval_subs(old, new) for s in self.args]) 313 314 @cacheit /home/luke/lib/python/sympy/sympy/core/mul.pyc in _eval_subs(self, old, new) 809 # collect commutative terms 810 else: -- 811 comms_final.remove(ele) 812 813 # continue only if all commutative terms in old are present ValueError: list.remove(x): x not in list In [4]: --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] New code in bicycle branch
Code generation has been coming up in the last few days and I have been dealing with it myself as well. For this purpose, I created a function for PyDy called 'generate_function'. You can see it if you go to my github, in the bicycle_work branch: git://github.com/hazelnusse/pydy.git And go to pydy.py:2936 to see the function. It is a little bit custom to PyDy because I rely on my customized StrPrinter, but maybe some of the ideas in it could be useful to others. It is also geared towards lists of equations which have trigonometric terms (sin,cos, tan) in them, so I do some parsing to identify all the trig terms and compute them only once. The basic idea is to specify: 1) a string name --- this will become the name of the Python function 2) a python list of Sympy Relational (lhs==rhs) objects 3) the function arguments (quantities needed to evaluate the rhs of the equations 4) optional function parameters 5) optional docstring 6) optional nested terms -- repeated things that show up in numerous places throughout the equations 7) optional time boolean argument to create a function signature of f(x, t, params) 8) optional triples boolean argument to return a list of length 3 lists rather than one big list, useful for 3d vector stuff It returns a string which is valid python code and defines a function which can be either used with exec() or written to file and then used later as a library. The function returns a list of the left hand sides of the items in the list of Relational objects. I have been using it to create functions that work well with scipy's odeint and fsolve and it has worked very well. To see it in action, run the rollingdisc.py script in the examples directory. It will print out the generated string expression. ~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 -~--~~~~--~~--~--~---
[sympy] Symbolic matrix inversion
I'm using Sympy from within PyDy to generate the equations of motion for mechanical systems. At the end of the day, the equations can be most generally written as: M(x) * x'' = F(x, x', t) M(x) is what is known as the mass matrix, and will in general depend on the configuration of the system (positions and angles). This matrix needs to be inverted in order to solve for x'', which then will allow for numerical integration or stability analysis. I am generating M(x) symbolically, and in some case is it sparse, but in many cases, it isn't. Each entry of the matrix is a Sympy expression, but instead of trying to invert a matrix of Sympy expressions, I introduce a dummy symbol for each non-zero entries and then invert the matrix of dummy symbols. Humble systems might have 5 degrees of freedom (so a 5x5 needs to be inverted), so this inversion isn't so bad, but beyond this, the matrix inversions take a really long time, especially when the matrices are full (no zero entries). I was thinking that it might be nice to have pre-computed matrix inverses for n x n matrices. Matrix inversion is O(n^3), so it would be nice to have all this precomputed symbolically, and this would greatly speed up Sympy's matrix capabilities. Inverses up to say 100x100 could be computed (or maybe something smaller), and then when you need an inverse, everything would be fast. This could also be used behind the scenes (by introduction of symbolic substitution dictionaries) for inverting a matrix full of sympy expressions. Does anybody know if this has been done by somebody somewhere, or have any other ideas on how it could be done better than the way I suggested? Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] Re: Symbolic matrix inversion
On Sep 29, 1:09 pm, Ondrej Certik ond...@certik.cz wrote: On Tue, Sep 29, 2009 at 12:49 PM, Luke hazelnu...@gmail.com wrote: I'm using Sympy from within PyDy to generate the equations of motion for mechanical systems. At the end of the day, the equations can be most generally written as: M(x) * x'' = F(x, x', t) M(x) is what is known as the mass matrix, and will in general depend on the configuration of the system (positions and angles). This matrix needs to be inverted in order to solve for x'', which then will allow for numerical integration or stability analysis. I am generating M(x) symbolically, and in some case is it sparse, but in many cases, it isn't. Each entry of the matrix is a Sympy expression, but instead of trying to invert a matrix of Sympy expressions, I introduce a dummy symbol for each non-zero entries and then invert the matrix of dummy symbols. Humble systems might have 5 degrees of freedom (so a 5x5 needs to be inverted), so this inversion isn't so bad, but beyond this, the matrix inversions take a really long time, especially when the matrices are full (no zero entries). I was thinking that it might be nice to have pre-computed matrix inverses for n x n matrices. Matrix inversion is O(n^3), so it would be nice to have all this precomputed symbolically, and this would greatly speed up Sympy's matrix capabilities. Inverses up to say 100x100 could be computed (or maybe something smaller), and then when you need an inverse, everything would be fast. This could also be used behind the scenes (by introduction of symbolic substitution dictionaries) for inverting a matrix full of sympy expressions. The inversion of a 100x100 dense matrix would be quite a big mess, wouldn't it? Yes, it would be disaster. But I see what you mean, and I think it makes sense to cache it, if it speeds things up. But see below. Does anybody know if this has been done by somebody somewhere, or have any other ideas on how it could be done better than the way I suggested? I would first try to profile the inversion code to see why it is slow. Because for example the adjoint method is just a ratio of two determinants, so it may be the determinants calculation that is slow (and should be cached). However, there are 100^2 different determinants (right?), but I guess caching 1 expressions should still be doable. But if this is the case, we should just speed up the determinant calculation, imho. Looking at the code, we have 2 algorithms implemented, bareis and berkowitz. I did some timings of the three matrix inversion (GE, ADJ, LU) using the timeit module. I also timed the two determinant methods as well to see they the two perform side by side. It seems that bareis (the default one) is drastically slower than berkowitz, even when you call .expand() on the berkowitz determinant to make it end up with identical symbolic expressions. Maybe this should be the default method for .det()? I went up to 5x5 matrices, it started to get really slow after that. Gaussian elimination seems to be the slowest one, at least for dense matrices like the ones I used. Here is the code I used to do the timings: import timeit from numpy import zeros, max import matplotlib.pyplot as plt # Dimension of matrix to invert n = range(2, 6) # Number of times to invert number = 20 # Store the results t = zeros((len(n), 5)) for i in n: setup_code = from sympy import Matrix, Symbol\nM = Matrix(%d,\ %d%(i,i)+,lambda i,j: Symbol('m%d%d'%(i,j))) t[i-2, 0] = timeit.Timer('M.inverse_GE()', setup_code).timeit (number) t[i-2, 1] = timeit.Timer('M.inverse_ADJ()', setup_code).timeit (number) t[i-2, 2] = timeit.Timer('M.inverse_LU()', setup_code).timeit (number) t[i-2, 3] = timeit.Timer('M.det(method=bareis)', setup_code).timeit(number) t[i-2, 4] = timeit.Timer('M.det(method=berkowitz).expand()', setup_code).timeit(number) plt.plot(n, t[:,0]/number, label='GE') plt.plot(n, t[:,1]/number, label='ADJ') plt.plot(n, t[:,2]/number, label='LU') plt.plot(n, t[:,3]/number, label='bareis_det') plt.plot(n, t[:,4]/number, label='berkowitz_det.expand()') plt.legend(loc=0) plt.title('Average time to complete 1 matrix inversion/determinant') plt.xlabel('matrix dimension') plt.ylabel('Time [seconds]') plt.xticks(n) plt.axis([2, n[-1], 0, max(t/number)]) plt.show() I'd be curious to know if others get similar results as I do. I posted the results of the above script here: http://i35.tinypic.com/so09hw.jpg It looks like Gaussian elimination is suffering from the bottleneck in the Bareis determinant since it has an assertion that calls .det() to make sure the determinant is non-zero. Also how about the creation of so many expressions, it could be slow too. Yeah, this is true. It seems to me though that if you had all the inverses computed for fully populated matrices, then if some of the entries were zero these things
[sympy] Re: Symbolic matrix inversion
Yes, this is something I should look into. I am pretty sure that the Netlib codes have this functionality, but it hasn't been wrapped into the Python scientific packages that I know of, at least not yet. scipy.integrate has odeint and ode, but both need everything in first order form, no mass matrix is allowed. I figured that if I was going to work symbolically, I may as well go as far as I can go, so if I can invert the matrices symbolically, I'd prefer that. This would also be nice because then the equations could be integrated with any numerical integrator out there, as the ode formulation would be as generic as possible. ~Luke On Sep 29, 4:15 pm, Alan Bromborsky abro...@verizon.net wrote: Luke wrote: On Sep 29, 1:09 pm, Ondrej Certik ond...@certik.cz wrote: On Tue, Sep 29, 2009 at 12:49 PM, Luke hazelnu...@gmail.com wrote: I'm using Sympy from within PyDy to generate the equations of motion for mechanical systems. At the end of the day, the equations can be most generally written as: M(x) * x'' = F(x, x', t) M(x) is what is known as the mass matrix, and will in general depend on the configuration of the system (positions and angles). This matrix needs to be inverted in order to solve for x'', which then will allow for numerical integration or stability analysis. I am generating M(x) symbolically, and in some case is it sparse, but in many cases, it isn't. Each entry of the matrix is a Sympy expression, but instead of trying to invert a matrix of Sympy expressions, I introduce a dummy symbol for each non-zero entries and then invert the matrix of dummy symbols. Humble systems might have 5 degrees of freedom (so a 5x5 needs to be inverted), so this inversion isn't so bad, but beyond this, the matrix inversions take a really long time, especially when the matrices are full (no zero entries). I was thinking that it might be nice to have pre-computed matrix inverses for n x n matrices. Matrix inversion is O(n^3), so it would be nice to have all this precomputed symbolically, and this would greatly speed up Sympy's matrix capabilities. Inverses up to say 100x100 could be computed (or maybe something smaller), and then when you need an inverse, everything would be fast. This could also be used behind the scenes (by introduction of symbolic substitution dictionaries) for inverting a matrix full of sympy expressions. The inversion of a 100x100 dense matrix would be quite a big mess, wouldn't it? Yes, it would be disaster. But I see what you mean, and I think it makes sense to cache it, if it speeds things up. But see below. Does anybody know if this has been done by somebody somewhere, or have any other ideas on how it could be done better than the way I suggested? I would first try to profile the inversion code to see why it is slow. Because for example the adjoint method is just a ratio of two determinants, so it may be the determinants calculation that is slow (and should be cached). However, there are 100^2 different determinants (right?), but I guess caching 1 expressions should still be doable. But if this is the case, we should just speed up the determinant calculation, imho. Looking at the code, we have 2 algorithms implemented, bareis and berkowitz. I did some timings of the three matrix inversion (GE, ADJ, LU) using the timeit module. I also timed the two determinant methods as well to see they the two perform side by side. It seems that bareis (the default one) is drastically slower than berkowitz, even when you call .expand() on the berkowitz determinant to make it end up with identical symbolic expressions. Maybe this should be the default method for .det()? I went up to 5x5 matrices, it started to get really slow after that. Gaussian elimination seems to be the slowest one, at least for dense matrices like the ones I used. Here is the code I used to do the timings: import timeit from numpy import zeros, max import matplotlib.pyplot as plt # Dimension of matrix to invert n = range(2, 6) # Number of times to invert number = 20 # Store the results t = zeros((len(n), 5)) for i in n: setup_code = from sympy import Matrix, Symbol\nM = Matrix(%d,\ %d%(i,i)+,lambda i,j: Symbol('m%d%d'%(i,j))) t[i-2, 0] = timeit.Timer('M.inverse_GE()', setup_code).timeit (number) t[i-2, 1] = timeit.Timer('M.inverse_ADJ()', setup_code).timeit (number) t[i-2, 2] = timeit.Timer('M.inverse_LU()', setup_code).timeit (number) t[i-2, 3] = timeit.Timer('M.det(method=bareis)', setup_code).timeit(number) t[i-2, 4] = timeit.Timer('M.det(method=berkowitz).expand()', setup_code).timeit(number) plt.plot(n, t[:,0]/number, label='GE') plt.plot(n, t[:,1]/number, label='ADJ') plt.plot(n, t[:,2]/number, label='LU') plt.plot(n, t[:,3]/number, label='bareis_det') plt.plot(n, t[:,4
[sympy] Re: Symbolic matrix inversion
In the formulation I use for PyDy, the equations of motion are generated in first order form. For holonomic systems with n degrees of freedom, there will be 2n first order equations and the first n of these I refer to as the kinematic differential equations. In the simplest case, the form of the first n equations would be like: q_i' = u_i (i = 1,...,n) The remaining n ODE's (dynamic differential equations) would be the ones with the mass matrix in the form like: M(q)*u' = F(q, u, t) Where q, u are n x 1 vectors, M is nxn, and F: n x n x 1 -- n Usually this choice of 'generalized speeds' (a.k.a quasi-coordinates) which result in kinematic differential equations like: q_i' = u_i is not the best choice out there. But even with other choices, they can be written as: q' = T(q) * u + R(t) Where in most cases R(t) is zero, except when you have some prescribed motion in your system. The dynamic differential equations would still have the same form as before. So they are linear in the generalized speeds, but the T(q) matrix would in general be comprised of trigonometric entries which depend on the configuration and/or parameters. Such choices of generalized speeds can often lead to reduced complexity of the dynamic equations, with some (usually worthwhile) trade-off in the complexity of the kinematic equations. For nonholonomic systems, depending on how you formulate things you may end up having to integrate fewer dynamic equations. For example, in the rolling disc, there are 5 coordinates that configure the disc, but only 3 degrees of freedom. If you are interested in all of the motion, you would integrate 5 kinematic D.E.'s and 3 dynamic D.E.'s. If you only are interested in the dynamic equations, you would end up only integrating 1 kinematic D.E. (the one associated with the lean of the disc), and 3 dynamic D.E.'s. So in these types of systems, it depends on what your needs are. ~Luke On Sep 29, 4:22 pm, Alan Bromborsky abro...@verizon.net wrote: Alan Bromborsky wrote: Luke wrote: On Sep 29, 1:09 pm, Ondrej Certik ond...@certik.cz wrote: On Tue, Sep 29, 2009 at 12:49 PM, Luke hazelnu...@gmail.com wrote: I'm using Sympy from within PyDy to generate the equations of motion for mechanical systems. At the end of the day, the equations can be most generally written as: M(x) * x'' = F(x, x', t) M(x) is what is known as the mass matrix, and will in general depend on the configuration of the system (positions and angles). This matrix needs to be inverted in order to solve for x'', which then will allow for numerical integration or stability analysis. I am generating M(x) symbolically, and in some case is it sparse, but in many cases, it isn't. Each entry of the matrix is a Sympy expression, but instead of trying to invert a matrix of Sympy expressions, I introduce a dummy symbol for each non-zero entries and then invert the matrix of dummy symbols. Humble systems might have 5 degrees of freedom (so a 5x5 needs to be inverted), so this inversion isn't so bad, but beyond this, the matrix inversions take a really long time, especially when the matrices are full (no zero entries). I was thinking that it might be nice to have pre-computed matrix inverses for n x n matrices. Matrix inversion is O(n^3), so it would be nice to have all this precomputed symbolically, and this would greatly speed up Sympy's matrix capabilities. Inverses up to say 100x100 could be computed (or maybe something smaller), and then when you need an inverse, everything would be fast. This could also be used behind the scenes (by introduction of symbolic substitution dictionaries) for inverting a matrix full of sympy expressions. The inversion of a 100x100 dense matrix would be quite a big mess, wouldn't it? Yes, it would be disaster. But I see what you mean, and I think it makes sense to cache it, if it speeds things up. But see below. Does anybody know if this has been done by somebody somewhere, or have any other ideas on how it could be done better than the way I suggested? I would first try to profile the inversion code to see why it is slow. Because for example the adjoint method is just a ratio of two determinants, so it may be the determinants calculation that is slow (and should be cached). However, there are 100^2 different determinants (right?), but I guess caching 1 expressions should still be doable. But if this is the case, we should just speed up the determinant calculation, imho. Looking at the code, we have 2 algorithms implemented, bareis and berkowitz. I did some timings of the three matrix inversion (GE, ADJ, LU) using the timeit module. I also timed the two determinant methods as well to see they the two perform side by side. It seems that bareis (the default one) is drastically slower than berkowitz, even when you call .expand() on the berkowitz determinant
[sympy] Re: Symbolic matrix inversion
I also check the GSL (GNU Scientific Library). They have a nice numerical integrator, but it doesn't allow for a mass matrix. ~Luke On Sep 29, 4:44 pm, Luke hazelnu...@gmail.com wrote: Yes, this is something I should look into. I am pretty sure that the Netlib codes have this functionality, but it hasn't been wrapped into the Python scientific packages that I know of, at least not yet. scipy.integrate has odeint and ode, but both need everything in first order form, no mass matrix is allowed. I figured that if I was going to work symbolically, I may as well go as far as I can go, so if I can invert the matrices symbolically, I'd prefer that. This would also be nice because then the equations could be integrated with any numerical integrator out there, as the ode formulation would be as generic as possible. ~Luke On Sep 29, 4:15 pm, Alan Bromborsky abro...@verizon.net wrote: Luke wrote: On Sep 29, 1:09 pm, Ondrej Certik ond...@certik.cz wrote: On Tue, Sep 29, 2009 at 12:49 PM, Luke hazelnu...@gmail.com wrote: I'm using Sympy from within PyDy to generate the equations of motion for mechanical systems. At the end of the day, the equations can be most generally written as: M(x) * x'' = F(x, x', t) M(x) is what is known as the mass matrix, and will in general depend on the configuration of the system (positions and angles). This matrix needs to be inverted in order to solve for x'', which then will allow for numerical integration or stability analysis. I am generating M(x) symbolically, and in some case is it sparse, but in many cases, it isn't. Each entry of the matrix is a Sympy expression, but instead of trying to invert a matrix of Sympy expressions, I introduce a dummy symbol for each non-zero entries and then invert the matrix of dummy symbols. Humble systems might have 5 degrees of freedom (so a 5x5 needs to be inverted), so this inversion isn't so bad, but beyond this, the matrix inversions take a really long time, especially when the matrices are full (no zero entries). I was thinking that it might be nice to have pre-computed matrix inverses for n x n matrices. Matrix inversion is O(n^3), so it would be nice to have all this precomputed symbolically, and this would greatly speed up Sympy's matrix capabilities. Inverses up to say 100x100 could be computed (or maybe something smaller), and then when you need an inverse, everything would be fast. This could also be used behind the scenes (by introduction of symbolic substitution dictionaries) for inverting a matrix full of sympy expressions. The inversion of a 100x100 dense matrix would be quite a big mess, wouldn't it? Yes, it would be disaster. But I see what you mean, and I think it makes sense to cache it, if it speeds things up. But see below. Does anybody know if this has been done by somebody somewhere, or have any other ideas on how it could be done better than the way I suggested? I would first try to profile the inversion code to see why it is slow. Because for example the adjoint method is just a ratio of two determinants, so it may be the determinants calculation that is slow (and should be cached). However, there are 100^2 different determinants (right?), but I guess caching 1 expressions should still be doable. But if this is the case, we should just speed up the determinant calculation, imho. Looking at the code, we have 2 algorithms implemented, bareis and berkowitz. I did some timings of the three matrix inversion (GE, ADJ, LU) using the timeit module. I also timed the two determinant methods as well to see they the two perform side by side. It seems that bareis (the default one) is drastically slower than berkowitz, even when you call .expand() on the berkowitz determinant to make it end up with identical symbolic expressions. Maybe this should be the default method for .det()? I went up to 5x5 matrices, it started to get really slow after that. Gaussian elimination seems to be the slowest one, at least for dense matrices like the ones I used. Here is the code I used to do the timings: import timeit from numpy import zeros, max import matplotlib.pyplot as plt # Dimension of matrix to invert n = range(2, 6) # Number of times to invert number = 20 # Store the results t = zeros((len(n), 5)) for i in n: setup_code = from sympy import Matrix, Symbol\nM = Matrix(%d,\ %d%(i,i)+,lambda i,j: Symbol('m%d%d'%(i,j))) t[i-2, 0] = timeit.Timer('M.inverse_GE()', setup_code).timeit (number) t[i-2, 1] = timeit.Timer('M.inverse_ADJ()', setup_code).timeit (number) t[i-2, 2] = timeit.Timer('M.inverse_LU()', setup_code).timeit (number) t[i-2, 3] = timeit.Timer('M.det(method=bareis)', setup_code).timeit
[sympy] Re: Symbolic matrix inversion
The methods you suggest essentially takes care of the mass matrix problem by solving a linear system numerically during numerical integration. I am familiar with tools out there that do this, but this isn't what I'm looking to do. I haven't seen one that is written directly usable in Python -- do you know of one? The netlib packages have this capability, but I'm no Fortran programmer. What I am interested in doing is solving the linear system symbolically so that first order equations can be generated symbolically and the most generic of ODE solvers will work. This also eliminates the iteration that is being done by the ODE solver during time integration. Thanks, ~Luke On Sep 29, 8:07 pm, Tim Lahey tim.la...@gmail.com wrote: On Sep 29, 2009, at 7:15 PM, Alan Bromborsky wrote: Are there differential equation solvers where you don't have to invert the matrix? A Newmark-Beta scheme will directly solve a second-order system of ODEs. The standard form uses iteration to solve the system so no inversion is necessary. For linear second-order problems you can rewrite things to use matrix algebra. For more information, I recommend Bathe and Wilson, Klaus-Jürgen Bathe and Edward L. Wilson. Numerical Methods in Finite Element Analysis. Prentice Hall, Englewood Cliffs, New Jersey, 1976. There are other second order solvers out there too. Cheers, Tim. --- Tim Lahey PhD Candidate, Systems Design Engineering University of Waterloohttp://www.linkedin.com/in/timlahey --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Re: Symbolic matrix inversion
Alan, For the systems I have studied at the moment, the most complicated inverses I have need to compute are 3x3 dense matrices (for the nonlinear equations of motion of a benchmark bicycle model [0]) and 6x6 sparse inverses (for solving the kinematic equations of motion for the derivatives of the configuration variables in terms of the generalized speeds). For an example, you can look at my github in the bicycle_work branch and look at examples/rollingdisc/ rollingdisc_lib.py. All the functions in that file were generated using Sympy/PyDy and include the equations of motion in first order form. In that particular example, the mass matrix is diagonal, so inversion is trivial. In general though this is not the case and for larger dimensional systems, this symbolic inversion could literally take days to complete and this is what I want to avoid. Again, the reason I want to do this symbolically is so that the generated equations of motion are in first order form and no special ODE solver is needed. As far as I know the Scipy numerical integration routines and the GSL routines require equations in this form, so I would like to keep my equations in a form that can be immediately useful to those audiences with minimal hassle. ~Luke [0] -- J. P. Meijaard, Jim M. Papadopoulos, Andy Ruina, A. L. Schwab, 2007 ``Linearized dynamics equations for the balance and steer of a bicycle: a benchmark and review,'' Proceedings of the Royal Society A 463:1955-1982. On Sep 29, 7:34 pm, Alan Bromborsky abro...@verizon.net wrote: Luke wrote: I also check the GSL (GNU Scientific Library). They have a nice numerical integrator, but it doesn't allow for a mass matrix. ~Luke On Sep 29, 4:44 pm, Luke hazelnu...@gmail.com wrote: Yes, this is something I should look into. I am pretty sure that the Netlib codes have this functionality, but it hasn't been wrapped into the Python scientific packages that I know of, at least not yet. scipy.integrate has odeint and ode, but both need everything in first order form, no mass matrix is allowed. I figured that if I was going to work symbolically, I may as well go as far as I can go, so if I can invert the matrices symbolically, I'd prefer that. This would also be nice because then the equations could be integrated with any numerical integrator out there, as the ode formulation would be as generic as possible. ~Luke On Sep 29, 4:15 pm, Alan Bromborsky abro...@verizon.net wrote: Luke wrote: On Sep 29, 1:09 pm, Ondrej Certik ond...@certik.cz wrote: On Tue, Sep 29, 2009 at 12:49 PM, Luke hazelnu...@gmail.com wrote: I'm using Sympy from within PyDy to generate the equations of motion for mechanical systems. At the end of the day, the equations can be most generally written as: M(x) * x'' = F(x, x', t) M(x) is what is known as the mass matrix, and will in general depend on the configuration of the system (positions and angles). This matrix needs to be inverted in order to solve for x'', which then will allow for numerical integration or stability analysis. I am generating M(x) symbolically, and in some case is it sparse, but in many cases, it isn't. Each entry of the matrix is a Sympy expression, but instead of trying to invert a matrix of Sympy expressions, I introduce a dummy symbol for each non-zero entries and then invert the matrix of dummy symbols. Humble systems might have 5 degrees of freedom (so a 5x5 needs to be inverted), so this inversion isn't so bad, but beyond this, the matrix inversions take a really long time, especially when the matrices are full (no zero entries). I was thinking that it might be nice to have pre-computed matrix inverses for n x n matrices. Matrix inversion is O(n^3), so it would be nice to have all this precomputed symbolically, and this would greatly speed up Sympy's matrix capabilities. Inverses up to say 100x100 could be computed (or maybe something smaller), and then when you need an inverse, everything would be fast. This could also be used behind the scenes (by introduction of symbolic substitution dictionaries) for inverting a matrix full of sympy expressions. The inversion of a 100x100 dense matrix would be quite a big mess, wouldn't it? Yes, it would be disaster. But I see what you mean, and I think it makes sense to cache it, if it speeds things up. But see below. Does anybody know if this has been done by somebody somewhere, or have any other ideas on how it could be done better than the way I suggested? I would first try to profile the inversion code to see why it is slow. Because for example the adjoint method is just a ratio of two determinants, so it may be the determinants calculation that is slow (and should be cached). However, there are 100^2 different determinants (right?), but I guess caching 1 expressions should still be doable
[sympy] Re: Symbolic matrix inversion
On Sep 30, 8:39 am, Luke hazelnu...@gmail.com wrote: The methods you suggest essentially takes care of the mass matrix problem by solving a linear system numerically during numerical integration. I am familiar with tools out there that do this, but this isn't what I'm looking to do. I haven't seen one that is written directly usable in Python -- do you know of one? The netlib packages have this capability, but I'm no Fortran programmer. What I am interested in doing is solving the linear system symbolically so that first order equations can be generated symbolically and the most generic of ODE solvers will work. This also eliminates the iteration that is being done by the ODE solver during time integration. By eliminating iteration here I mean eliminating the iterations of the root finding / linear system solving algorithm, not adaptive time stepping type iteration. ~Luke Thanks, ~Luke On Sep 29, 8:07 pm, Tim Lahey tim.la...@gmail.com wrote: On Sep 29, 2009, at 7:15 PM, Alan Bromborsky wrote: Are there differential equation solvers where you don't have to invert the matrix? A Newmark-Beta scheme will directly solve a second-order system of ODEs. The standard form uses iteration to solve the system so no inversion is necessary. For linear second-order problems you can rewrite things to use matrix algebra. For more information, I recommend Bathe and Wilson, Klaus-Jürgen Bathe and Edward L. Wilson. Numerical Methods in Finite Element Analysis. Prentice Hall, Englewood Cliffs, New Jersey, 1976. There are other second order solvers out there too. Cheers, Tim. --- Tim Lahey PhD Candidate, Systems Design Engineering University of Waterloohttp://www.linkedin.com/in/timlahey --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
[sympy] Preventing expansion
I feel like I've seen code for this on the mailing list or IRC but after some searching wasn't able to find it. Is it possible to prevent something like (x*y)**2 from being expanded to x**2*y**2? I tried an expand=False option to Mul and Pow, as in: Mul(x*y, x*y, expand=False) Pow(x*y, 2, expand=False) but this didn't do it. Is there a way? Thanks, ~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 -~--~~~~--~~--~--~---
[sympy] GSoC project mentoring
Hello, I did a Sympy GSoC project in 2009 on a package called PyDy [0]. PyDy depends intimately on SymPy, but currently the two projects are maintained separately. The basic functionality of PyDy is to provide a set of classes which ease kinematic and dynamic analysis of mechanical systems that obey the laws of Newtonian Mechanics. PyDy relies on the core symbolic functionality of SymPy in a way similar to the Geometric Algebra module (sympy/GA.py). By the end of my GSoC summer, PyDy was very functional and I had created 12 examples of use for deriving equations of motion for both trivial (pendulum) and non- trivial (rolling coin, rolling torus, bicycle--almost) mechanical systems. Sadly, the project has seen very little activity since my GSoC project. There are two students in my lab who are interested in helping develop and improve PyDy. One of the ideas we have been discussing is how the core functionality of PyDy really depends on Sympy and we think it would make more sense to have PyDy as a module of Sympy, probably in sympy/physics or maybe in sympy/pydy (or some other place?). This way, it would be more like a library that can be imported along with Sympy if you want to formulate study symbolic equations of motion. A few advantages of this approach are: -- Code updates to sympy wouldn't break pydy functionality since the core testing would be done together -- PyDy would be available to anybody who installs sympy. This could be really helpful for both projects because there are many physics, math, and engineering students (both grad and undergrad) who need to do some basic 3D vector symbolic vector analysis, and keeping pydy within sympy would make this much easier than it currently is. -- We could maintain a separate source tree for detailed examples of use, which depend on many other tools besides Sympy, and don't make sense to have distributed with sympy. -- Developers of PyDy would be more connected to Sympy and vice-versa, which would be a win for both groups. What do people think of this idea? A fair bit of work needs to be done to make the pydy code compliant with they sympy project -- doctests and docstrings need to be improved, but most of the testing of PyDy's functionality is already implemented. Back to the topic of GSoC, there are many other aspects of PyDy that need work besides the possibility of integrating it into sympy. Here are a few items: -- Class hierarchy needs to be re-evaluated/re-designed to include some notion of the system (all bodies, particles, applied forces/ torques, generalized coordinates, degrees of freedom, etc.). Currently all of this is embedded in the Point and ReferenceFrame classes and is a bit hackish. -- Handling of closed kinematic loops (four-bar linkage) needs to be improved -- Templates for outputting boilerplate animation code to enable immediate visualization after symbolic derivation. -- Improvement of LaTeX printing for vector expressions. We are working on a document outlining these things in more detail, we have made it public here: https://docs.google.com/document/d/1Egkw9VkXcIYOiXonKFGRU00gycoA7w4Oq4M085d0fAg/edit?hl=en I would like to ensure that work on Pydy is beneficial for the Sympy project. Pydy is fairly heavy on the trigonometry and in the past I ran into snags in various aspects of trigsimp. Part of this was probably avoidable for reasons I won't go into here, but part of it was due to aspects of sympy that needed improvement. I see this as place of technical overlap where work on PyDy will help improve Sympy. Another place where PyDy can help SymPy is by bringing more uses to Sympy -- every physics and engineering student has to take a dynamics class in which aspects of PyDy could be very beneficial to their studies and this in turn would expose more people to Sympy. By tying something this ubiquitous to Sympy, I think the user base would both grow and be diversified. The two students in my lab that are interested should be posting introduction emails shortly, and they are working on familiarizing themselves with the Sympy source tree and identifying an issue that they can fix and submit a patch for. They will be adding their proposals to the wiki and notifying the mailing list as well. Seeing as both of these students are in my lab, I would be willing to mentor them for the GSoC projects, should they be accepted. We use git and python extensively in our lab so some of the hurdles in the development process should be lowered by the resources and experience of the people in my lab. This will help both students to hit the ground running a lot more quickly. Cheers, ~Luke [0] -- pydy.org -- 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.
[sympy] Re: GSoC project mentoring
Aaron, Thanks for the suggestion about PSF. However, to me it seems natural though to apply to Sympy rather than PSF because PyDy is completely and wholly dependent on Sympy -- it can't work without it. All development of it requires interfacing with and using Sympy's functionality, not just Python. This is in contrast to something like mpmath, which can operate standalone, but also can operate with sympy, which in that case it makes sense to keep the two project separate. I am in favor of including PyDy (or some part of it) as a module of Sympy for two reasons. First, it helps with the testing of PyDy by ensuring changes to Sympy don't break PyDy functionality. Second, when working on things such as the trig branch, where most of the simplification cases came directly from my work within PyDy, it makes it easier to write tests for sympy that ensure the functionality of PyDy. The separation between the two projects simply made concurrent development of both harder, IMHO. An example of this would be GA package benefiting from being part of Sympy and the testing framework that is in place. It would be great for PyDy to have this same type of benefit, and I think it would really help the development of both. As Ondrej said, PyDy is pretty small, so it wouldn't be a huge addition to sympy as far as the number of lines of code or number of files. With regard to the trig branch -- I think it would be great to finish up as well. In retrospect however, I think I was a bit naive as to how difficult this would be. Many aspects of it are non-trivial. I'm not sure this is something that can be easily done as a side project but rather needs the full attention of a couple of people, which explains why it is in the state it is in. I'll give it a look, but it hasn't been touched since June 26, 2009, so there may be quite a lot that breaks once I rebase from the current master. ~Luke On Apr 5, 3:02 pm, Aaron Meurer asmeu...@gmail.com wrote: I agree with Ondrej. Since PyDy is (still at least) separate form SymPy, another idea regarding GSoC would be to apply to work under the umbrella of Python. Seehttp://wiki.python.org/moin/SummerOfCode/2011. You have to fill out an application to work under them this year. I would also look at PSU (and whatever others). I say this because the competition for SymPy might be high this year (depending on how many slots Google gives us). But again, remember that you don't have much time, as the deadline for student applications is Friday. And remember that if the students apply to SymPy they need to submit at patch that gets merged in (like everyone else). On Tue, Apr 5, 2011 at 2:37 PM, Ondrej Certik ond...@certik.cz wrote: Hi Luke, On Tue, Apr 5, 2011 at 1:08 PM, Luke hazelnu...@gmail.com wrote: Hello, I did a Sympy GSoC project in 2009 on a package called PyDy [0]. PyDy depends intimately on SymPy, but currently the two projects are maintained separately. The basic functionality of PyDy is to provide a set of classes which ease kinematic and dynamic analysis of mechanical systems that obey the laws of Newtonian Mechanics. PyDy relies on the core symbolic functionality of SymPy in a way similar to the Geometric Algebra module (sympy/GA.py). By the end of my GSoC summer, PyDy was very functional and I had created 12 examples of use for deriving equations of motion for both trivial (pendulum) and non- trivial (rolling coin, rolling torus, bicycle--almost) mechanical systems. Sadly, the project has seen very little activity since my GSoC project. There are two students in my lab who are interested in helping develop and improve PyDy. One of the ideas we have been discussing is how the core functionality of PyDy really depends on Sympy and we think it would make more sense to have PyDy as a module of Sympy, probably in sympy/physics or maybe in sympy/pydy (or some other place?). This way, it would be more like a library that can be imported along with Sympy if you want to formulate study symbolic equations of motion. A few advantages of this approach are: -- Code updates to sympy wouldn't break pydy functionality since the core testing would be done together -- PyDy would be available to anybody who installs sympy. This could be really helpful for both projects because there are many physics, math, and engineering students (both grad and undergrad) who need to do some basic 3D vector symbolic vector analysis, and keeping pydy within sympy would make this much easier than it currently is. -- We could maintain a separate source tree for detailed examples of use, which depend on many other tools besides Sympy, and don't make sense to have distributed with sympy. -- Developers of PyDy would be more connected to Sympy and vice-versa, which would be a win for both groups. What do people think of this idea? A fair bit of work needs to be done to make the pydy code
[sympy] class design / modelling
Does anybody here use any class modelling tools to help design class hierarchies before they begin implementing them? For most things I've done, I've just jumped in and started coding, but in I think I might like to explore tools that encourage more upfront thought on the design before the coding starts. I've checked out this wikipedia page: http://en.wikipedia.org/wiki/List_of_UML_tools and it seems like many of these tools are implemented as Eclipse plugins and pretty much all are based on UML, does anybody here have any experience with any of them, or have any thoughts on this approach to class design? ~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.
Re: [sympy] Question regarding vectors
Here is a more explicit example of what Gilbert is talking about: In [1]: from sympy import * In [2]: from pydy import * In [3]: x = symbols('x') In [4]: N = ReferenceFrame('N') In [5]: type(N[1]) Out[5]: pydy.pydy.UnitVector In [9]: test = x*N[1] + x*x*N[2] In [10]: type(test) Out[10]: sympy.core.add.Add In [11]: test2 = Vector(test) In [12]: test2 Out[12]: x*n1 + x**2*n2 In [13]: type(test2) Out[13]: pydy.pydy.Vector In [14]: test3 = x*test2 In [15]: test3 Out[15]: x*x*n1 + x**2*n2 In [16]: type(test3) Out[16]: sympy.core.mul.Mul As you can see, in Out[15], the multiplication of x and test2 is being printed in a way that doesn't make sense, and in Out[16] we can see that this multiplication isn't resulting in another Vector object, instead it is of type Mul. Currently, to create a Vector object, you need to explicitly call Vector on a sympy expression that is composed from terms that have UnitVectors in them, or pass a dictionary with UnitVectors as the keys and sympy expressions as the values. Once you have that Vector object, you might want to multiply it by a scalar (sympy expression) and have it return another Vector object. This could be done using a somewhat user unfriendly approach: In [22]: Vector(dict([(k, x*v) for k, v in test2.dict.items()])) Out[22]: x**2*n1 + x**3*n2 This gets the job done, but it isn't very convenient. So basically, the question is whether 1) Is it easy enough in Sympy to make something like x*aVectorObject evaluate to another Vector object? Where the x is a scalar part (probably a sympy Expression) and aVectorObject is of type Vector (which currently subclasses from Basic)? 2) Or is it ok to have to be more explicit about creating Vector objects by using the notation Vector(x**2*N[1] + x**3*N[2]) or Vector({N[1]: x**2, N[2]:x**3})? Additionally, there are other types of products that make sense for Vector and UnitVector objects, namely dot, cross, and outer products. So the stuff above would only be for multiplying a Vector by a scalar. I think all the other types of products have to make use of explicit method calls since there would be no way to know which type of product would be implied. ~Luke On Mon, May 9, 2011 at 4:23 PM, Gilbert Gede gilbertg...@gmail.com wrote: In PyDy (which we plan to merge into SymPy.physics.classical this summer) Vector is one of the classes already implemented (along with UnitVector). Vectors extend Basic, and UnitVector extend Expr. The way it works now, you can't use Vector as part of a SymPy expression: In [57]: test Out[57]: x*n1 + x*a1 In [58]: x*test*x Out[58]: x**2*x*n1 + x*a1 Do people want to be able to use Vector (which comes with dot, cross, outer products, and derivative (between reference frames) functions implemented) in SymPy expressions? Or is it the type of thing no one really wants? I'm looking forward to getting to work on PyDy SymPy this summer. -Gilbert -- 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. -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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.
Re: [sympy] Question regarding vectors
Can the vectors and multivectors in the GA module work with arbitrary sympy expressions? i.e, if v is a GA vector, and s is a sympy expression, does it make sense to do: s*v? Is the result of type Mul or of something else? ~Luke On Mon, May 9, 2011 at 5:42 PM, Alan Bromborsky abro...@verizon.net wrote: On 05/09/2011 08:30 PM, Luke wrote: Here is a more explicit example of what Gilbert is talking about: In [1]: from sympy import * In [2]: from pydy import * In [3]: x = symbols('x') In [4]: N = ReferenceFrame('N') In [5]: type(N[1]) Out[5]: pydy.pydy.UnitVector In [9]: test = x*N[1] + x*x*N[2] In [10]: type(test) Out[10]: sympy.core.add.Add In [11]: test2 = Vector(test) In [12]: test2 Out[12]: x*n1 + x**2*n2 In [13]: type(test2) Out[13]: pydy.pydy.Vector In [14]: test3 = x*test2 In [15]: test3 Out[15]: x*x*n1 + x**2*n2 In [16]: type(test3) Out[16]: sympy.core.mul.Mul As you can see, in Out[15], the multiplication of x and test2 is being printed in a way that doesn't make sense, and in Out[16] we can see that this multiplication isn't resulting in another Vector object, instead it is of type Mul. Currently, to create a Vector object, you need to explicitly call Vector on a sympy expression that is composed from terms that have UnitVectors in them, or pass a dictionary with UnitVectors as the keys and sympy expressions as the values. Once you have that Vector object, you might want to multiply it by a scalar (sympy expression) and have it return another Vector object. This could be done using a somewhat user unfriendly approach: In [22]: Vector(dict([(k, x*v) for k, v in test2.dict.items()])) Out[22]: x**2*n1 + x**3*n2 This gets the job done, but it isn't very convenient. So basically, the question is whether 1) Is it easy enough in Sympy to make something like x*aVectorObject evaluate to another Vector object? Where the x is a scalar part (probably a sympy Expression) and aVectorObject is of type Vector (which currently subclasses from Basic)? 2) Or is it ok to have to be more explicit about creating Vector objects by using the notation Vector(x**2*N[1] + x**3*N[2]) or Vector({N[1]: x**2, N[2]:x**3})? Additionally, there are other types of products that make sense for Vector and UnitVector objects, namely dot, cross, and outer products. So the stuff above would only be for multiplying a Vector by a scalar. I think all the other types of products have to make use of explicit method calls since there would be no way to know which type of product would be implied. ~Luke On Mon, May 9, 2011 at 4:23 PM, Gilbert Gedegilbertg...@gmail.com wrote: In PyDy (which we plan to merge into SymPy.physics.classical this summer) Vector is one of the classes already implemented (along with UnitVector). Vectors extend Basic, and UnitVector extend Expr. The way it works now, you can't use Vector as part of a SymPy expression: In [57]: test Out[57]: x*n1 + x*a1 In [58]: x*test*x Out[58]: x**2*x*n1 + x*a1 Do people want to be able to use Vector (which comes with dot, cross, outer products, and derivative (between reference frames) functions implemented) in SymPy expressions? Or is it the type of thing no one really wants? I'm looking forward to getting to work on PyDy SymPy this summer. -Gilbert -- 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. GA module has vectors and multivectors. See documentation http://docs.sympy.org/dev/modules/galgebra/GA/GAsympy.html -- 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. -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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.
Re: [sympy] Question regarding vectors
Alan, From what I can see in GA.py, you have one class MV, which doesn't derive from anything, and then you use the setup method to somehow inject MV objects into the global namespace. So, then, if x is a sympy expression, and e is a MV object: type(x*e) == type(e*x) == class 'sympy.galgebra.GA.MV' This is the sort of behavior I would like to have as far as scalar multiplication of a UnitVector or Vector by a sympy expression goes. It looks like you achieved this by defining the __mul__ and __rmul__ methods in the MV class, which then call your geometric_product method. In geometric_product, if only one of the operands is a MV object, you assume the other is a scalar and call the scalar_mul method, which then does the distribution of the scalar across all the elements in self.mv. A bit surpisingly, you seem to depend self.mv being a numpy.ndarray for this to work properly, but I am sure you have some reasons for this. The question then seems to be what are the benefits or drawbacks of subclassing from Expr? Perhaps if few or none of the methods in Expr would make sense to call on UnitVector or Vector objects, they shouldn't subclass from Expr and instead should just be standalone classes that implement only the methods that make sense for them, including the __mul__ and __rmul__ methods, as Alan did in his MV class? ~Luke On Tue, May 10, 2011 at 5:44 AM, Alan Bromborsky abro...@verizon.net wrote: The assumption is that the expression multiplying the vector (multivector) is a scalar and the result is a vector. The geometric algebra is instantiated by defining a set of abstract vectors say e1, e2, e3, e4 and the dot product of all pairs of the vectors. These dot products can be symbols or numbers. The default option is that the dot product of ei and ej is the symbol eidotej and printed as ei.ej. The operator for the dot product is | so that print e1|e2 returns (e1.e2). Thus if you define vectors - (a1,a2,b1,and b2 are sympy symbols) a = a1*e1+a2*e2 b = b1*e1+b2*e2 Then there are three products print a|b - a1*b1*(e1sq)+a2*b2*(e2sq)+(a1*b2+a2*b1)*(e1.e2) where in the dot product e1.e2 = e2.e1 print a*b - a1*b1*(e1sq)+a2*b2*(e2sqr)+a1*b2*(e1e2)+a2*b1*(e2e1) where in the geometric product e1*e1=e1sq and e2*e2=e2sq print a^b - (a1*b2-a2*b1)*(e1^e2) where in the wedge product e1^e1=e2^e2=0 and e1^e2=-e2^e1 The geometric product of two vectors can be reduced via a*b = a|b+a^b using e1*e1 = e1sq, e2*e2 = e2sq, e1*e2 = (e1.e2)+e1^e2, and e2*e1 = (e1.e2)+e2^e1 = (e1.e2)-e1^e2. Also a|b = (a*b+b*a)/2 and a^b = (a*b-b*a)/2 On 05/09/2011 08:51 PM, Luke wrote: Can the vectors and multivectors in the GA module work with arbitrary sympy expressions? i.e, if v is a GA vector, and s is a sympy expression, does it make sense to do: s*v? Is the result of type Mul or of something else? ~Luke On Mon, May 9, 2011 at 5:42 PM, Alan Bromborskyabro...@verizon.net wrote: On 05/09/2011 08:30 PM, Luke wrote: Here is a more explicit example of what Gilbert is talking about: In [1]: from sympy import * In [2]: from pydy import * In [3]: x = symbols('x') In [4]: N = ReferenceFrame('N') In [5]: type(N[1]) Out[5]: pydy.pydy.UnitVector In [9]: test = x*N[1] + x*x*N[2] In [10]: type(test) Out[10]: sympy.core.add.Add In [11]: test2 = Vector(test) In [12]: test2 Out[12]: x*n1 + x**2*n2 In [13]: type(test2) Out[13]: pydy.pydy.Vector In [14]: test3 = x*test2 In [15]: test3 Out[15]: x*x*n1 + x**2*n2 In [16]: type(test3) Out[16]: sympy.core.mul.Mul As you can see, in Out[15], the multiplication of x and test2 is being printed in a way that doesn't make sense, and in Out[16] we can see that this multiplication isn't resulting in another Vector object, instead it is of type Mul. Currently, to create a Vector object, you need to explicitly call Vector on a sympy expression that is composed from terms that have UnitVectors in them, or pass a dictionary with UnitVectors as the keys and sympy expressions as the values. Once you have that Vector object, you might want to multiply it by a scalar (sympy expression) and have it return another Vector object. This could be done using a somewhat user unfriendly approach: In [22]: Vector(dict([(k, x*v) for k, v in test2.dict.items()])) Out[22]: x**2*n1 + x**3*n2 This gets the job done, but it isn't very convenient. So basically, the question is whether 1) Is it easy enough in Sympy to make something like x*aVectorObject evaluate to another Vector object? Where the x is a scalar part (probably a sympy Expression) and aVectorObject is of type Vector (which currently subclasses from Basic)? 2) Or is it ok to have to be more explicit about creating Vector objects by using the notation Vector(x**2*N[1] + x**3*N[2]) or Vector({N[1]: x**2, N[2]:x**3})? Additionally, there are other types of products that make sense for Vector and UnitVector objects, namely dot, cross, and outer
Re: [sympy] Re: Question regarding vectors
The dot and cross products are implemented at the lowest level in UnitVector, and the Vector class simply calls these methods on all of the UnitVector objects that comprise it when these methods are called on a Vector class. dot and cross functions are provided as convenience wrapper functions around the class methods, so the user can choose to use whichever approach is more natural to them. ~Luke On Tue, May 10, 2011 at 11:02 AM, Vinzent Steinberg vinzent.steinb...@googlemail.com wrote: On 10 Mai, 03:30, Ronan Lamy ronan.l...@gmail.com wrote: Please, try to make the interface dot(v1, v2), and not v1.dot(v2). While I agree that it looks cleaner for the simple case, I would prefer v1.dot(v2).dot(v3) over dot(dot(v1, v2), v3) For the dot product it does of course not make sense to multiply three vectors in a row, but I think we should keep this in mind in general for user defined operations. Vinzent -- 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. -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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.
Re: [sympy] Re: Who uses SymPy?
This was pretty much my experience as well. I was introduced to Python in a graduate course and made the migration from Matlab over to Python over the course of a couple of years. In engineering there are few people using open source tools, I think mostly because people get used to doing things a certain way and don't want to change, and the vast majority of the software taught in engineering curriculum is proprietary. This makes it really hard to use open source tools and collaborate with other people in engineering because they often simply aren't willing to invest the time in learning new tools. In some cases, there isn't a viable open source tool to do the job, but often this isn't the case. Companies like Mathworks have gotten into bed with engineering departments and designed the course curriculum to be centered around tools like Matlab, so the level of entrenchment is quite deep. At the UC system though, with the financial trouble we are in, software licenses take a big chunk out of the budget, and people are starting to realize you can achieve many of the same things using FOSS. So maybe initially the motivation will be financial in nature, but I think all the other benefits of FOSS will become clear to these people once they take the time to try it. But there is a whole generation of entrenchment that will eventually retire and make room for open source, so I see things getting better as time goes on. ~Luke On Thu, May 12, 2011 at 10:32 AM, Sherjil Ozair sherjiloz...@gmail.com wrote: On Thu, May 12, 2011 at 9:07 PM, Cory Dominguez corydoming...@gmail.com wrote: As a very small response to this question. My name is Cory Dominguez and I am a physics major at University of California at Santa Cruz. I am new to this group but I am interested in contributing. This quarter I am taking a class is Computational Physics where we have mainly looked at numerical analysis with c++ and for the second half of the quarter we get a crash course in Mathematica and do some symbolic analysis. I had heard of Sage through my various stumbles around the internet and I am a great fan of python. At least at my university, none of the professors I have talked to even know of the open source tools available today. They rely instead on software like Mathematica and Maple. I really wish that I had been aware of software like matplotlib, numpy, and sympy during my lower division courses. I think it could of increased my understanding tremendously. In my opinion if you make undergraduates aware of these tools and they are allowed to get used to them as they take their fundamental courses, then you lay a good foundation for this group in the future. I remember how stoked I was to get a TI-89 calculator, learning about sympy was like christmas. Exactly my feelings too, when I got to know about Sympy. :) SymPy sure needs more advertising. But maybe, we'll focus on that when we hit 1.0, I think. Thanks for the reply, Cory. Cheers, Cory On Thu, May 12, 2011 at 9:51 AM, SherjilOzair sherjiloz...@gmail.com wrote: A very smart and to-the-point question, Matthew. I've been wanting the answer to this question myself when working on my project. The answer to this question is critical for code writing. Another issue I would like to raise, that I believe is related to this topic, is a phrase in the Sympy Mission, … while keeping the code as simple as possible in order to be comprehensible and easily extensible. How do we, as coders, follow this maxim ? Do we sacrifice performance for readability ? Or is this line just their to emphasize our choice of choosing python as our language. A notable example which doesnt follow this guideline is the Polys internals. Comments ? As to the original question, is there any data of where/how Sympy is used ? If not, can we start collecting such data ? Thanks Matthew, once again, to raise such an important question. -Sherjil Ozair On May 12, 8:14 pm, Matthew Rocklin mrock...@gmail.com wrote: Do we have a clear understanding of who our userbase is? Is SymPy being used for education? for research in academia? in industry? I imagine the answer is that yes, it's being used in all of those places. Does anyone know the extent to which it's used in these contexts? While designing I'd like to know what audience I should target. Best, -Matt -- 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. -- 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
Re: [sympy] Re: Question regarding vectors
Gilbert, I prefer this notation: B = ReferenceFrame('B') and then to access the basic vectors of that frame, to use one of the following approaches: B.x, B.y, B.z or, B.i, B.j, B.k You could view the ReferenceFrame class as a container object for the basis vectors and implement the __iter__() method to iterate over the basis vectors in the following way: v = a*B.i + b*B.j + B.k for basisvector in B: dot(v, basisvector) Since we are restricting ourself to basis vectors in R^3, we probably don't need all the other methods typical of a container object, I think __iter__() would be enough. My vote is to go with the ijk or xyz syntax and not use the __getitem__() method that allows for B[1]. This will mean some work to change things from how they are currently implemented in PyDy, but I think the syntax is cleaner and more concise. What do other people think about this? Another thing to think about though is how you will print the basis vectors, both to the screen and to LaTeX. Currently, PyDy prints UnitVectors as b1, b2, b3, and it uses unicode to make the color bright so you can distinguish UnitVectors from the scalar multiplier. For LaTeX printing, this I think should be \boldsymbol{b}_{1}, \boldsymbol{b}_x or \boldsymbol_{i}. If you go with the ijk syntax, bi, bj, bk might work but in most physics/math books I have seen they typically only use \hat{\boldsymbol{i}}, etc, and typically this is in settings where you don't have many different reference frames to distinguish between, so the syntax isn't ambiguous. On the other hand, I have seen \boldsymbol{b}_x, etc, so perhaps this might be more common and familiar to some users? It is a pretty minor difference, so I say you pick one you think is most likely to appeal to the widest audience and stick with it. This might also be something that could have a default value, but could be customized -- I have seen subscripts of ijk, xyz, 012, or 123 in various classical mechanics literature. The problem with the numbered subscripts is that while B.y or B.j would work, B.2 wouldn't work since 2 isn't a valid variable name. I'm not sure what the best solution would be for this if we were to try to allow for customizing the subscripts. I guess this is why the syntax of: b1, b2, b3, B = ReferenceFrame('B') might be desirable, I just feel like it might be more typing than is desirable in most cases. Do any of the physics people out there have thoughts on what syntax would be nicest for physics students? We definitely want to keep the syntax familiar to that potential user base, but we also need to make sure we can accommodate many different reference frames which is common in multibody dynamics. ~Luke On Fri, May 13, 2011 at 6:29 PM, Gilbert gede gilbertg...@gmail.com wrote: So I think we've decided to make a new Vector class, to replace the previous UnitVector and Vector classes, and it will not extend any other sympy classes. It will use sympy's matrix class. The current plan is for each vector to have a list of lists; the inner list will be the coefficients of each basis vector and the frame they belong to, and the outer list will store the inner list for each frame. It will be something like: [[(1,2,1),B],[(4,2,1),N]] As for operations, we're currently leaning towards writing operators for Vector, and then wrapping them with Dot, Cross, etc. So if A B are Vectors, and t a scalar: A*t would call Vector.__mul__ Dot(A,B) would call Vector.__and__ , maybe? We're still deciding on which operators to use for dot and cross products. Does this seem like an good solution? Allowing one user interface that is unambiguous but longer and a shorter, rougher option? I think this will all work out nicely, as once you have the basis vectors instantiated, you'll control what is returned by every operation. This leads to the final thing we're trying to decide; how to use the three basis vectors. It's between calling something like: b1,b2,b3,B = ReferenceFrame('B'), where b1 is a Vector with contents [[(1,0,0),B]], etc or B = ReferenceFrame('B') and then access the basis vectors as B[1], B[2], B[3] or B.x,B.y,B.z or B.i, B.j, B.k What are people's opinions here? Should the basis vectors be linked with the frame they are created with? Or should they be independent in the namespace? -Gilbert On May 11, 1:18 pm, Ronan Lamy ronan.l...@gmail.com wrote: Le mardi 10 mai 2011 à 11:37 -0700, Luke a écrit : The dot and cross products are implemented at the lowest level in UnitVector, and the Vector class simply calls these methods on all of the UnitVector objects that comprise it when these methods are called on a Vector class. dot and cross functions are provided as convenience wrapper functions around the class methods, so the user can choose to use whichever approach is more natural to them. Not making a choice between the two options might seem easiest in the short term but it's actually
[sympy] Problem with user-defined functions
Hi eveyone, I'm developing an web application which has to interact with user- defined formulas of some financial kpis. I decided to use sympy to have a more solid math engine. Basically the input I reiceve is very simple, it might be in the worst case something like: kpi - (log(sum('production'))*count('sales')/min('spread') (this formula is totally made-up) I defined some functions to interact with the database according to the official docs and they seem to be working: For example defining from sympy.core.function import Function class SUM(Function): nargs = 2 @classmethod def eval(cls, arg): map = Code(function () { emit(sum,{%(field)s:this.%(field)s}); } % {'field':arg}) reduce = Code( function(key, values) { var sum = 0; values.forEach(function(doc) { if (doc.%(field)s != undefined){ sum += doc.%(field)s; } }); return {%(field)s:sum}; }; % {'field':arg}) result = db.people.map_reduce(map, reduce, myresults) return result.find_one()['value'][unicode(arg)] #EOF Then from the command line I can type: print SUM(field) 1923 But when I try to use sympify my function doesn't evaluate.. print sympify(SUM('field')).evalf() SUM(field) N(SUM('field')) SUM(field) Am I doing anything wrong? Thanks in advance! -- 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.
[sympy] Re: Problem with user-defined functions
Oh, thanks a lot. Now it's working fine. Now the only problem is that the code is evaluated when calling sympify, and not when calling evalf. Could I ask you what is the way to keep the function lazy? I explain myself better. Since the function SUM has to operate on a database if I have something like that: SUM('field') + SUM('field') + SUM('field') #not lazy, computes immediately three queries 1234 I'm doing the same operation three times and this is not very good in terms of performances, what I expected would have been: a = SUM('field') + SUM('field') + SUM('field') - 3SUM('field') # one single query print a 3*SUM('field') print N(a) 1234 just like other functions work. e.g. log(10)+log(10)+log(10) 3*log(10) On Jun 2, 9:38 am, Mateusz Paprocki matt...@gmail.com wrote: Hi, On 2 June 2011 09:07, luke luca.giaco...@gmail.com wrote: Hi eveyone, I'm developing an web application which has to interact with user- defined formulas of some financial kpis. I decided to use sympy to have a more solid math engine. Basically the input I reiceve is very simple, it might be in the worst case something like: kpi - (log(sum('production'))*count('sales')/min('spread') (this formula is totally made-up) I defined some functions to interact with the database according to the official docs and they seem to be working: For example defining from sympy.core.function import Function class SUM(Function): nargs = 2 @classmethod def eval(cls, arg): map = Code(function () { emit(sum,{%(field)s:this.%(field)s}); } % {'field':arg}) reduce = Code( function(key, values) { var sum = 0; values.forEach(function(doc) { if (doc.%(field)s != undefined){ sum += doc.%(field)s; } }); return {%(field)s:sum}; }; % {'field':arg}) result = db.people.map_reduce(map, reduce, myresults) return result.find_one()['value'][unicode(arg)] #EOF Then from the command line I can type: print SUM(field) 1923 Very interesting application. I'm not sure if you are familiar with this, but staying on the safe side note here that SUM(field) doesn't do exactly what you expect, but the outcome is fine. Usually, SymPy's functions don't accept raw string arguments, but sympify() them: In [1]: class fun(Function): ...: nargs = 1 ...: @classmethod ...: def eval(cls, arg): ...: print type(arg) ...: ...: In [2]: fun('abc') class 'sympy.core.symbol.Symbol' Out[2]: fun(abc) So in eval() you got a symbol not string 'abc', but as str() of a Symbol is simply the name of the symbol, then this (and your code) works as expected: In [3]: print ---%s--- % Symbol('abc') ---abc--- But when I try to use sympify my function doesn't evaluate.. print sympify(SUM('field')).evalf() SUM(field) N(SUM('field')) SUM(field) The problem here is that SymPy, precisely speaking sympify(), doesn't know what SUM() is, because SUM() resides in the global namespace of the interpreter, which is unknown to sympify(), e.g.: In [4]: sympify(whatever(10)) Out[4]: whatever(10) whatever() is unknown to sympify(), so a new Function object is constructed for it. The same for fun() which I defined above: In [6]: sympify(fun(10)) Out[6]: fun(10) To overcome this, pass globals() to sympify(), e.g.: In [7]: sympify(fun(10), globals()) class 'sympy.core.numbers.Integer' Out[7]: fun(10) (in your case this will be sympify(SUM('field'), globals())). Am I doing anything wrong? Thanks in advance! -- 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. Mateusz -- 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.
[sympy] Re: Problem with user-defined functions
Actually you're wrong. Every instance of a class in python has its own attributes and editing the attributes of one instance of a class wont modify the attributes of the other classes. Try: class MyClass: def __init__(self,var): self.var=var then execute: a = MyClass(10) print a.var 10 b = MyClass(20) print b.var 20 print a.var, b.var 10 20 This said, my code might effectively not be the best one but my issue is that in _eval_evalf(cls,arg) the value of arg is not a symbol but is a float (57 in my case, probably is an index of some internal variable.. I can't find any documentation about that). So it's pretty unusable, that's why I set cls.arg. However the code is working so thanks everybody. On Jun 2, 7:01 pm, Ronan Lamy ronan.l...@gmail.com wrote: Le jeudi 02 juin 2011 à 09:35 -0700, luke a écrit : Yes, that worked. But I had to restructure the code class SUM(Function): nargs = 2 @classmethod def eval(cls, arg): cls.arg=arg @classmethod def _eval_evalf(cls, arg): map = Code(function () { emit(sum,{%(field)s:this.%(field)s}); } % {'field':cls.arg}) reduce = Code( function(key, values) { var sum = 0; values.forEach(function(doc) { if (doc.%(field)s != undefined){ sum += doc.%(field)s; } }); return {%(field)s:sum}; }; % {'field':cls.arg}) result = db.people.map_reduce(map, reduce, myresults) return result.find_one()['value'][unicode(cls.arg)] Because arg in _eval_evalf was strangely enough a float (more precisely 57, have no clue why :) ). Thank you all guys! Your implementation won't work correctly: _eval_evalf needs to be an ordinary method of the instance in order to access to the argument of the function. Note that SUM is a class and that SUM('some_field') is an instance of it, so each time you set SUM.arg, all SUM calls will see it and since it's reset every time you call SUM(...), you'll get this: a = SUM('some_field'); SUM('other_field') a.evalf() - result for SUM('other_field') So you do need to follow my advice exactly - and remove eval(). On Jun 2, 6:07 pm, Ronan Lamy ronan.l...@gmail.com wrote: Le jeudi 02 juin 2011 à 08:03 -0700, luke a écrit : Oh, thanks a lot. Now it's working fine. Now the only problem is that the code is evaluated when calling sympify, and not when calling evalf. Could I ask you what is the way to keep the function lazy? I explain myself better. Since the function SUM has to operate on a database if I have something like that: SUM('field') + SUM('field') + SUM('field') #not lazy, computes immediately three queries 1234 I'm doing the same operation three times and this is not very good in terms of performances, what I expected would have been: a = SUM('field') + SUM('field') + SUM('field') - 3SUM('field') # one single query print a 3*SUM('field') print N(a) 1234 just like other functions work. e.g. log(10)+log(10)+log(10) 3*log(10) Note that your use case isn't handled very well by sympy (for now). Subclasses of Function are supposed to be symbolic representations of numeric functions that return numeric results for numeric arguments. But there are ways to hack around these implicit assumptions. To get lazy evaluation, the easiest is probably to use SUM('field', evaluate=False), which tells the function to store its argument without executing eval(). Then you can evaluate the expression using .doit(). You should get something like: a = SUM('field', evaluate=False) + SUM('field', evaluate=False) + SUM('field', evaluate=False) print a 3*SUM('field') print a.doit() 1234 Otherwise, you could implement your class so that the DB lookup and calculations are only done when you call evalf() - that should give you exactly the behaviour you expected above. For that, you'd have to replace your eval() classmethod with an _eval_evalf() method, e.g. def _eval_evalf(self, prec): arg = self.args[0] body of your eval() On Jun 2, 9:38 am, Mateusz Paprocki matt...@gmail.com wrote: Hi, On 2 June 2011 09:07, luke luca.giaco...@gmail.com wrote: Hi eveyone, I'm developing an web application which has to interact with user- defined formulas of some financial kpis. I decided to use sympy to have a more solid math engine. Basically the input I reiceve is very simple, it might be in the worst case something like: kpi - (log(sum('production'))*count('sales')/min('spread') (this formula is totally made-up) I defined some functions
[sympy] Re: Problem with user-defined functions
WAIT, I didn't see that you use self.arg[0]!! that's why my code was giving me 57, I just need to call cls.arg[0], great now I can remove the eval ;)! thanks again On Jun 2, 9:30 pm, luke luca.giaco...@gmail.com wrote: Actually you're wrong. Every instance of a class in python has its own attributes and editing the attributes of one instance of a class wont modify the attributes of the other classes. Try: class MyClass: def __init__(self,var): self.var=var then execute: a = MyClass(10) print a.var 10 b = MyClass(20) print b.var 20 print a.var, b.var 10 20 This said, my code might effectively not be the best one but my issue is that in _eval_evalf(cls,arg) the value of arg is not a symbol but is a float (57 in my case, probably is an index of some internal variable.. I can't find any documentation about that). So it's pretty unusable, that's why I set cls.arg. However the code is working so thanks everybody. On Jun 2, 7:01 pm, Ronan Lamy ronan.l...@gmail.com wrote: Le jeudi 02 juin 2011 à 09:35 -0700, luke a écrit : Yes, that worked. But I had to restructure the code class SUM(Function): nargs = 2 @classmethod def eval(cls, arg): cls.arg=arg @classmethod def _eval_evalf(cls, arg): map = Code(function () { emit(sum,{%(field)s:this.%(field)s}); } % {'field':cls.arg}) reduce = Code( function(key, values) { var sum = 0; values.forEach(function(doc) { if (doc.%(field)s != undefined){ sum += doc.%(field)s; } }); return {%(field)s:sum}; }; % {'field':cls.arg}) result = db.people.map_reduce(map, reduce, myresults) return result.find_one()['value'][unicode(cls.arg)] Because arg in _eval_evalf was strangely enough a float (more precisely 57, have no clue why :) ). Thank you all guys! Your implementation won't work correctly: _eval_evalf needs to be an ordinary method of the instance in order to access to the argument of the function. Note that SUM is a class and that SUM('some_field') is an instance of it, so each time you set SUM.arg, all SUM calls will see it and since it's reset every time you call SUM(...), you'll get this: a = SUM('some_field'); SUM('other_field') a.evalf() - result for SUM('other_field') So you do need to follow my advice exactly - and remove eval(). On Jun 2, 6:07 pm, Ronan Lamy ronan.l...@gmail.com wrote: Le jeudi 02 juin 2011 à 08:03 -0700, luke a écrit : Oh, thanks a lot. Now it's working fine. Now the only problem is that the code is evaluated when calling sympify, and not when calling evalf. Could I ask you what is the way to keep the function lazy? I explain myself better. Since the function SUM has to operate on a database if I have something like that: SUM('field') + SUM('field') + SUM('field') #not lazy, computes immediately three queries 1234 I'm doing the same operation three times and this is not very good in terms of performances, what I expected would have been: a = SUM('field') + SUM('field') + SUM('field') - 3SUM('field') # one single query print a 3*SUM('field') print N(a) 1234 just like other functions work. e.g. log(10)+log(10)+log(10) 3*log(10) Note that your use case isn't handled very well by sympy (for now). Subclasses of Function are supposed to be symbolic representations of numeric functions that return numeric results for numeric arguments. But there are ways to hack around these implicit assumptions. To get lazy evaluation, the easiest is probably to use SUM('field', evaluate=False), which tells the function to store its argument without executing eval(). Then you can evaluate the expression using .doit(). You should get something like: a = SUM('field', evaluate=False) + SUM('field', evaluate=False) + SUM('field', evaluate=False) print a 3*SUM('field') print a.doit() 1234 Otherwise, you could implement your class so that the DB lookup and calculations are only done when you call evalf() - that should give you exactly the behaviour you expected above. For that, you'd have to replace your eval() classmethod with an _eval_evalf() method, e.g. def _eval_evalf(self, prec): arg = self.args[0] body of your eval() On Jun 2, 9:38 am, Mateusz Paprocki matt...@gmail.com wrote: Hi, On 2 June 2011 09:07, luke luca.giaco...@gmail.com wrote: Hi eveyone, I'm developing an web application which has to interact with user- defined formulas of some
[sympy] Re: Problem with user-defined functions
Nope in spite of my enthusiasm cls.args wont work properly as it will give me a property and not a symbol :) I'll put back my eval since it worked. Hope that was of any help! On Jun 2, 9:32 pm, luke luca.giaco...@gmail.com wrote: WAIT, I didn't see that you use self.arg[0]!! that's why my code was giving me 57, I just need to call cls.arg[0], great now I can remove the eval ;)! thanks again On Jun 2, 9:30 pm, luke luca.giaco...@gmail.com wrote: Actually you're wrong. Every instance of a class in python has its own attributes and editing the attributes of one instance of a class wont modify the attributes of the other classes. Try: class MyClass: def __init__(self,var): self.var=var then execute: a = MyClass(10) print a.var 10 b = MyClass(20) print b.var 20 print a.var, b.var 10 20 This said, my code might effectively not be the best one but my issue is that in _eval_evalf(cls,arg) the value of arg is not a symbol but is a float (57 in my case, probably is an index of some internal variable.. I can't find any documentation about that). So it's pretty unusable, that's why I set cls.arg. However the code is working so thanks everybody. On Jun 2, 7:01 pm, Ronan Lamy ronan.l...@gmail.com wrote: Le jeudi 02 juin 2011 à 09:35 -0700, luke a écrit : Yes, that worked. But I had to restructure the code class SUM(Function): nargs = 2 @classmethod def eval(cls, arg): cls.arg=arg @classmethod def _eval_evalf(cls, arg): map = Code(function () { emit(sum,{%(field)s:this.%(field)s}); } % {'field':cls.arg}) reduce = Code( function(key, values) { var sum = 0; values.forEach(function(doc) { if (doc.%(field)s != undefined){ sum += doc.%(field)s; } }); return {%(field)s:sum}; }; % {'field':cls.arg}) result = db.people.map_reduce(map, reduce, myresults) return result.find_one()['value'][unicode(cls.arg)] Because arg in _eval_evalf was strangely enough a float (more precisely 57, have no clue why :) ). Thank you all guys! Your implementation won't work correctly: _eval_evalf needs to be an ordinary method of the instance in order to access to the argument of the function. Note that SUM is a class and that SUM('some_field') is an instance of it, so each time you set SUM.arg, all SUM calls will see it and since it's reset every time you call SUM(...), you'll get this: a = SUM('some_field'); SUM('other_field') a.evalf() - result for SUM('other_field') So you do need to follow my advice exactly - and remove eval(). On Jun 2, 6:07 pm, Ronan Lamy ronan.l...@gmail.com wrote: Le jeudi 02 juin 2011 à 08:03 -0700, luke a écrit : Oh, thanks a lot. Now it's working fine. Now the only problem is that the code is evaluated when calling sympify, and not when calling evalf. Could I ask you what is the way to keep the function lazy? I explain myself better. Since the function SUM has to operate on a database if I have something like that: SUM('field') + SUM('field') + SUM('field') #not lazy, computes immediately three queries 1234 I'm doing the same operation three times and this is not very good in terms of performances, what I expected would have been: a = SUM('field') + SUM('field') + SUM('field') - 3SUM('field') # one single query print a 3*SUM('field') print N(a) 1234 just like other functions work. e.g. log(10)+log(10)+log(10) 3*log(10) Note that your use case isn't handled very well by sympy (for now). Subclasses of Function are supposed to be symbolic representations of numeric functions that return numeric results for numeric arguments. But there are ways to hack around these implicit assumptions. To get lazy evaluation, the easiest is probably to use SUM('field', evaluate=False), which tells the function to store its argument without executing eval(). Then you can evaluate the expression using .doit(). You should get something like: a = SUM('field', evaluate=False) + SUM('field', evaluate=False) + SUM('field', evaluate=False) print a 3*SUM('field') print a.doit() 1234 Otherwise, you could implement your class so that the DB lookup and calculations are only done when you call evalf() - that should give you exactly the behaviour you expected above. For that, you'd have to replace your eval() classmethod with an _eval_evalf() method, e.g
[sympy] Re: Problem with user-defined functions
My bad, sorry for my inexperience with sympy, final code: (this is really working!) class SUM(Function): nargs = 1 def _eval_evalf(cls, prec): print cls.args map = Code(function () { emit(sum,{%(field)s:this.%(field)s}); } % {'field':cls.args[0]}) reduce = Code( function(key, values) { var sum = 0; values.forEach(function(doc) { if (doc.%(field)s != undefined){ sum += doc.%(field)s; } }); return {%(field)s:sum}; }; % {'field':cls.args[0]}) result = db.people.map_reduce(map, reduce, myresults) return result.find_one()['value'][unicode(cls.args[0])] On Jun 2, 9:36 pm, luke luca.giaco...@gmail.com wrote: Nope in spite of my enthusiasm cls.args wont work properly as it will give me a property and not a symbol :) I'll put back my eval since it worked. Hope that was of any help! On Jun 2, 9:32 pm, luke luca.giaco...@gmail.com wrote: WAIT, I didn't see that you use self.arg[0]!! that's why my code was giving me 57, I just need to call cls.arg[0], great now I can remove the eval ;)! thanks again On Jun 2, 9:30 pm, luke luca.giaco...@gmail.com wrote: Actually you're wrong. Every instance of a class in python has its own attributes and editing the attributes of one instance of a class wont modify the attributes of the other classes. Try: class MyClass: def __init__(self,var): self.var=var then execute: a = MyClass(10) print a.var 10 b = MyClass(20) print b.var 20 print a.var, b.var 10 20 This said, my code might effectively not be the best one but my issue is that in _eval_evalf(cls,arg) the value of arg is not a symbol but is a float (57 in my case, probably is an index of some internal variable.. I can't find any documentation about that). So it's pretty unusable, that's why I set cls.arg. However the code is working so thanks everybody. On Jun 2, 7:01 pm, Ronan Lamy ronan.l...@gmail.com wrote: Le jeudi 02 juin 2011 à 09:35 -0700, luke a écrit : Yes, that worked. But I had to restructure the code class SUM(Function): nargs = 2 @classmethod def eval(cls, arg): cls.arg=arg @classmethod def _eval_evalf(cls, arg): map = Code(function () { emit(sum,{%(field)s:this.%(field)s}); } % {'field':cls.arg}) reduce = Code( function(key, values) { var sum = 0; values.forEach(function(doc) { if (doc.%(field)s != undefined){ sum += doc.%(field)s; } }); return {%(field)s:sum}; }; % {'field':cls.arg}) result = db.people.map_reduce(map, reduce, myresults) return result.find_one()['value'][unicode(cls.arg)] Because arg in _eval_evalf was strangely enough a float (more precisely 57, have no clue why :) ). Thank you all guys! Your implementation won't work correctly: _eval_evalf needs to be an ordinary method of the instance in order to access to the argument of the function. Note that SUM is a class and that SUM('some_field') is an instance of it, so each time you set SUM.arg, all SUM calls will see it and since it's reset every time you call SUM(...), you'll get this: a = SUM('some_field'); SUM('other_field') a.evalf() - result for SUM('other_field') So you do need to follow my advice exactly - and remove eval(). On Jun 2, 6:07 pm, Ronan Lamy ronan.l...@gmail.com wrote: Le jeudi 02 juin 2011 à 08:03 -0700, luke a écrit : Oh, thanks a lot. Now it's working fine. Now the only problem is that the code is evaluated when calling sympify, and not when calling evalf. Could I ask you what is the way to keep the function lazy? I explain myself better. Since the function SUM has to operate on a database if I have something like that: SUM('field') + SUM('field') + SUM('field') #not lazy, computes immediately three queries 1234 I'm doing the same operation three times and this is not very good in terms of performances, what I expected would have been: a = SUM('field') + SUM('field') + SUM('field') - 3SUM('field') # one single query print a 3*SUM('field') print N(a) 1234 just like other functions work. e.g. log(10)+log(10)+log(10) 3*log(10) Note that your use case
[sympy] Adding sympy.physics to documentation
I'd like to get sympy.physics added to docs.sympy.org. From what I can tell, this should be as simple as creating doc/src/modules/physics/index.txt Before doing this, I wanted to see what people thought about the organization of this module, because this will influence how the docs are organized. Currently, there are several files in sympy/physics, and then there is physics/quantum, and there is physics/classical [0]. A few questions: 1) Should any of the code in sympy.physics be bundled into it's own submodule (similar to quantum and/or classical)? 2) Are there reasons this part of sympy has not been added to docs.sympy.org in the past (other than lack of time)? The easiest approach would probably to leave the structure as is, and just add the necessary .txt files to doc/src/modules/physics. If people are happy with the current structure of this part of sympy, I can add some skeleton files that will get the basic sphinx framework started, and then the submodules can be more completely fleshed out and polished by the people who are most familiar with the various bits of code that sympy/physics includes. Thoughts? ~Luke [0] -- https://github.com/gilbertgede/sympy/tree/pydy/sympy/physics/classical -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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.
Re: [sympy] Re: Adding sympy.physics to documentation
1) Should any of the code in sympy.physics be bundled into it's own submodule (similar to quantum and/or classical)? You could have either a 'physics' submodule and a 'classical' subsubmodule, or a 'classical physics' and a 'quantum physics' submodule. I don't really care either way, and this should be easy to change later. The first one corresponds more to the (intended) structure of the physics-related code. I think having a physics submodule with 'classical' and 'quantum' subsubmodules make sense. I'll leave the other physics subsubmodules (units, matrices, hydrogen, etc.) where they are for now and if it makes sense to rearrange things, we can do that down the road. 2) Are there reasons this part of sympy has not been added to docs.sympy.org in the past (other than lack of time)? No, it should be there, it is just that noone yet made sure it's generated correctly when building the docs. I'll get started on this. ~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.
Re: [sympy] Re: Adding sympy.physics to documentation
On Tue, Jun 7, 2011 at 1:26 PM, krastanov.ste...@gmail.com krastanov.ste...@gmail.com wrote: What would the classical module contain? Won't newtonian, galilean or just mechanics be more suitable in this case? physics.classical will contain what Gilbert is working on for his GSoC project. His project is focused is on rigid body mechanics, especially multi-body systems. It provides tools for performing convenient 3d vector kinematics, as well as algorithms for deriving equations of motion automatically. I guess classical mechanics or newtonian mechanics would more precisely describe what his project is about, and we decided that it would make sense to put this sort of thing into sympy.physics.classical For example Hamiltonian mechanics applies to boot classical and quantum physics. Also optics/thermodynamics/stat. phys./etc don't play well with such separation. Perhaps it would make more sense to put his project into sympy.physics.classicalmechanics, or even just sympy.physics.mechanics? Anyway, this can be changed later. If you prepare the skeleton files I would be happy to go over the code and document the parts that I use. Cool, thanks! I'll mail the list when I get this up and running on a github branch. ~Luke Stefan On 7 June 2011 20:34, Luke hazelnu...@gmail.com wrote: 1) Should any of the code in sympy.physics be bundled into it's own submodule (similar to quantum and/or classical)? You could have either a 'physics' submodule and a 'classical' subsubmodule, or a 'classical physics' and a 'quantum physics' submodule. I don't really care either way, and this should be easy to change later. The first one corresponds more to the (intended) structure of the physics-related code. I think having a physics submodule with 'classical' and 'quantum' subsubmodules make sense. I'll leave the other physics subsubmodules (units, matrices, hydrogen, etc.) where they are for now and if it makes sense to rearrange things, we can do that down the road. 2) Are there reasons this part of sympy has not been added to docs.sympy.org in the past (other than lack of time)? No, it should be there, it is just that noone yet made sure it's generated correctly when building the docs. I'll get started on this. ~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. -- 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. -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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.
[sympy] bugs in units
I was writing some documentation for physics/units.py and discovered some infinite recursion RuntimeError: from sympy.physics.units import joule joule File /home/luke/repos/sympy/sympy/core/expr.py, line 140, in __lt__ return C.StrictInequality(self, other) File /home/luke/repos/sympy/sympy/core/relational.py, line 128, in __new__ return rop_cls._eval_relation(lhs.evalf(), rhs.evalf()) File /home/luke/repos/sympy/sympy/core/relational.py, line 185, in _eval_relation return lhs rhs File /home/luke/repos/sympy/sympy/core/decorators.py, line 75, in __sympifyit_wrapper return func(a, sympify(b, strict=True)) File /home/luke/repos/sympy/sympy/core/expr.py, line 137, in __lt__ dif = self - other File /home/luke/repos/sympy/sympy/core/decorators.py, line 75, in __sympifyit_wrapper return func(a, sympify(b, strict=True)) File /home/luke/repos/sympy/sympy/core/decorators.py, line 115, in binary_op_wrapper return func(self, other) File /home/luke/repos/sympy/sympy/core/expr.py, line 86, in __sub__ return Add(self, -other) File /home/luke/repos/sympy/sympy/core/expr.py, line 70, in __neg__ return Mul(S.NegativeOne, self) File /home/luke/repos/sympy/sympy/core/cache.py, line 100, in wrapper return func_cache_it_cache[k] File /home/luke/repos/sympy/sympy/core/numbers.py, line 1100, in __hash__ return super(Integer, self).__hash__() File /home/luke/repos/sympy/sympy/core/numbers.py, line 797, in __hash__ return super(Rational, self).__hash__() File /home/luke/repos/sympy/sympy/core/numbers.py, line 193, in __hash__ return super(Number, self).__hash__() RuntimeError: maximum recursion depth exceeded while calling a Python object Bug report filed here: http://code.google.com/p/sympy/issues/detail?id=2461 ~Luke -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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.
Re: [sympy] Re: Adding sympy.physics to documentation
+1 for sympy.physics.mechanics ~Luke On Thu, Jun 9, 2011 at 12:56 PM, Brian Granger elliso...@gmail.com wrote: On Tue, Jun 7, 2011 at 10:28 PM, Luke hazelnu...@gmail.com wrote: On Tue, Jun 7, 2011 at 1:26 PM, krastanov.ste...@gmail.com krastanov.ste...@gmail.com wrote: What would the classical module contain? Won't newtonian, galilean or just mechanics be more suitable in this case? physics.classical will contain what Gilbert is working on for his GSoC project. His project is focused is on rigid body mechanics, especially multi-body systems. It provides tools for performing convenient 3d vector kinematics, as well as algorithms for deriving equations of motion automatically. I guess classical mechanics or newtonian mechanics would more precisely describe what his project is about, and we decided that it would make sense to put this sort of thing into sympy.physics.classical For example Hamiltonian mechanics applies to boot classical and quantum physics. Also optics/thermodynamics/stat. phys./etc don't play well with such separation. Perhaps it would make more sense to put his project into sympy.physics.classicalmechanics, or even just sympy.physics.mechanics? I think that classical or mechanics make the most sense. Because classical physics also includes other areas (EM, thermo, etc), maybe mechanicsa makes the most sense. Brian Anyway, this can be changed later. If you prepare the skeleton files I would be happy to go over the code and document the parts that I use. Cool, thanks! I'll mail the list when I get this up and running on a github branch. ~Luke Stefan On 7 June 2011 20:34, Luke hazelnu...@gmail.com wrote: 1) Should any of the code in sympy.physics be bundled into it's own submodule (similar to quantum and/or classical)? You could have either a 'physics' submodule and a 'classical' subsubmodule, or a 'classical physics' and a 'quantum physics' submodule. I don't really care either way, and this should be easy to change later. The first one corresponds more to the (intended) structure of the physics-related code. I think having a physics submodule with 'classical' and 'quantum' subsubmodules make sense. I'll leave the other physics subsubmodules (units, matrices, hydrogen, etc.) where they are for now and if it makes sense to rearrange things, we can do that down the road. 2) Are there reasons this part of sympy has not been added to docs.sympy.org in the past (other than lack of time)? No, it should be there, it is just that noone yet made sure it's generated correctly when building the docs. I'll get started on this. ~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. -- 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. -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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. -- Brian E. Granger Cal Poly State University, San Luis Obispo bgran...@calpoly.edu and elliso...@gmail.com -- 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. -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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.
[sympy] sympy/physics sphinx documentation
I've started working on Sphinx documentation for the physics submodule: https://github.com/hazelnusse/sympy/tree/sphinx_physics There are three main items to work on: 1) physics -- top level sympy/physics files 2) quantum -- sympy/physics/quantum files 3) mechanics -- sympy/physics/mechanics files The documentation for all these lives in sympy/doc/src/modules/physics. In that directory, I've added stubs for each of these items. Gilbert and I are going to work on mechanics documentation and I have something started for units.py, but it would be great for those who know more about the other top level physics files and the quantum stuff to give feedback or maybe even links to example scripts that could be turned into Sphinx documentation without too much effort. There is a lot of stuff in quantum, it would be really great to get some documentation for it into the Sphinx site. I'm not sure what the best way to coordinate all of this is, does pushing the skeleton of the documentation for this submodule into the master branch make sense so that the basic framework is there and then people can build on it, or should it all be done separately and once it is polished then push it in as a whole? ~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.
Re: [sympy] Question on Interfaces
I ran this same question by my girlfriend who teaches undergraduate physics classes. She isn't an experienced programmer, so concepts of operator overloading and object oriented vs functional programming styles are not on here mind, but she has taught a lot of the core required physics classes to both majors and non-majors at UC Davis, so she has a lot of experience interacting with undergraduates on this kind of thing. Surprisingly, she thought the operator interface seemed the clearest because once you learn the meanings of the , ^, |, it is about as close to what you would write on a black board or on paper as you could hope for. That said, there are issues with , ^, and |, namely it is unlikely to know what they mean unless you read the docstrings of Vector or read the Sphinx documentation that Gilbert has written. Additionally, as Matthew brings up using '^' for the cross product may visually conflict with the wedge operator. Then again, it doesn't seem to hurt to have overlapping syntax's, as long as they are both well documented. I vote for keeping the operators and the functions, and if any are removed, to remove the methods. If people have thoughts on any negative implications of implementing multiple ways to perform the same thing, especially related to long term maintenance of the code, it would be great to hear them. ~Luke On Thu, Aug 11, 2011 at 12:14 PM, Gilbert Gede gilbertg...@gmail.com wrote: My Summer of Code project is writing a submodule of SymPy for creation of symbolic equations of motion for multibody systems. As part of this, I've implemented classes to represent vectors and dyadics. I have currently implemented three ways to do mathematical operations on vectors: an operator, a function, and a method interface. I think three interfaces for these operations is too many, and am looking for some input on which ones people prefer. The implemented interfaces look like: Cross product: (vec1 ^ vec2) cross(vec1, vec2) vec1.cross(vec2) Dot product: (vec1 vec2) dot(vec1, vec2) vec1.dot(vec2) Outer product: (vec1 | vec2) outer(vec1, vec2) vec1.outer(vec2) Here is one example where vector and dyadic quantities are used in the code. I is a dyadic, and omega and alpha are vectors. -(I alpha) - (omega ^ (I omega)) -dot(I, alpha) - cross(omega, dot(I, omega)) -I.dot(alpha) - omega.cross(I.dot(omega)) I'd appreciate people's opinions on: 1) Which is clearest? 2) Which would be easiest to teach? 3) Which is least error prone? I personally prefer the operator interface (, ^, |), as I think once you learn what the three operators represent, it is clearer to read and write. I would especially value the input of anyone who would be interested in using this as part of teaching students. I've also made a poll here: http://www.surveymonkey.com/s/CK8HDMD Thanks, Gilbert -- 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. -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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.
Re: [Sports Biomechanics] Re: [sympy] Question on Interfaces
One comment below. On Thu, Aug 11, 2011 at 1:15 PM, Jason Moore moorepa...@gmail.com wrote: I'm for the functional names as it is how all the programming languages that I know of implement dot products and cross products. It is clear what they mean and the symbols we use in math for the dot product and cross product (a dot and a cross) do not exist explicitly on the key board. Secondly, those symbols you use are already resevered for python operations, what happens when I have a script that requires both the dot product of a vector and the bitwise and comparison? He is only overloading these operators for his classes, so it would have no effect on the same operators used with other classes. So, if you wanted to do bitwise manipulations on ints (or any other classes which support /^/|) and vector products using the /^/| operators in the same script, you could, and the code would work properly, although a reader would have to be more aware of the context in which the is being used. Doing a /^/| between incompatible types (i.e., int and Vector) would raise a TypeError exception. However, one could argue that it is safer to use operators because they are tied to the classes, whereas with the functions, if you import them into the global namespace you could unintentionally overwrite any other dot/cross/outer functions that may have existed. Obviously this is avoidable with the import syntax Python offers, but if you were careless, it could happen. The binary operators he is overloading are really no different from any other class method, except for the rules of precedence defined by the Python language. Obviously there are pros/cons of both ways, I think the real question is whether to support both interfaces, or to be more restrictive and only support one. This question of whether it is better to only support one way of doing things versus a couple ways of doing things has also come up in regards to how basis vectors of a Reference Frame are accessed, and it seems like having two ways to do things might not be too much of a hassle to support, with the added benefit that with the extra functionality, the Python code can look very similar to how it is printed/prettyprinted/latex'd, which I think is a very desirable quality. I think operator assignment belongs in language design. You all have chosen python as your language of choice for the software, so your are stuck with syntax and style from the python language. Everyone that uses your software has to learn python to some degree before they can use it anyways. Autolev for example is it's own mini langague so they have the power to assign whatever keyboard keys to various opeartions, like the '' for vectors and other operations. Python has standards and overloading symbols is funky. Another example I know of is the ggplot library in R. They overload the '+' symbol is a very non-R way. When you read R code with ggplot stuff embedded in it you have to think in a totally different way than the rest of the code to understand what is going on. Keep in mind that people's scripts can have many modules imported from tons of python librarys, including your library (sympy.physics.mechanics). If you rewrite the language definition, then it doesn't necessarily fit with the rest of the code. Jason On Thu, Aug 11, 2011 at 12:42 PM, Luke hazelnu...@gmail.com wrote: I ran this same question by my girlfriend who teaches undergraduate physics classes. She isn't an experienced programmer, so concepts of operator overloading and object oriented vs functional programming styles are not on here mind, but she has taught a lot of the core required physics classes to both majors and non-majors at UC Davis, so she has a lot of experience interacting with undergraduates on this kind of thing. Surprisingly, she thought the operator interface seemed the clearest because once you learn the meanings of the , ^, |, it is about as close to what you would write on a black board or on paper as you could hope for. That said, there are issues with , ^, and |, namely it is unlikely to know what they mean unless you read the docstrings of Vector or read the Sphinx documentation that Gilbert has written. Additionally, as Matthew brings up using '^' for the cross product may visually conflict with the wedge operator. Then again, it doesn't seem to hurt to have overlapping syntax's, as long as they are both well documented. I vote for keeping the operators and the functions, and if any are removed, to remove the methods. If people have thoughts on any negative implications of implementing multiple ways to perform the same thing, especially related to long term maintenance of the code, it would be great to hear them. ~Luke On Thu, Aug 11, 2011 at 12:14 PM, Gilbert Gede gilbertg...@gmail.com wrote: My Summer of Code project is writing a submodule of SymPy for creation of symbolic equations of motion for multibody systems
[sympy] MathJax script tag
I pulled the latest master and built the sphinx documentation. Things seem to build fine, but this is what is generated for the MathJax script tag: script type=text/javascript src=../../_static/http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML-full;/script Obviously, src doesn't make sense with the result that all the LaTeX code appears undrendered. I am using Sphinx 1.0.1, and Python 2.7.1, and I simply entered make html from the sympy/doc directory. Is this a bug, or am I doing something incorrectly? Thanks, ~Luke -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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.
Re: [sympy] MathJax script tag
Ok, I just upgraded to Sphinx 1.0.7 and it fixed the problem. Thanks, ~Luke On Tue, Aug 16, 2011 at 4:10 PM, Aaron Meurer asmeu...@gmail.com wrote: It works for me. The only thing that I can think of is that your version of Sphinx has a bug in it. I am using 1.0.7, which generates script type=text/javascript src=http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML-full;/script Aaron Meurer On Tue, Aug 16, 2011 at 5:06 PM, Luke hazelnu...@gmail.com wrote: I pulled the latest master and built the sphinx documentation. Things seem to build fine, but this is what is generated for the MathJax script tag: script type=text/javascript src=../../_static/http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML-full;/script Obviously, src doesn't make sense with the result that all the LaTeX code appears undrendered. I am using Sphinx 1.0.1, and Python 2.7.1, and I simply entered make html from the sympy/doc directory. Is this a bug, or am I doing something incorrectly? Thanks, ~Luke -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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. -- 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. -- Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety. -- Benjamin Franklin, Historical Review of Pennsylvania, 1759 -- 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.
Re: [sympy] doctest testmod() globs keyword argument
On Sun, Aug 21, 2011 at 10:42 AM, Aaron Meurer asmeu...@gmail.com wrote: On Sat, Aug 20, 2011 at 7:34 PM, Luke hazelnu...@gmail.com wrote: On Sat, Aug 20, 2011 at 3:37 PM, Aaron Meurer asmeu...@gmail.com wrote: I don't know of any doctests in SymPy that do this. Why can't you put imports in each doctest? I'd highly recommend it. The reason for not wanting to do the imports is as follows. We have a class (Kane) that implements an algorithm, and there are many steps to that algorithm. Setting up the proper execution context for each doctest requires that each docstring replicate a lot of import statements and code that are done in previous docstrings. Looking at the docstrings for this gets cumbersome pretty quickly because of all the setup code that is required to be in each and every docstring. Maybe create a helper function that does it all for you and import that. To see if this can be done, you'll probably have to do what I would end up doing, which is to read the source. Look at sympy/utilities/runtests.py and also the source for Python's doctest.py (import doctest; doctest?? in IPython will tell you where it is locally). I can tell you that how our doctest runner works is that it subclasses the Python doctest, over writting stuff that is broken there in at least one Python version. Ok. Something in testmod() must be different from the default doctest module, I'll give it a look. By the way, when you say running Python on this file, do you mean running python -m doctest myfile.py? I mean python myfile.py. Running a file and running the doctests in the file are different things. What does python -m doctest myfile.py give? Yes, they are two different things. It fails in the same way running sympy's doctest on the file fails. The reason is that the code at the end of the file is not run: if __name__ == __main__: import doctest from sympy import Symbol doctest.testmod(globs={'Symbol' : Symbol}) According to the python man page, the -m flag runs the file as a script, which I presume means from top to bottom, and __name__ != __main__ within the execution context. What is the main motivation for executing doctests in this fashion as opposed to the one which requires the above if statement? Is it safe to assume that all sympy doctests should be written such that they will pass when python -m doctest mymodule.py is run? Or is there a way to change how the doctests are run for a particular file, i.e., so that doctests are tested by the if statement above when python mymodule.py is run? Luke Aaron Meurer ~Luke Aaron Meurer On Sat, Aug 20, 2011 at 3:54 PM, Luke hazelnu...@gmail.com wrote: Hello, I would like to alter the execution context of some doctests so that I don't have redundant import statements in every doctest. Python's doctest.testmod() function allows one to do all the common import statements in one place (at the bottom of your module), and pass those names so that all doctests have those names available when they are run. A simple example of this is: #!/usr/bin/env python def foo(bar): x = Symbol('x') print(x) x pass if __name__ == __main__: import doctest from sympy import Symbol doctest.testmod(globs={'Symbol' : Symbol}) Running python on this file works (the tests pass even though Symbol isn't explicitly imported within the foo function's doctest). However, sympy's doctest fails with these errors: ../../bin/doctest doctest_globaldict.py test process starts = executable: /usr/bin/python (2.7.1-final-0) architecture: 64-bit cache: yes ground types: python sympy/physics/doctest_globaldict.py[1] F [FAIL] __ sympy.physics.doctest_globaldict.foo File /home/luke/repos/sympy/sympy/physics/doctest_globaldict.py, line 4, in sympy.physics.doctest_globaldict.foo Failed example: x = Symbol('x') Exception raised: Traceback (most recent call last): File /usr/lib/python2.7/doctest.py, line 1254, in __run compileflags, 1) in test.globs File doctest sympy.physics.doctest_globaldict.foo[0], line 1, in module x = Symbol('x') NameError: name 'Symbol' is not defined ** File /home/luke/repos/sympy/sympy/physics/doctest_globaldict.py, line 5, in sympy.physics.doctest_globaldict.foo Failed example
Re: [sympy] doctest testmod() globs keyword argument
The main reason I am doing things this way is because this is how I learned it when reading docs.python.org: http://docs.python.org/py3k/library/doctest.html?highlight=doctest#doctest The second reason I prefer this way is because it makes it very easy to control the execution context of all the doctests within a module, through the use of the globs keyword argument to doctest.testmod(). I'm not sure if it is possible to control the execution context in the same way when python -m doctest file.py is used. No, what you suggested does not work. sympy's doctest is a function, whereas the Python standard library, doctest is a module with a large number of functions, testmod() being one of them. ~Luke On Mon, Aug 22, 2011 at 10:32 AM, Aaron Meurer asmeu...@gmail.com wrote: Well, I don't know why you are doing things this way, but clearly python -m doctest file.py or ./bin/doctest file.py do not run __name__ == `__main__`. Does it work if you replace import doctest with from sympy import doctest? Aaron Meurer On Sun, Aug 21, 2011 at 2:32 PM, Luke Peterson hazelnu...@gmail.com wrote: If the file has the if statement in it (as below), then running python on the file (without -m doctest) *will* run the doctests, and you can easily control the execution context of the doctests by doing any required imports/setup in this if statement and passing handles to testmod via the globs keyword argument. This is part of the Python standard library, so I would consider it also to be pretty standard, and I have found this functionality quite useful. ~Luke On Aug 21, 2011, at 11:43 AM, Aaron Meurer asmeu...@gmail.com wrote: On Sun, Aug 21, 2011 at 12:32 PM, Luke hazelnu...@gmail.com wrote: On Sun, Aug 21, 2011 at 10:42 AM, Aaron Meurer asmeu...@gmail.com wrote: On Sat, Aug 20, 2011 at 7:34 PM, Luke hazelnu...@gmail.com wrote: On Sat, Aug 20, 2011 at 3:37 PM, Aaron Meurer asmeu...@gmail.com wrote: I don't know of any doctests in SymPy that do this. Why can't you put imports in each doctest? I'd highly recommend it. The reason for not wanting to do the imports is as follows. We have a class (Kane) that implements an algorithm, and there are many steps to that algorithm. Setting up the proper execution context for each doctest requires that each docstring replicate a lot of import statements and code that are done in previous docstrings. Looking at the docstrings for this gets cumbersome pretty quickly because of all the setup code that is required to be in each and every docstring. Maybe create a helper function that does it all for you and import that. To see if this can be done, you'll probably have to do what I would end up doing, which is to read the source. Look at sympy/utilities/runtests.py and also the source for Python's doctest.py (import doctest; doctest?? in IPython will tell you where it is locally). I can tell you that how our doctest runner works is that it subclasses the Python doctest, over writting stuff that is broken there in at least one Python version. Ok. Something in testmod() must be different from the default doctest module, I'll give it a look. By the way, when you say running Python on this file, do you mean running python -m doctest myfile.py? I mean python myfile.py. Running a file and running the doctests in the file are different things. What does python -m doctest myfile.py give? Yes, they are two different things. It fails in the same way running sympy's doctest on the file fails. The reason is that the code at the end of the file is not run: if __name__ == __main__: import doctest from sympy import Symbol doctest.testmod(globs={'Symbol' : Symbol}) According to the python man page, the -m flag runs the file as a script, which I presume means from top to bottom, and __name__ != __main__ within the execution context. What is the main motivation for executing doctests in this fashion as opposed to the one which requires the above if statement? Is it safe to assume that all sympy doctests should be written such that they will pass when python -m doctest mymodule.py is run? Or is there a way to change how the doctests are run for a particular file, i.e., so that doctests are tested by the if statement above when python mymodule.py is run? Luke -m runs the doctest.py file as a script, with your file as the command line argument. This is the standard way to run the standard Python doctest on a file. Just running python myfile.py should not run any doctests, just the code in the module itself. Aaron Meurer Aaron Meurer ~Luke Aaron Meurer On Sat, Aug 20, 2011 at 3:54 PM, Luke hazelnu...@gmail.com wrote: Hello, I would like to alter the execution context of some doctests so that I don't have redundant import statements in every doctest. Python's doctest.testmod() function allows one to do all the common import statements in one place (at the bottom of your module
Re: [sympy] doctest testmod() globs keyword argument
On Thu, Aug 25, 2011 at 7:00 AM, Ronan Lamy ronan.l...@gmail.com wrote: Le samedi 20 août 2011 à 18:34 -0700, Luke a écrit : On Sat, Aug 20, 2011 at 3:37 PM, Aaron Meurer asmeu...@gmail.com wrote: I don't know of any doctests in SymPy that do this. Why can't you put imports in each doctest? I'd highly recommend it. The reason for not wanting to do the imports is as follows. We have a class (Kane) that implements an algorithm, and there are many steps to that algorithm. Setting up the proper execution context for each doctest requires that each docstring replicate a lot of import statements and code that are done in previous docstrings. Looking at the docstrings for this gets cumbersome pretty quickly because of all the setup code that is required to be in each and every docstring. Hmmm... I think you're doing it wrong. Doctests are meant to be read in isolation and to be fairly self-contained. This kind of narrative explaining a long ordered chain of related operations would rather belong in a doc file. If your doctests looked like standard doctests, you wouldn't need a ton of setup and the problem would go away. Also, though I haven't read the code, this suggests another question: if you have methods that can't make sense in isolation, maybe they should actually be private? One option is to allow for all the algorithm inputs to be keyword arguments to the __init__ method, and then describe everything in the init method. Previously we had an __init__ method that took no inputs, and we had separate public method calls to perform the algorithm setup, which meant that each of these methods needed to have a docstring with a fairly long bit of setup code just to get to the point where you can actually use the method in a meaningful way. The downside of this is that some of these methods which are now effectively called from __init__ (if the user provides that information) take a fair bit of time to run -- so the creation of the algorithm instance takes a while, which might seem a bit strange to users, what do you think? The upside of putting all this in the __init__ is that we can guarantee the order of the method calls is consistent -- which does indicate that these might be better off as private methods. However, sometimes you might want to set the algorithm up with one set of inputs, and then later on change the inputs, so either a new instance would need to be created, or individual public methods would need to be available. And if there are public methods, we need a docstring. so I'm not sure what the best solution is. ~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.
[sympy] Import errors with an installed version of Sympy
If I put the Sympy source repository folder into my PYTHONPATH environment variable, I can import sympy and all of its components successfully. If I instead have an empty PYTHONPATH environment variable, then run `sudo python setup.py install`, which by default installs to `/usr/local', and then try to import sympy, I get the following import errors: luke@ThinkPad-W510:~$ echo $PYTHONPATH luke@ThinkPad-W510:~$ python Python 2.7.2+ (default, Oct 4 2011, 20:06:09) [GCC 4.6.1] on linux2 Type help, copyright, credits or license for more information. from sympy import * Traceback (most recent call last): File stdin, line 1, in module File /usr/local/lib/python2.7/dist-packages/sympy/__init__.py, line 30, in module from sympy.core import * File /usr/local/lib/python2.7/dist-packages/sympy/core/__init__.py, line 4, in module from sympify import sympify File /usr/local/lib/python2.7/dist-packages/sympy/core/sympify.py, line 5, in module from core import all_classes as sympy_classes File /usr/local/lib/python2.7/dist-packages/sympy/core/core.py, line 3, in module from assumptions import AssumeMeths, make__get_assumption File /usr/local/lib/python2.7/dist-packages/sympy/core/assumptions.py, line 3, in module from sympy.core.core import BasicMeta ImportError: cannot import name BasicMeta Am I doing something wrong, or is this a bug? ~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.