-
-
Notifications
You must be signed in to change notification settings - Fork 49
What to do with integer inputs? #26
Comments
It's good that we make a consious decision on this, but I can't think of a single use case when the user wouldn't want and expect option 4. |
You are pretty leet hacker if you want anything else than |
4 — The common convention in Julia is, in a function (like ODE integration) where only floating-point numeric types make sense, other numeric arguments are promoted to floating-point as needed. (See e.g. any of the transcendental math functions like This isn't any less "correct" than 3. It's not a question of correctness, it's a question of defining the function in the most useful way. |
4 also applies to rational inputs, for the same reasons. |
See e.g. how quadgk does the promotion. You do the implementation assuming everything is the same floating-point type (or complex version thereof), and then write a separate generic method that promotes all arguments to the same type as needed. |
@stevengj I'm not sure |
I think we should explicitly check for nonsensical It looks like everybody agrees that if a user supplies machine integers if(y0 <: Int || eltype(y0) <: Int)
y0 = float(y0)
end |
@ivarne Sure, but at the same time it's reasonable to assume that any user of an ODE library realizes that the solution space for any ODE problem is spanned by (a tensor power of) the real numbers. Trying to restrict the solution to an ODE to rational numbers just doesn't make sense - at least not with the algorithms we have implemented. Thus, if the input arguments do not support (and behave well) under float conversion, there's something fundamentally wrong with them. |
You guys probably have a better understanding about what kind of numeric types it makes sense for ODE solvers to run on. I just wanted to challenge your assumptions to see if there are fundamental reasons why we should always convert everything to We could (in the future) create a keyword arg to disable the |
@tlycken, a simple technique would be to first apply @ivarne, I don't understand why you think an integer input is a "mistake". Is it a mistake to type |
@stevengj Yeah, that's a good approach to get a correctly typed |
@tlycken, the whole point of duck typing is that you don't need to declare the type. When the (Nor do I think that you need to call a separate method after promotion of In other words, you define something like:
where I have used |
@stevengj I do think When it comes to ODE solvers are generic algorithms that does (to my knowledge) generic operations where it might make sense to allow exotic types to propagate. When the algorithms makes assumptions about the numeric properties of the underlying type, they can raise errors if the given type does not make sense. Also I have not checked with SIUnits or other wrapping types, but as we do not have Multiple inheritance, they will often be unable to inherit from everything you want them to. I just feel that it is useless to restrict values to |
You need to be careful to avoid dispatch loops. Actually, even the snippet I gave above has a problem for
which will work with any ODE integration over (e.g.) complex But I don't see any sensible use case for not doing some kind of floating-point promotion in an ODE solver, whether via There is a perfectly sensible reason to use |
(PS. I disagree that |
(@stevengj Good to see that we actually agree on the important stuff. Promotion rules that extends to user defined types is definitely awesome, but the discussion is not about promotion in general. Julia has not defined |
Using them as (effectively) a Given that fact, it is unhelpful to throw an error. |
On a separate note, an easier way to prevent dispatch loops here is to just call an |
Yes there is. With fixed timestep methods this is clearly possible. With adaptive methods, you just have to check your timestepping to change by rational values. One scheme for this is do reject/accept by doubling/halving the timestep. Using integer and rational values for time can be good for ODE solvers which form the backend to DDE solvers since those are not very robust to small intervals that are due to propagation of discontinuities (this arises since 1/3 + 1/3 + 1/3 != 1 in floating point). |
A common dilemma in Julia, is what to do when the user provides integers to a function where they probably want do do the calculation in floating point. Many users do not care about the difference between
13.
and13
, and does not want the "wrong" result when they forget the.
.Suggestions
InexactError
99.9 % of the timefloat
internally, but convert back to Int before returningT <: Integer
tofloat
, and return floating point results.It seems to be the general opinion that ODE solvers are performance sensitive, and we want them to be type stable, both internally and externally, to improve performance. We then have to decide what we want to do when the user supplies integers to
tspan
andy0
.The text was updated successfully, but these errors were encountered: