Broadcasting vectors and matrices in Julia

SeSodesa :

I would like to use a dotted version of a scalar function to calculate values for an entire matrix of inputs. The function is defined as follows:

function SpecificCharge(U, r, B)
 ( 2 * U ) / ( r^2 * B^2 )
end

and I would like to give it the following inputs:

const Us = [ # voltages U
  228.9, 243, 257, 271, 285, 300
]

const Rs = [ # radii r
  9 7 5.8 5 4.3 3.9;
  10.5 8.1 6.7 5.7 4.9 4.5;
  10.1 8.3 7.1 6.5 6 4.8;
  11.1 9.0 7.2 6.5 5.6 5.1;
  10.5 8.3 7.8 6.5 5.7 5.4;
  11.9 8.9 8.0 7.4 6.2 5.5
]

const Bs = [ # flux densities B
  0.0007332339999999999, 0.00089328, 0.0010421599999999999, 0.00119104, 0.00133992, 0.0014873112
]

# Calling the dotted version of the function
specific_charges = SpecificCharge.(Us, Rs, Bs)

The result should be a matrix of same dimensions as Rs, with each radius replaced by the corresponding specific charge, given by SpecificCharge. There is one flux density corresponding to each U--B pair, and the rows in Rs correspond to voltages U and columns to flux densities B.

The problem is, I'm not sure how broadcasting works in Julia. Does the function SpecificCharge. work as is, if I just transpose the vectors Us and Bs appropriately, or do I need to complicate the function itself to make this work?

fredrikekre :

Does the function SpecificCharge. work as is, if I just transpose the vectors Us and Bs appropriately, or do I need to complicate the function itself to make this work?

Did you try it? It works as written, however, I am guessing you want to transpose either Us or Bs to get the correct "coupling".


When you use broadcast with different array dimensions (vectors and matrices in your example) Julia will "extend" arrays in the singleton dimensions. E.g. a vector will be extended to a matrix with a copy of the vector in each column. Here is an example to illustrate this

julia> A = ["A1", "A2"];

julia> B = ["B11" "B12" "B13";
            "B21" "B22" "B23"];

julia> f(args...) = join(args, ", ");

julia> f.(A, B)
2×3 Array{String,2}:
 "A1, B11"  "A1, B12"  "A1, B13"
 "A2, B21"  "A2, B22"  "A2, B23"

As you can see, the vector A has been extended in the singleton dimension to

julia> A2 = [A A A]
2×3 Array{String,2}:
 "A1"  "A1"  "A1"
 "A2"  "A2"  "A2"

such that it has the same size as B, and then f is applied to each pair. To extend a vector in the other dimension you need to permute it;

julia> C = ["C1", "C2", "C3"];

julia> f.(B, permutedims(C))
2×3 Array{String,2}:
 "B11, C1"  "B12, C2"  "B13, C3"
 "B21, C1"  "B22, C2"  "B23, C3"

and now C has been extended in the first dimension (the singleton dimension), essentially

julia> C2 = [permutedims(C); permutedims(C); permutedims(C)]
3×3 Array{String,2}:
 "C1"  "C2"  "C3"
 "C1"  "C2"  "C3"
 "C1"  "C2"  "C3"

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=390571&siteId=1