Re: [sympy] How to implement an DifferentialOperator that can do this kind calculation

403 views
Skip to first unread message

Stefan Krastanov

unread,
Jan 26, 2013, 8:45:08 AM1/26/13
to sy...@googlegroups.com
Before suggesting a solution I need to point out a problem with your
suggestion. Namely, multiplication and application are two very
different operation (there is overlap (e.g. matrix multiplication) but
I will leave it out for the moment). SymPy does not have support for
this type of "abuse of notation" for the moment. If you are
interesting implementing it yourself your best shot (in my opinion)
would be to get inspiration by the matrix expression module and the
rewrite rules module.

On the other hand if you want to use simple vanilla python for all
this you can just use the `diff` global function but presumably you do
not want that in order to facilitate automatic simplifications like
"2*p - p -> p".

If this is the case (and you are absolutely sure that this is
necessary (usually it is not)) you can try to use the differential
geometry module (in differential geometry vector fields are
differential operators). If you know the formalism it will be very
easy to use, however if you do not know it you will need to read
something more than just the documentation.

http://docs.sympy.org/dev/modules/diffgeom.html#sympy.diffgeom.BaseVectorField

On 25 January 2013 23:49, ruoyu zhang <ruoy...@gmail.com> wrote:
>>>> p = DifferentialOperator(t)
>>>> a * p * f(t)
> Derivative(f(t), t)*a
>
> p is a DifferentialOperator, when it multiply with some expression at right
> side, it calculates the derivative of the expression.
>
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To post to this group, send email to sy...@googlegroups.com.
> To unsubscribe from this group, send email to
> sympy+un...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>

ruoyu zhang

unread,
Jan 26, 2013, 7:45:16 PM1/26/13
to sy...@googlegroups.com
I want to do some calculation like this:

[cos(theta), -sin(theta)]     [Ld*p + R, -Lq*omega]     [cos(theta), sin(theta)]      [Id]
                          *                         *                              *
[sin(theta),  cos(theta)]     [Ld*omega,  Lq*p + R]     [-sin(theta),  cos(theta)]    [Iq]
 
This is a part of motor equation expressed in matrix multiplication,Id, Iq, theta are functions of t (time), p is the differential operator, so this isn't a simple multiplication. I will do this kind of calculation a lot, so I want to find a generic method.



在 2013年1月26日星期六UTC+9下午10时45分08秒,Stefan Krastanov写道:

Aaron Meurer

unread,
Jan 26, 2013, 9:24:34 PM1/26/13
to sy...@googlegroups.com
There is also some concept of operators in the quantum module. I don't
remembr if it does what you want or not.

