Tuple of Arrays: assigning or accumulating into the first column of each tuple elements

I’m trying to apply a matrix A to a single column of each element of X and accumulate into X, where X is a tuple of arrays.

N = 2
A = rand(N,N)
X = (ones(N,N),ones(N,N))
for fld in eachindex(X)
    X[fld][:,1] += A*X[fld][:,1]
end    

I can apply A*X[fld][:,1] to all fields using map and broadcasted getindex, but I get an error if I try to set or accumulate into the columns of elements of the tuple

getindex.(X,(:),1) .+= map(x->A*x,getindex.(X,(:),1)) # doesn't work

Is there a way to do this without looping over the elements of the struct?

Hi Jesse,

I hope this is what you want. If you are writing in global scope and the code is performance sensitive then:

 f!(X,A)=X[:,1] += A*X[:,1]
f! (generic function with 2 methods)

f!.(X,Ref(A)) #note the dot

If not, then the simpler:

f!(X)=X[:,1] += A*X[:,1]
f!.(X)

Or maybe i misunderstood :slight_smile:

Cheers!

1 Like

Hi Rami - thanks! The evaluating of A*X isn’t the issue, it’s storing it back into X which causes me problems. I’m trying to figure out how to do

X[1][:,1] = f!.(X)[1]
X[2][:,1] = f!.(X)[2]

without having to loop through the tuple elements.

The result is stored in X:

**julia>** A = rand(N,N)

2×2 Array{Float64,2}:

 0.96716 0.878143

 0.703457 0.99305 

**julia>** X = (ones(N,N),ones(N,N))

([1.0 1.0; 1.0 1.0], [1.0 1.0; 1.0 1.0])

**julia>** for fld in eachindex(X)

X[fld][:,1] += A*X[fld][:,1]

end  

**julia>** X

([2.8453 1.0; 2.69651 1.0], [2.8453 1.0; 2.69651 1.0])

**julia>** X = (ones(N,N),ones(N,N))

([1.0 1.0; 1.0 1.0], [1.0 1.0; 1.0 1.0])

**julia>** f!.(X)

([2.8453, 2.69651], [2.8453, 2.69651])

**julia>** X
([2.8453 1.0; 2.69651 1.0], [2.8453 1.0; 2.69651 1.0])
1 Like

AH - my mistake, I missed that! Thanks, that works great.