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

Accessing and referring to ODESystem states #1049

Closed
baggepinnen opened this issue Jun 16, 2021 · 11 comments
Closed

Accessing and referring to ODESystem states #1049

baggepinnen opened this issue Jun 16, 2021 · 11 comments

Comments

@baggepinnen
Copy link
Contributor

I'm struggling to wrap my head around the states of ODESystem, below, I have a system with a state called u, which I can access like a property, but at the same time, this state is not in states(P).

julia> states(P)
3-element Vector{Term{Real, Nothing}}:
 x1(t)
 u(t)
 y(t)

julia> P. # press TAB
u  x1  y
julia> P.u
P₊u(t)

julia> P.u  states(P)
ERROR: TypeError: non-boolean (Term{Bool, Nothing}) used in boolean context
Stacktrace:
 [1] in(x::Term{Real, Nothing}, itr::Vector{Term{Real, Nothing}})
   @ Base ./operators.jl:1135
 [2] top-level scope
   @ REPL[75]:1

julia> P.u  Set(states(P))
false

I suspect this is another case of the namespacing making things difficult to understand, as I have

julia> @nonamespace P.u  Set(states(P))
true

This issue might just be a documentation issue, I can't really find out how to think about the namespacing properly, I'm constantly baffled by how it behaves.

@ChrisRackauckas
Copy link
Member

Yeah I see this come up a few times. I think self-namespacing needs to be equality. @YingboMa ?

@YingboMa
Copy link
Member

YingboMa commented Jun 16, 2021

a.x is fundamentally different from x, and that's the point of namespacing. We need another model of doing composition if this is a problem.

@lamorton
Copy link
Contributor

I got bit by this too. As I understand it, SymbolicUtils overloads == b/c @variables don't have specific numeric values, even though they are subtypes of Number. OTOH, === appears not to work across namespace boundaries.

julia> using ModelingToolkit
julia> @parameters t
julia> @variables P(t)
julia> eqs = [D(P) ~ 1]
julia> sys = ODESystem(eqs)

julia> sys.P == P
var"##ODESystem#257₊P"(t) == P(t) # This is giving off "non-Boolean used in boolean context" 

julia> sys.P === P 
false

julia> P === P
true

julia> sys.P === sys.P # yikes!
false

@YingboMa
Copy link
Member

YingboMa commented Jun 17, 2021

Using triple-equal certainty won't work, and the results are expected. To check equality of symbolic variables, isequal should be used. Maybe you should read the documentation of ===, too. It checks equality in the sense that no program can differentiate the objects. We have metadata and other mutable information in symbolic expressions so that === will return false.

I'll close this because this not a software problem. It does what it is designed to do. If you want sys.P to be the same as P, describe your use-case and show that there's no other ways of achieving it.

@baggepinnen
Copy link
Contributor Author

This issue might just be a documentation issue, I can't really find out how to think about the namespacing properly, I'm constantly baffled by how it behaves.

Part of the reason for this issue is that it can be quite difficult to work with ModelingToolkit. The whole namespace thing is counter intuitive and the documentation does not really help. There might very well be another way of doing what we want, but how to figure this out? If issues like these were taken seriously I bet MTK would have a lot more happy users and contributors.

@YingboMa
Copy link
Member

I don't quite want to document this yet because I think behavior of composition and inheritance is going to change. I am also not very happy with the current design.

@baggepinnen
Copy link
Contributor Author

Oki, since you are considering redesigning it, I can share what I feel is the biggest problem with the current design from a user perspective: the behavior is counter intuitive. A user with Julia experience has a certain feeling for how objects behave, when they are equal and so on. This issue was opened because of such an instance where the user's expectation is that P.u refers to one of states(P), but the P.u syntax has been overloaded in a counter-intuitive way to mean something else. I believe a lot of headaches can be avoided by trying less to be clever with syntax (and display) and instead require the user to be explicit about what they mean, while keeping standard syntax (and display/printing) to mean what it means for most other julia code.

@YingboMa
Copy link
Member

I opened another issue that elaborated on what's the current behavior and why sys.x does not equal to x.

@YingboMa
Copy link
Member

@baggepinnen could you make an issue collecting all the parts of MTK that you think are poorly documented? Or is it mostly just how composition and inheritance work. I think spending too much time on the code makes me fail to see what's not obvious.

@cadojo
Copy link
Contributor

cadojo commented Jun 19, 2021

After reading through this and related issues, I now understand that sys.x and x are different. But then what is the preferred way for constructing an ODEProblem from an ODESystem in another package?

@ChrisRackauckas
Copy link
Member

We're going to fix this, which is the point of #1052 . sys.x and x should be the same by default, and namespacing should require @namespace. That's the current proposed solution at least: I kind of want a simpler operator but a macro isn't the worst thing.

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

5 participants