I’m working on a project that involves solving something like a multi-particle problem (the application is not terribly important for my question), where each particle moves under a velocity field that depends on locations of all particles in the system (think planets affecting each other by gravity). I’m building the velocity field function that would eventually get passed onto ODEProblem
from DifferentialEquations.jl
.
To store each particle (in real plane, at least for now), I use the alias to
const Vec2D = StaticArrays.SVector{2}
I’m trying to use VectorOfArray
from RecursiveArrayTools.jl
to represent the ensemble of particles. (UPDATE: I originally used a plain vector of static vectors but ran into trouble with adaptive ODE integrators. Based on ODE of Vector of Matrices I decided to try out VectorOfArray
.)
I’m new convert from MATLAB to Julia, I’m adjusting to the multiple dispatch and types and syntax, so I have a few questions. (Any other suggestions based on the limited code I’m posting here are more than welcome.)
For example, I initialize two ensembles, of N
and M
random particles by:
pN = VectorOfArrays( [Vec2D(c) for c in eachcol(rand(2,N))] )
pM = VectorOfArrays( [Vec2D(c) for c in eachcol(rand(2,M))] )
Q1 I want to perform a computation over all pairs of particles. Guided by Broadcasting over combinations of inputs
For example, to simply list all pairs (without computing on them), I hoped that the following should work:
[ (v,w) for v in pN, w in pM ] # or
[ args for args in Iterators.product(pN, pM)]
but I get
ERROR: MethodError: no method matching Array{Tuple{SVector{2, Float64}, SVector{2, Float64}}, 4}(::UndefInitializer, ::Tuple{Int64, Int64})
Closest candidates are:
Array{T, N}(::UndefInitializer, ::Tuple{Vararg{Int64, N}}) where {T, N} at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/boot.jl:469
Array{T, N}(::UndefInitializer, ::Tuple{Vararg{Integer, N}}) where {T, N} at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/baseext.jl:36
Array{T, N}(::Missing, ::Any...) where {T, N} at /Applications/Julia-1.7.app/Contents/Resources/julia/share/julia/base/baseext.jl:43
So I’ve done
[ (v,w) for v in pN[:], w in pM[:] ] # or
[ args for args in Iterators.product(pN[:], pM[:])]
But using [:]
seems a bit… clunky? Is this the best way to go about doing this, or can I avoid the VectorOfArray
→ Vector
conversion ([:]
)? Should I be even worried (from efficiency/performance standpoint) about this?
Q2. Say that I wanted to define a type alias Ensemble
to ensure it’s a VectorOfArrays
holding only Vec2D
, how would I do it?
My guesses
const Ensemble = VectorOfArrays{Vec2D}
or
const Ensemble{T} = VectorOfArray{T,2,Vector{Vec2D{T}} } where {T <: Number }
(second guided by typeof(pN)
for pN
defined as above) did not work. They evaluate ok, but when I try a drop-in replacement
pN = Ensemble( [Vec2D(c) for c in eachcol(rand(2,N))] )
I get a
ERROR: MethodError: no method matching (VectorOfArray{T, 2, Array{SVector{2, T}, 1}} where T<:Number)(::Vector{SVector{2, Float64}})
and similar for the first type.