2015-05-14 8 views
6

Si consideri il seguente codiceCome posso scrivere codice per lavorare con le matrici 1D in Julia?

function test(m,B) 
    @show typeof(B) 
    all_u = rand(m,10) 
    one_u = all_u[:,1] 
    B*one_u 
end 
# Works 
@show test(3, [1 1 1; 2 2 2]) 
# Works 
@show test(2, [1 1; 2 2]) 
# Fails 
@show test(1, [1; 2]) 

L'ultima riga non riesce con

`*` has no method matching *(::Array{Int64,1}, ::Array{Float64,1}) 

perché B è ora un vettore 1-D (che non è OK), e così è one_u (che è sempre il caso, e non causa problemi).

Come posso scrivere test(m,B) per gestire il caso m==1 che non richiede in realtà speciale involucro per m==1 (vale a dire utilizzando un if)? So che per il caso m==1 posso effettivamente scrivere un altro metodo di spedizione sul fatto che lo B è un Vector ma sembra terribilmente dispendioso.

+0

La tua domanda mi ricorda http://stackoverflow.com/questions/27153924/prevent-julia-from-automatically-converting-the-type-of-a-1d-matrix-slice .. Sarebbe 'one_u = all_u [:, 1: 1]' non fare il trucco? – Jubobs

+0

Se hai due array 1d e stai cercando il prodotto scalare, allora uso la funzione 'punto' (come in' punto (B, one_u) '). – spencerlyon2

+0

Jubobs che sembra molto simile, indagherò. spencerlyon2 Non so se ho due array 1D, dato che B è talvolta una matrice, a volte una matrice vettoriale/1D - questo è il problema. – IainDunning

risposta

6

citando your follow-up comment:

B è talvolta una matrice, talvolta una matrice vettore/1D - questo è il problema.

È possibile convertire un vettore in un array 2D con l'operazione "slicing" [:;:]. In altre parole, se B ha tipo Array{T,1}, quindi B[:,:] ha tipo Array{T,2}:

julia> B = [1; 2] 
2-element Array{Int64,1}: 
1 
2 

julia> typeof(B[:, :]) 
Array{Int64,2} 

D'altra parte, se B ha già tipo Array{T,2}, quindi [:;:] è un no-op:

julia> B = [1 1; 2 2] 
2x2 Array{Int64,2}: 
1 1 
2 2 

julia> typeof(B[:, :]) 
Array{Int64,2} 

julia> B[:, :] == B 
true 

Pertanto, per adattare la definizione della funzione per il caso m==1 (ovvero convertire B in un array 2D quando necessario), è possibile semplicemente sostituire B[:,:]*one_u per B*one_u:

julia> function test(m, B) 
      @show typeof(B) 
      all_u = rand(m, 10) 
      one_u = all_u[:, 1] 
      B[:, :] * one_u 
     end 
test (generic function with 1 method) 

julia> @show test(3, [1 1 1; 2 2 2]) 
typeof(B) => Array{Int64,2} 
test(3,[1 1 1;2 2 2]) => [1.4490640717303116,2.898128143460623] 
2-element Array{Float64,1}: 
1.44906 
2.89813 

julia> @show test(2, [1 1; 2 2]) 
typeof(B) => Array{Int64,2} 
test(2,[1 1;2 2]) => [0.9245851832116978,1.8491703664233956] 
2-element Array{Float64,1}: 
0.924585 
1.84917 

julia> @show test(1, [1; 2]) 
typeof(B) => Array{Int64,1} 
test(1,[1,2]) => [0.04497125985152639,0.08994251970305278] 
2-element Array{Float64,1}: 
0.0449713 
0.0899425 
Problemi correlati