convert composite type to a vector

134 views
Skip to first unread message

Tamas Papp

unread,
Mar 5, 2015, 4:51:36 AM3/5/15
to julia...@googlegroups.com
If I have a composite type

type Foo
a
b
c
end

I can initialize it with a vector like this:

x = Foo([1,2,3]...)

But how can I get the fields as a vector, eg [x.a,x.b,x.c] without
enumerating them? convert(x, Vector) does not work.

I need this to go back and forth between the type and the vector
representation of a set of parameters when using NLopt.

Best,

Tamas

Simon Danisch

unread,
Mar 5, 2015, 5:00:06 AM3/5/15
to julia...@googlegroups.com
easiest would probably be: [foo.(i) for i=1:length(names(Foo))]

Mauro

unread,
Mar 5, 2015, 5:10:14 AM3/5/15
to julia...@googlegroups.com
A bit more obfuscated (for immutable bittypes only):

julia> immutable Foo{T}
a::T
b::T
c::T
end

julia> x = Foo([1,2,3]...)
Foo{Int64}(1,2,3)

julia> reinterpret(Int, [x])
3-element Array{Int64,1}:
1
2
3

Tamas Papp

unread,
Mar 5, 2015, 5:26:07 AM3/5/15
to julia...@googlegroups.com
Thanks. If I wanted to add a method to convert, what could I dispatch
on, ie what is the supertype that has all composite and immutable types
(and only those?)

Using v"0.4.0-dev+3661".

Tamas

René Donner

unread,
Mar 5, 2015, 5:27:54 AM3/5/15
to julia...@googlegroups.com
And if you want to reduce memory allocations and your fields are all of the same type:

immutable Foo{T}
a::T
b::T
c::T
end

# this always works also for mutables / varying fieldtypes:
typevec(a) = [a.(x) for x in names(a)]

# create initial view
typevec!(foo::Foo) = pointer_to_array(
convert(Ptr{typeof(foo.a)}, pointer_from_objref(foo))+sizeof(typeof(foo.a)), 3)

# point to a different obj, reusing the view array
function typevec!(a, view)
p = convert(Ptr{eltype(view)}, pointer_from_objref(view))
unsafe_store!(p, pointer_from_objref(a)+sizeof(eltype(view)), 2)
view
end

foo = Foo(1,2,3)
foo2 = Foo(10,20,20)
@show @time typevec(foo)
@show @time view = typevec!(foo)
@show @time typevec!(foo2,view)


Just be careful that foo does not go out of scope while you use the result of "typevec!"

Simon Danisch

unread,
Mar 5, 2015, 6:19:05 AM3/5/15
to julia...@googlegroups.com
Just be careful that foo does not go out of scope while you use the result of "typevec!" 
this basically makes typevec! unsafe right? So, it probably should be prefixed like this.

Am Donnerstag, 5. März 2015 10:51:36 UTC+1 schrieb Tamas Papp:

René Donner

unread,
Mar 5, 2015, 6:27:13 AM3/5/15
to julia...@googlegroups.com
Sure, would be good!

I generally use this pattern only inside more general, pure functions that, say, loop over an array or list of items, where the data that is being viewed into is guaranteed to exist. I avoid to use these unsafe functions directly / on an adhoc basis, and I never pass the results around.
Reply all
Reply to author
Forward
0 new messages