You could try just making an object that overrides __rmul__. But if
any operation manually creates a Mul with your object, it won't be
called (this is a long running issue that we are still thinking about
how to fix. See http://code.google.com/p/sympy/issues/detail?id=1941).

Aaron Meurer
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
>
> To post to this group, send email to sy...@googlegroups.com.

Alexey U. Gudchenko

unread,
Jan 27, 2013, 8:34:53 AM1/27/13
to sy...@googlegroups.com

Additionally to Stefan's answer about sympy core , I introduce the
example how it may be implemented concretely.

There is the tested code in the atachment of it.
(I can create PR, but I don't know where will it be better to put in the
sympy modules)

And there is the '__call__' magic-method used instead of the implicit
multiplication as aplly-like method.

>>> Dx = DiffOperator(x)
>>> myD = (a*Dx + Dx**3) # construct diff operator
>>> myD(x**4) # apply this operator.
4*a*x**3 + 24*x


For matrices it is some more complicated

>>> I = Matrix([[0, -1], [1, 0]])
>>> myD = I*Dx # construct diff
>>> myD(x**2) # apply

Derivative([x**2, 0]
[ 0, x**2], x)


Here I don't know how Derivative can be automatically applied for the
Matrix expression.


--
Alexey Gudchenko
diff_operator.py

Aaron Meurer

unread,
Jan 27, 2013, 4:08:49 PM1/27/13
to sy...@googlegroups.com
On Jan 27, 2013, at 6:34 AM, "Alexey U. Gudchenko" <pr...@goodok.ru> wrote:

>
> Additionally to Stefan's answer about sympy core , I introduce the
> example how it may be implemented concretely.
>
> There is the tested code in the atachment of it.
> (I can create PR, but I don't know where will it be better to put in the
> sympy modules)
>
> And there is the '__call__' magic-method used instead of the implicit
> multiplication as aplly-like method.
>
>>>> Dx = DiffOperator(x)
>>>> myD = (a*Dx + Dx**3) # construct diff operator
>>>> myD(x**4) # apply this operator.
> 4*a*x**3 + 24*x
>
>
> For matrices it is some more complicated
>
>>>> I = Matrix([[0, -1], [1, 0]])
>>>> myD = I*Dx # construct diff
>>>> myD(x**2) # apply
>
> Derivative([x**2, 0]
> [ 0, x**2], x)
>
>
> Here I don't know how Derivative can be automatically applied for the
> Matrix expression.

Well just as application of Dx isn't really multiplication, neither is
application of the matrix operator. So a subclass of Matrix will be
needed here.

Aaron Meurer

>
>
> --
> Alexey Gudchenko
>
> On 26.01.2013 02:49, ruoyu zhang wrote:
>>>>> p = DifferentialOperator(t)
>>>>> a * p * f(t)
>> Derivative(f(t), t)*a
>>
>> p is a DifferentialOperator, when it multiply with some expression at
>> right side, it calculates the derivative of the expression.
>>
>
> --
> You received this message because you are subscribed to the Google Groups "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy?hl=en.
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
> <diff_operator.py>

Alexey U. Gudchenko

unread,
Jan 28, 2013, 1:21:04 AM1/28/13
to sy...@googlegroups.com
Yes, for the matrix differential operators with matrices which are
depended of the variables of differentiation we must think.

But for the "constant" matrix (which is independent of the variable x) I
don't quite understand what kind of subclass of Matrix is needed: which
is related to differential operator or differential method of matrix itself.

In order to avoid duplicating code, I think, we must use that for the
matrix M which is independent of the variable x the following is:

M Dx = Dx M

and at the same time for the applying this operator we only care that
differential operator would always be to the left of the expression A
(x) to which it is applied.

So for the (constant) matrix differential operator myD = (M Dx)

(M Dx) A(x) = (Dx M) A(x) = Dx (M A(x))

Is it right?

This is done automatically in presented diff_operator.py (only for the
matrices M which are independent of the variable x)

Therefore for the (M Dx) A(x) we can compute M A(x) firstly and then
only a problem in this case, that I can't compute derivative of the
matrix expression

diff( M*A(x), x)

This was the question.

In the case when M(x) is depended of x, we must of course keep it always
on the left in th expression

M(x) Dx != Dx M(x)

(this is not realized in attached code above)

So a subclass of Matrix will be needed only in this case.
Or rather, internal support in DiffOperator expression must be
implemented for this case.


Alexey Gudchenko

Alexey U. Gudchenko

unread,
Jan 28, 2013, 1:36:43 AM1/28/13
to sy...@googlegroups.com
On 28.01.2013 10:21, Alexey U. Gudchenko wrote:

> M Dx = Dx M

Will correct that, under this formula, I could see construction of a
differential operator and not the applying of differential operators to
the constant matrix (which obviously result in zero).


That is I meant that

[ a 0 ] [ (a Dx) 0 ]
[ ] Dx = [ ]
[ 0 a ] [ 0 (a Dx)]


And then

> (M Dx) A(x) = Dx (M A(x))

Aaron Meurer

unread,
Jan 28, 2013, 12:48:44 PM1/28/13
to sy...@googlegroups.com
But applying D first is probably more efficient.

Aaron Meurer

Aaron Meurer

unread,
Mar 18, 2013, 1:13:52 PM3/18/13
to sy...@googlegroups.com
Making an operator that works automatically always is not currently possible. To really work completely, you would need http://code.google.com/p/sympy/issues/detail?id=1941. See also https://github.com/sympy/sympy/wiki/Canonicalization (feel free to edit that page). 

However, you could make a class that works most of the time using the ideas from that stackoverflow question, and for the cases it doesn't handle, write a simple function that goes through an expression and applies the operator where it hasn't been applied yet. 

By the way, one thing to consider with a differential operator as "multiplication" is that it's nonassociative. Namely, (D*f)*g = g*Df, whereas D*(f*g) = g*Df + f*Dg. So you need to be careful when you do stuff that it doesn't "eat" some part of an expression and not the whole thing. For example, D*2*x would give 0 because of this. SymPy everywhere assumes that multiplication is associative, so it's likely to do that incorrectly at some point. 

If that becomes an issue, I would recommend dumping the automatic application, and just working with a function that goes through and applies it (which as I noted above, you will need anyway). 

Aaron Meurer


On Mar 18, 2013, at 6:57 AM, Saullo Castro <saullo...@gmail.com> wrote:

Dear Mr. Zhang, we are using a differential operator as you need, please see more details on:

We could address it without changing the core classes in Sympy only when the differential operator is used on the left side. When it is used on the right side the method __mul__ in the core class Expr had to be changed.
We are still looking for a Sympy native solution, though.

Regards



On Friday, January 25, 2013 11:49:43 PM UTC+1, ruoyu zhang wrote:
>>> p = DifferentialOperator(t)
>>> a * p * f(t)
Derivative(f(t), t)*a

p is a DifferentialOperator, when it multiply with some expression  at right side, it calculates the derivative of the expression.

Julien Rioux

unread,
Mar 18, 2013, 6:44:26 PM3/18/13
to sy...@googlegroups.com
On Monday, 18 March 2013 05:49:11 UTC-4, Saullo Castro wrote:
Dear Mr. Zhang, we are using a differential operator as you need, please see more details on:

We could address it without changing the core classes in Sympy only when the differential operator is used on the left side. When it is used on the right side the method __mul__ in the core class Expr had to be changed.
We are still looking for a Sympy native solution, though.

Regards



_op_priority and the @call_highest_priority are there exactly for this purpose. Define it in your class with a value above 10.0, which is Expr's default value for it. Also define __rmul__, using the decorator @call_highest_priority. This will allow your class to control what happens during multiplication (left or right), but you will still run into subtle problems because multiplication != application, as already a mentioned couple of times.

Cheers,
Julien

Saullo Castro

unread,
Apr 26, 2013, 6:34:56 AM4/26/13
to sy...@googlegroups.com
Thank you Julien and Aaron for the answers.
I am still working on this differential operator.
I hope I can give you a successful feedback very soon.
Greetings,
Saullo
Message has been deleted

Saullo Castro

unread,
Apr 26, 2013, 9:03:04 AM4/26/13
to sy...@googlegroups.com
I have now a mid term solution based on all your tips and it has been posted in Stackoverflow, in a post created for this issue.
I would really appreciate if you could take a look there and make any suggestions you believe would improve the solution.
I am still not managing to perform all the differentiations, but at least now it is applied only where it should.

Regards,
Saullo

On Monday, March 18, 2013 11:44:26 PM UTC+1, Julien Rioux wrote:

Saullo Castro

unread,
May 2, 2013, 11:08:54 AM5/2/13
to sy...@googlegroups.com
The referred solution  in Stackoverflow as showed to work really well. In my local SymPy version (which is a fork of 0.7.2-git from 30/04/2013) I've added an engineering module with the Rayleigh Ritz method implemented. The user must supply the matrix of differential operators [B], the trial functions [g] and the material constitutive matrix [F] in order to get the buckling modes and the eigenvectors (more details in here or in the Stackoverflow question).
Is there a an interest from the SymPy group to add such functionality in the master release?
Regards,
Saullo

Yuxiang Wang

unread,
Oct 15, 2018, 1:37:35 AM10/15/18
to sympy
Hi all,

Being curious - were there any follow-ups on this topic of creating a matrix of differential operators?

Best,
Shawn
Reply all
Reply to author
Forward
0 new messages