On Mon, 2016-06-20 at 10:32, Chris Rackauckas <rackd...@gmail.com> wrote: > I agree rationals don't make sense in most cases (I did it once just for > fun), but how would it work with other defined numbers as they come? Will > the promotions "just work?"
No. It is the duty of the type-creator to embed their new type into the promotion system of Julia. > But as mentioned, applying f once and using the types from there would > catch most cases. Yes, that is the general strategy but I find it quite hard to do it correctly (otherwise, I'd have caught this before...) > On Monday, June 20, 2016 at 9:00:28 AM UTC+1, Mauro wrote: >> >> I'd say this is a bug. `sin(5)` works, so `ode23(f, 0, [0,1])` should >> work too by promoting `y0=0` and `tspan=[0,1]` to appropriate types. >> Note that `eltype(tspan)` needs to be promoted to some kind of floating >> point number; I don't think rationals make sense for >> differential-equations. I pushed a fix, at least for the Runge-Kutta >> solvers of ODE.jl: https://github.com/JuliaLang/ODE.jl/pull/96 >> >> On Mon, 2016-06-20 at 07:09, Gabriel Gellner <gabriel...@gmail.com >> <javascript:>> wrote: >> > Fair enough. I guess if the urge is to support strangely generic code >> then >> > the inputs should never be expected to be promoted. But I just don't see >> > what you are describing as being a "standard" in Julia. ODE.jl and your >> > project maybe try to attain this level of genericity, but most of Base >> > seems to do this kind of promotion, and doesn't always return the types, >> or >> > give an inexact error, when you provide certain inputs (like returning >> > Rational if you input Rational). Optim.jl, Roots.jl, Disributions.jl >> > doesn't do this, quadgk doesn't give back rationals, etc. The standard >> > libraries I use the most often I guess. >> > >> > A user that is told that type in type out is the standard in Julia, and >> > that strange error messages like the OP had are not bugs, would have >> great >> > reason to be skeptical that this is actually a contract that is commonly >> > followed. Maybe this is the way Julia is going. I hope that doing the >> > common case will never get too annoying (like throwing a type error so I >> > can have the unlikely case that I an use Rational inputs for an ode >> solver >> > ;), and that all my code would be expected to be filled with eltypes and >> > inexact errors. We shall see. >> > >> > On Sunday, June 19, 2016 at 7:32:55 PM UTC-7, Chris Rackauckas wrote: >> >> >> >> But I gave an example where the output type can change depending on the >> >> chosen timespan (eltype(y0)==Rational{Int}), so "eltype(f(y0))" can >> really >> >> only be what the time integration algorithm actually produces, which >> means >> >> you have to just run it and see what happens. It becomes a >> type-stability >> >> issue because the internals of the functions are using similar(y0) to >> make >> >> all the arrays (well, with some promotions before doing so), and so >> each >> >> time you go through the loop you're banking on getting the same type. >> The >> >> other way to handle this would be to make the arrays something like a >> Float >> >> which just always kind of work, so this "bug" was likely introduced >> when >> >> the integrator were upgraded to allow for output to be any type (That's >> >> what introduced this issue in DifferentialEquations.jl, so I assume >> that's >> >> what happened in ODE.jl as well). >> >> >> >> The examples you gave are cases where the output is set (Int/Int >> returns >> >> on Float no matter what), or where the type promotion isn't too >> difficult >> >> (quadgtk is a linear combination of values from a to b, so just check >> the >> >> element type of the intermediate values that you're using and promote >> >> everything to that). But if you don't want to do the first, and you're >> >> dealing with a case where type inference is essentially undecidable, >> you >> >> will have this issue. >> >> >> >> That said, using the heuristic of "eltype(f(y0))" will do better than >> it >> >> currently does (it would catch the case where all inputs are an Int but >> one >> >> application makes things floats, which is probably the most common >> problem). >> >> >> >> On Monday, June 20, 2016 at 3:13:44 AM UTC+1, Gabriel Gellner wrote: >> >>> >> >>> I will admit my understanding of type stability in a jit compiler is >> >>> shakey, but I don't see 0.5//2 as a type instability, rather it is a >> method >> >>> error (the issues is a float does not convert to an int, but having a >> int >> >>> become a float is a fair promotion, so I can't see why requiring y0 to >> be a >> >>> float is at all similar -- it is very Julian to promote it). I >> understand >> >>> type instability to mean that the output of function is not uniquely >> >>> determined by its inputs. In this sense there is no type instability. >> The >> >>> issue as I understand it is that we do eltype(y0) for the output type, >> when >> >>> maybe it makes more sense to do eltype(f(y0)) which would then be type >> >>> stable, since f is. This would even work if you did y0 = 3f0, etc. >> >>> >> >>> Again I could be missing something simple, but requiring the inputs >> >>> to agree with the output of the input function feels like something >> far >> >>> beyond any kind of Julia difference from other languages, and more a >> >>> feature of it being a dynamic language and not purely static. >> Suggesting >> >>> users, especially new users, to be worry about these situations >> doesn't >> >>> jive with my understanding of Julia. It feels like premature >> optimization >> >>> to me. >> >>> >> >>> >> >>> On Sunday, June 19, 2016 at 6:38:37 PM UTC-7, Chris Rackauckas wrote: >> >>> >> >>>> I mean, it's the same type instability that you get if you try things >> >>>> like .5//2. Many Julia function work with ints that give a float, but >> not >> >>>> all do. If any function doesn't work (like convert will always fail >> if you >> >>>> somehow got a float but initialized an array to be similar(arrInt)), >> then >> >>>> you get this error. >> >>>> >> >>>> This can be probably be masked a little by pre-processing. I know >> that >> >>>> ODE.jl makes the types compatible to start, but that doesn't mean >> they will >> >>>> be after one step. For example, run an Euler step with try-catch and >> then >> >>>> have it up the types to whatever is compatible, then solve the ODE. >> And >> >>>> this has almost no performance penalty in most cases (and would be >> easy to >> >>>> switch off). But I don't know if this goes into a low level "this >> uses this >> >>>> method to solve the ODE" that ODE.jl implements. But even if you do >> this, >> >>>> you won't catch all of the type errors. For example, if you want to >> use >> >>>> Rational{Int}, it can take quite a few steps to overflow the >> numerator or >> >>>> denominator, but once it does, you get an InexactError (and the >> solution is >> >>>> to use Rational{BigInt}). >> >>>> >> >>>> You can use some try-catch phrases in the main solver, or put the >> solver >> >>>> in a try-catch and have it fix types and re-run, but these are all >> things >> >>>> that would be non-intuitive behavior and would have to be off by >> default. >> >>>> But at that point, the user would probably know to just fix the type >> >>>> problem. >> >>>> >> >>>> So honestly I don't think that there's a good way to make this >> "silent". >> >>>> But this is the fundamental trade off in Julia that makes it fast, >> and it's >> >>>> not something that is just encountered here, so users will need to >> learn >> >>>> about it pretty quick or else they will see lots of other >> >>>> functions/packages break. >> >>>> >> >>>> On Monday, June 20, 2016 at 2:07:30 AM UTC+1, Gabriel Gellner wrote: >> >>>>> >> >>>>> Is this truly a type instability? >> >>>>> >> >>>>> The function f has no type stability issues from my understanding of >> >>>>> the concept. No matter the input types you always get a Float output >> so >> >>>>> there is no type instability. Many of Julia's functions work this >> way, >> >>>>> including division 1/2 -> float even though the inputs are ints. >> >>>>> >> >>>>> The real issue is that ode23 infers the type of the output from y0 >> >>>>> which in this case is an int, but I don't see how this is the >> correct >> >>>>> inference. Maybe it is desired, but I hardly see this as normal >> Julia >> >>>>> behavior. I can happily mix input types to arguments in many Julia >> >>>>> constructs, without forcing me to have to use the same input vs >> output >> >>>>> type. matrix mult, sin, sqrt, etc etc. Isn't this exactly what >> convert >> >>>>> functions are for? >> >>>>> >> >>>>> hell the developer docs say that literals in expressions should be >> ints >> >>>>> so that conversions can be better. that is they say I should right >> 2*x not >> >>>>> 2.0*x so that type promotions can work correctly. The issue in this >> case is >> >>>>> that an implementation detail is being exposed to the user, that >> eltype(y0) >> >>>>> is determining the output of the function. I don't see that this is >> >>>>> standard Julian practice, though it might be desired in this case. >> For >> >>>>> example I can use quadgk(f, 1, 2) and not have an error because of >> the >> >>>>> integer a, b. And that is a very similar style function Base method. >> >>>>> >> >>>>> Maybe I am missing something simple, but I worry being to harsh >> about >> >>>>> types when it feels unessary. >> >>>>> >> >>>>> >> >>>>> On Sunday, June 19, 2016 at 5:28:39 PM UTC-7, Chris Rackauckas >> wrote: >> >>>>> >> >>>>>> I wouldn't call this a bug, it's a standard Julia thing for a >> reason. >> >>>>>> You get an InexactError() because you start with an Int and you do >> an >> >>>>>> operation which turns the Int into a Float so the program gets mad >> at the >> >>>>>> type instability. You can just change everything to floats, but >> then you're >> >>>>>> getting rid of the user choice. For example, if you change >> everything to >> >>>>>> floats, you can't solve it all using rationals of BigInts or >> whatever crazy >> >>>>>> numbers the user wants. However, if you let the number operations >> do as >> >>>>>> they normally do, the user can get an answer in the same way that >> they >> >>>>>> provide it. And it's not like this is a weird thing inside some >> >>>>>> mathematical packages, this is normal Julia behavior. >> >>>>>> >> >>>>>> But this kind of thing will cause issues for first-timers in Julia. >> It >> >>>>>> should be front and center in the Noteworthy Differences from Other >> >>>>>> Languages that if you really want a float, start with a float. >> >>>>>> >> >>>>>> On Sunday, June 19, 2016 at 10:06:42 PM UTC+1, Gabriel Gellner >> wrote: >> >>>>>>> >> >>>>>>> You are passing in the initial condition `start` as an integer, >> but >> >>>>>>> ode23 needs this to be a float. Change it to `const start = 3.0` >> and you >> >>>>>>> are golden. This does feel like a bug you should file an issue at >> the >> >>>>>>> github page. >> >>>>>>> >> >>>>>>> On Sunday, June 19, 2016 at 11:49:55 AM UTC-7, Joungmin Lee wrote: >> >>>>>>>> >> >>>>>>>> Hi, >> >>>>>>>> >> >>>>>>>> I am making simple examples of the ODE package in Julia, but I >> >>>>>>>> cannot make a code without error for 1st order ODE. >> >>>>>>>> >> >>>>>>>> Here is my code: >> >>>>>>>> >> >>>>>>>> using ODE; >> >>>>>>>>> >> >>>>>>>>> function f(t, y) >> >>>>>>>>> x = y >> >>>>>>>>> >> >>>>>>>>> dx_dt = (2-x)/5 >> >>>>>>>>> >> >>>>>>>>> dx_dt >> >>>>>>>>> end >> >>>>>>>>> >> >>>>>>>>> const start = 3; >> >>>>>>>>> time = 0:0.1:30; >> >>>>>>>>> >> >>>>>>>>> t, y = ode23(f, start, time); >> >>>>>>>>> >> >>>>>>>> >> >>>>>>>> It finally gives: >> >>>>>>>> LoadError: InexactError() >> >>>>>>>> while loading In[14], in expression starting on line 1 >> >>>>>>>> >> >>>>>>>> in copy! at abstractarray.jl:310 >> >>>>>>>> in setindex! at array.jl:313 >> >>>>>>>> in oderk_adapt at >> >>>>>>>> C:\Users\user\.julia\v0.4\ODE\src\runge_kutta.jl:279 >> >>>>>>>> in oderk_adapt at >> >>>>>>>> C:\Users\user\.julia\v0.4\ODE\src\runge_kutta.jl:220 >> >>>>>>>> in ode23 at C:\Users\user\.julia\v0.4\ODE\src\runge_kutta.jl:210 >> >>>>>>>> >> >>>>>>>> The example of 2nd order ODE at the GitHub works fine. >> >>>>>>>> >> >>>>>>>> How should I edit the code? >> >>>>>>>> >> >>>>>>> >>