-
-
Notifications
You must be signed in to change notification settings - Fork 49
Change output from Array{Array{Float64,1},1} to Array{Float64,2} #80
Comments
There is a simple, but non-intuitive, way, to convert from a julia> v = Vector{Float64}[[1, 2], [3, 4], [5, 6]]
3-element Array{Array{Float64,1},1}:
[1.0,2.0]
[3.0,4.0]
[5.0,6.0]
julia> hcat(v...)'
3x2 Array{Float64,2}:
1.0 2.0
3.0 4.0
5.0 6.0 Here, An alternative way to extract the first component from each is xs = [x[1] for x in v]
ys = [x[2] for x in v]
plot(xs, ys) |
Thanks a ton! This is very helpful. How can we fix this? Would it be possible to add something like the following to convert(::Type{Array{T,2}}, v::Array{Array{T,1},1}) = hcat(v...)' Or could we at least change the output of the ODE functions to give a |
Last time I checked, using a list comprehension was faster. This is actually an unexported function in ODE.jl: vcat_nosplat(y) = eltype(y[1])[el[1] for el in y] # Does vcat(y...) without the splatting Anyway, I also find this a bit annoying. Could the 2D array be the standard output for 1D array IC input? And only the vector of vectors for scalar-like things? Last, there is the scalar-like test https://github.com/JuliaLang/ODE.jl/blob/master/test/interface-tests.jl to look at. |
To be honest I am not a big fan of such a change (but I am ready to be convinced otherwise). The current API might be (mildly) annoying, but it is intuitive and consistent: the output always is a vector of solutions of the type of the IC. You can use any of those solutions immediately as an IC. The price you have to pay is calling How would you put the 1D arrays in the 2D output, row wise or column wise? |
Yes, you're right. It's just that I almost always do a hcat/vcat, which somewhat is annoying too. I'd do a column per time step. |
Without specific numbers, there might be some performance concern for using
Column default makes sense and transposing should be much easier than flattening. I don't really think consistency is an issue here. There's good reason that we have a nice type system and don't treat everything as a black box. A |
And now actual numbers. The benchmarks source can be found here and the results can be found in the same directory and is also pasted here,
The benchmark measures the effeciency for some basic operations including creating the buffers, converting them into different format and assessing elements (sum). As clearly shown above, creating arrays of arrays is mush slower, Concatenating the vectors is commonly even more expensive than transposing ( |
I am not saying that matrices are bad, it's just that |
My point is, "consistency" is pretty much the only possible reason for the current behavior but it's not really a good reason because the other way around is consistent with the distinction between array and scalar every else. For performance, you need a fairly big system for the overhead to not matter and it's very significant for small systems. For using the result, the current one is almost certainly not the form you want. For actual ODE, at least for what I've dealt with, I usually want to see the evolution of each degrees of freedom. For PDE, as you said, it's handy to present the results as 2d arrays. Even if you are somehow more interested in each vector, simply constructing subarray or arrayview is easy and cheap. |
The main argument for the current behavior is generality. I might want to integrate ODEs over some arbitrary Banach space, not just |
If you are doing arithmetics on a custom type, it's pefectly fine to return a |
@yuyichao : Don't get me wrong, I don't insist on the current behavior. However, we went through some discussions (#20) to define the current API, so we shouldn't make fast decisions now.
There is no logical reason why an ODE solver has to return a matrix either. Maybe this was introduced by MATLAB? Often solvers (like in Sundials) only return the final solution and one can access intermediate results only via some event system. The convenience really depends on the use case I suppose. If you are saying that there is no Julia function/package that gives
That also depends on what you want to do. If you want to evaluate some function |
Sure.
That would be a plus for least surprise. (Also for
I've never use Sundials but that interface sounds better. I also do this when I write these kind of functions to have a flexible interface to gather intermediate results, which could be a dummy one if you don't care about them or don't want to pay the overhead (or if they are simply too big to fit in the memory).
Well,
Agree. The point is that it is equally easy to do with matrix. Just do |
As another side note, I think the |
This is above my paygrade, but fwiw I think the majority of users would appreciate having a |
The plan was to use an iterator interface for the low level functions. Then On Do., 5. Nov. 2015 at 20:30, Alex Williams notifications@github.com
|
Perhaps the problem is, really, that we're using For example, indexing into an |
This would probably result in quite a bit of extra code to maintain. I'm not sure it would be worth it. |
Actually, some changes that made it into Julia 0.4 make it easier than ever to overload indexing; we only have to care about how indexing is handled for single elements, and then there are wrapper function in Base that handle indexing with ranges, colons etc. I think something like this would suffice to start with:
As you notice, the |
You can append to a vector and reshape if the size isn't known beforehand. |
Ah! That makes sense. That's also good because it can leave the internals of the solvers untouched, using |
@tlycken +1 on the idea of But with respect to this issue, there could be a benefit in dropping the As far as I can tell removing the constraint doesn't cost anything, since it can always be put back in later (e.g. with some kind of |
I'd also like to +1 @stevengj comment about allowing for generality in the type of the state variable. If his idea about chebfun-like representations sounds too exotic to some, I'd like to point out that it would also be desirable to accommodate the case where the state variable is a matrix (i.e. matrix differential equation) or higher order array, the applications of which are quite common. Having to pack/unpack matrices into vectors to set solutions to matrix odes was one of my number one pet peeves with fortran and MATLAB. Julia could lead to way to a better future for this area:) |
When I run
I get:
Which is annoying because I want to, for example, plot the evolution for the first dynamic variable:
Which doesn't work... It just plots all the dynamic variables. Is there a workaround for this? Or an easy way to convert
Array{Array{Float64,1},1}
toArray{Float64,2}
? Shouldn'tode45
be modified to return a 2D array?The text was updated successfully, but these errors were encountered: