Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addition of Directional derivatives #12417

Merged
merged 12 commits into from
Mar 31, 2017

Conversation

mohit3011
Copy link
Contributor

Fixes #12416

@mohit3011
Copy link
Contributor Author

@jksuom , @asmeurer please review this PR . Thanks

@@ -214,6 +214,38 @@ def gradient(scalar, coord_sys):

return coord_sys.delop(scalar).doit()

def directional_derivative(scalar, vect, coord_sys):
"""
Returns the directional derivative of a scalar field computed along a given vector
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you have double white space, after "along a".
If you want to correct this, you shouldn't push new commit. You can use git commit --amend. It overrides before one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@szymag , thanks for reviewing it. I will correct the mistake.

@szymag
Copy link
Contributor

szymag commented Mar 27, 2017

I have some doubts about your solution.

I think that vector, which you take as parameter, should be normalized. Here, you can find some information about it (here or in the next film):
https://www.khanacademy.org/math/multivariable-calculus/multivariable-derivatives/gradient-and-directional-derivatives/v/directional-derivative

Directional derivative is a function, but you return vector. More explicitly <class 'sympy.core.add.Add'>. It may be complicated for user, who also want to calculate value of functional derivative in some point.

What do you think?

@mohit3011
Copy link
Contributor Author

mohit3011 commented Mar 27, 2017

@szymag , I don't think that normalization is necessary. The definition of Directional Derivatives as given here Wikipedia considers Directional Derivative as gradient(f).v.

Also , the function here doesn't return a vector , rather it returns a dot product which is always scalar.

@mohit3011
Copy link
Contributor Author

Also quoting from Wikipedia's Definition

In the context of a function on a Euclidean space, some texts restrict the vector v to being a unit vector. Without the restriction, this definition is valid in a broad range of contexts.

Therefore I have not kept the condition of V being a unit vector so that it could be used in broader sense.

@szymag
Copy link
Contributor

szymag commented Mar 27, 2017

You always should allowed user to put any vector, but then normalized them.
My argumentation here is that, when you put two different vector with the same direction but different length, you get different result.

I'm not going to persist on my idea, it is just convention. It will be better, if someone from maintainers takes a look.

@mohit3011
Copy link
Contributor Author

mohit3011 commented Mar 28, 2017

ping @jksuom @asmeurer @Upabjojr , please review this PR

@siefkenj
Copy link
Contributor

The directional derivative is unfortunately named, but you should allow any vector (including the zero vector) as input. That way, the directional derivative is a linear function in its direction for differentiable functions. Some textbooks work around the issue by defining the directional derivative only for unit vectors and leaving it the term "directional derivative" unspecified for non-unit vectors.

However, your code will only produce the directional derivative for a differentiable function. The true definition of the directional derivative of f at the point x in the direction v is lim_{h -> 0}( f(x+hv)-f(x))/h which is only equal to grad f(x) . v if f is differentiable. Does sympy have a differentiability test?

@mohit3011
Copy link
Contributor Author

@siefkenj

The directional derivative is unfortunately named, but you should allow any vector (including the zero vector) as input.

As you said this functions allows any vector as input.

directional derivative of f at the point x in the direction v is lim_{h -> 0}( f(x+hv)-f(x))/h which is only equal to grad f(x) . v if f is differentiable.

I have used the existing Gradient function in Sympy for DIrectional Derivative so it must be checking the conditions of differentiability as Gradient function further calls the existing Derivative function of Sympy.

5*R.x**2 + 30*R.x*R.z

"""
return gradient(scalar,coord_sys).dot(vect).doit()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unrelated to this PR, but I believe gradient should be called as gradient(scala) without the coord_sys variable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not really, look at documentation:
http://docs.sympy.org/dev/modules/vector/fields.html
We need manually put information about coordinate system. For me it is also strange

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that, that's why we need to modify the gradient function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I misunderstand your comment a bit.

I know that, that's why we need to modify the gradient function.

I agree with you, but now it isn't so easy. If I correctly understand code, vector has no information about his coordinate system, we need forward this information explicitly to function (like gradient).
I am writing proposal, where I also include this information, and I would like to fix this issue.

Copy link
Contributor Author

@mohit3011 mohit3011 Mar 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Upabjojr , It won't be that easy now as this would mean changing the whole sytem of deloperator.py and functions.py. So it's better to let it be in this way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I wrote that this issue is not related to this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I correctly understand code, vector has no information about his coordinate system,

It has:

In [6]: c = CoordSysCartesian('rect')

In [7]: c
Out[7]: rect

In [8]: c.x
Out[8]: rect_x

In [9]: c.x.args
Out[9]: (rect.x, 0, rect, rectₓ, \mathbf{{x}_{rect}})

In [10]: c.x.args[2]
Out[10]: rect

In [11]: c.x.args[2] == c
Out[11]: True

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Upabjojr , in reply to your last comment. I would like to point out that in whenever we call the gradient function from vector/functions.py then it calls the class CoordSysCartesian in vector/coordsysrect.py int his class delop function is called. which further calls Del function in deloperator.py . Now, the class CoordSysCartesian requires the name of Coordinate system for assigning purposes so that's we are passing coordinate system in gradient function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it needs some cleanup.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Upabjojr , please merge this PR. Thanks

>>> R = CoordSysCartesian('R')
>>> f1 = R.x*R.y*R.z
>>> v1 = 3*R.i + 4*R.j + R.k
>>> directional_derivative(f1, v1, R)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the same problem as in the gradient function. I don't like the R parameter in the API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Upabjojr , I understand what you mean, but as I told you earlier it would be a very large amount of work to clean up the whole coordinate system with each function. So for the existing system this is the best possible way

Copy link
Contributor Author

@mohit3011 mohit3011 Mar 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe the work for redefining the whole system can be done in other PRs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's simple. Use .atoms( ).

Copy link
Contributor Author

@mohit3011 mohit3011 Mar 29, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does .atoms() does ? and how it will help here ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you can also extract the coordinate system object from vector.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Upabjojr , maybe we can extract that information but then it would create a problem that it would be out of convention. What I mean is that in the existing system the user has to to give cordinate system as input in every function , now if I create a function where user doesn't have to give the coordinate system as input then it would create confusion and disturb the conventions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every time user wishes to use this function then he/she has to use a syntax which would be different from other functions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's start writing the new functions with an intuitive syntax. This can be fixed by adding one line to extract the coordinate system and then calling the gradient.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay , let's do it

@Upabjojr
Copy link
Contributor

vector.atoms(CoordSysCartesian)

@mohit3011
Copy link
Contributor Author

@Upabjojr , it has passed all Tests except one which has error due to exceeded time limit.

@mohit3011
Copy link
Contributor Author

@Upabjojr , please review this PR thanks

@Upabjojr Upabjojr merged commit b921ef3 into sympy:master Mar 31, 2017
@mohit3011 mohit3011 deleted the Directional_derivatives branch March 31, 2017 17:26
@mohit3011
Copy link
Contributor Author

@Upabjojr , Thanks

@szymag szymag mentioned this pull request Jul 2, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants