Reshaping a broadcasted expression

Viewed 86

I would like to make the following broadcasted expression work:

J = rand(4,4)
fx1 = rand(2,2)
fx2 = rand(2,2)
@. J[:,1] = fx1 + fx2

I really want some kind of:

@. J[:,1] = vec(fx1 + fx2)

where this vec is saying it should reshape to be 4x1, but I don't want to have to make this allocating. How could this be generically handled (i.e. no indexing on the fx)?

3 Answers

You can "exempt" vec from the @. macro by protecting it with a $:

julia> expand(:(@. J[:,1] = $vec(fx1) + $vec(fx2)))
:((Base.broadcast!)(+, (Base.dotview)(J, :, 1), (vec)(fx1), (vec)(fx2)))

Another possibility, is instead of vec-ing the fx1 and fx2 to reshape the slice of J:

Jcol = reshape(view(J,:,1),(2,2))
@. Jcol = fx1 + fx2

Not sure about efficiency, but it may give a clearer perspective depending on the surrounding algorithm. The LLVM code seems short enough and the assignment statement is clear.

Since vecs are views, the following works:

J = rand(4,4)
fx1 = rand(2,2)
fx2 = rand(2,2)
vfx1,vfx2 = vec(fx1),vec(fx2)
@. J[:,1] = vfx1 + vfx2

I don't think there's a way to do it in one line like I wanted, but this is fine.

Related