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

Tests of differentiate() compares expressions too strictly #14

Open
ivarne opened this issue Jul 1, 2013 · 7 comments
Open

Tests of differentiate() compares expressions too strictly #14

ivarne opened this issue Jul 1, 2013 · 7 comments

Comments

@ivarne
Copy link
Collaborator

ivarne commented Jul 1, 2013

Correct changes to the implementations of differentiate() and simpelify() breaks tests if the order of arguements are changed.

>>> isequal(:(a+b) , :(b+a))
false

The test should use a less strict comparison function for expressions than isequal, so that it wil be easier to write tests and easier to modify the code without having to modify tests. It is very easy to make mistakes when updating tests to new behaviour.

@johnmyleswhite
Copy link
Collaborator

This would be very helpful, but it's a large body of work: you need to build tests for expressions that are robust to operations that respect commutativity and associativity. Worth doing, but going to take some time.

@ivarne
Copy link
Collaborator Author

ivarne commented Jul 1, 2013

A first version that knows a short list of commutative operations (+, *) and checks if they are equal if the arguments reordered should not be too much work. It will be much harder if one also wants to make :(a+b-c) == :(a-c+b), but I think that canonicalizing the expressions to something like :(a+b+(-c)) might be an option.

A complicating factor might be that * is not commutative on materixes so that symbols and expressions can't be reorderd safely, because the dimensions is unknown.

I have some trouble finding a proper name for a comparison function, if we are not going to redefine isequal(a::Expr, b::Expr) or ==(a::Expr, b::Expr). What do you tink about usin isapprox(a::Expr, b::Expr), or do you have any better suggestions?

@johnmyleswhite
Copy link
Collaborator

Why not isequivalent or isequiv to indicate that it's not equality in the CS, but equality in the mathematical sense?

I don't think any of the existing code is likely to work correctly for matrices to begin with. Does it?

@ivarne
Copy link
Collaborator Author

ivarne commented Jul 1, 2013

isequivalent(a::Expr, b::Expr) feels like the right option.

I would expect that it works for vectors and matrix variables, at least in the simple cases i can think of, but it can't differentiate with respect to a vector, without some code changes.

Introducing differentiation with respect to a vector will probably introduce lots of possibility for user error and missunderstanding, so some verification algorithms might be needed. I am not sure if the automatic broadcasing rules would work as expected. The shortcuts and simplification routines would also need to be wetted. In the simplest sense the only modification would be to replace 0 with zeros(size(wrt)...), 1 with ones(size(wrt)...), dn/dn = eye(size(n)...).

@ivarne
Copy link
Collaborator Author

ivarne commented Jul 4, 2013

I tried to write a isequivalent(a::Expr, b::Expr) function but most of my ideas fitted better in the simplify() metods and it felt wrong to not write them there. The simple solution was

isequivalent(a::Expr, b::Expr) = isequal(simplify(a),simplify(b))

To make it more robust for comparison i implemented some canonicalization but I am not sure if the sorting of arguments to the + operator belongs in a simplify.

You can have a look at my changes at https://github.com/ivarne/Calculus.jl/commits/advanced_simpelify. Please comment.

@johnmyleswhite
Copy link
Collaborator

I'll get to this soon. Sorry for the delay: my mother is ill and I've spent the last week in the hospital with her.

@ivarne
Copy link
Collaborator Author

ivarne commented Jul 11, 2013

I'll be away from the internett for at least the next 1-3 weeks, so you don't have to hurry.

I really like the possibilities in Julia for manipulating expressions and evaluating them directly. It is makes it much easier to write code to manipulate equations and preparing for efficient computation. My plan is to make a framework for thermodynamic state equations, but the first step is to get the differentiation right.

I tried to search for a rationale for using the SymbolParameter{:op} approach with multiple dispatch in differentiation and simplification, but i did not find any discussion. The first thing I did when learning about Julia metaprogramming was to write differentiation routines, but I Dict{Symbol, Expr} that i referenced when I encountered a :call. If users are able to change that dict they migt use the differentiation routines for different purpuses and change rules if they does not think they are correctly implemented.

I hope Julia succeeds and reaches a point where universities stop teaching MATLAB. I feel so sorry for all the students who spent much time learning the commercial product, only to get an employer that does not think the price is worth it.

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

No branches or pull requests

2 participants