2015-06-21 3 views
5

Sono stato felice di apprendere che Julia permette un modo meravigliosamente succinta per formare prodotti interni:Qual è il modo migliore per creare prodotti interni?

julia> x = [1;0]; y = [0;1]; 

julia> x'y 
1-element Array{Int64,1}: 
0 

Questa alternativa al dot(x,y) è bello, ma può portare a sorprese:

julia> @printf "Inner product = %f\n" x'y 
Inner product = ERROR: type: non-boolean (Array{Bool,1}) used in boolean context 

julia> @printf "Inner product = %f\n" dot(x,y) 
Inner product = 0.000000 

Così, mentre i 'Mi piacerebbe scrivere x'y, sembra meglio evitarlo, poiché altrimenti ho bisogno di essere consapevole delle insidie ​​relative agli scalari rispetto alle matrici 1-by-1.

Ma io sono nuovo di Julia, e probabilmente non sto pensando nel modo giusto. Altri usano questa alternativa succinta a dot e, in caso affermativo, quando è sicuro farlo?

+2

Non è molto chiaro che cosa avete bisogno (o non fare) e che cosa siete disposti a sacrificare, quindi non mi distacco una risposta: È possibile utilizzare il [ '⋅' operator] (http://julia.readthedocs.org/en/latest/stdlib/linalg/#Base.⋅) invece di 'punto'. Puoi anche [dichiarare] (http://julia.readthedocs.org/en/latest/manual/types/#type-declarations) quale tipo ti aspetti per una funzione variabile/di ritorno: 'x = [0; 1]: : Array {Float64,1} ' –

risposta

4

C'è un problema concettuale qui. Quando si esegue

julia> x = [1;0]; y = [0;1]; 
julia> x'y 
0 

che in realtà è trasformato in una matrice * prodotto vettoriale con dimensioni di 2x1 e 1 rispettivamente, risultante in una matrice 1x1. Altre lingue, come MATLAB, non distinguono tra una matrice 1x1 e una quantità scalare, ma Julia lo fa per una serie di motivi. Non è quindi mai sicuro utilizzarlo come alternativa alla "vera" funzione di prodotto interno dot, che è definita per restituire un'uscita scalare.

Ora, se non sei un fan degli dot s, puoi considerare sum(x.*y) di sum(x'y). Tieni anche presente che i vettori di colonne e righe sono diversi: in effetti, non esiste un vettore di riga in Julia, più che esiste una matrice 1xN. Così si ottiene cose come

julia> x = [ 1 2 3 ] 
1x3 Array{Int64,2}: 
1 2 3 

julia> y = [ 3 2 1] 
1x3 Array{Int64,2}: 
3 2 1 

julia> dot(x,y) 
ERROR: `dot` has no method matching dot(::Array{Int64,2}, ::Array{Int64,2}) 

You might have used a 2d row vector where a 1d column vector was required. 
Note the difference between 1d column vector [1,2,3] and 2d row vector [1 2 3]. 
You can convert to a column vector with the vec() function. 

Il messaggio di errore suggerimento è dot(vec(x),vec(y), ma sum(x.*y) funziona anche in questo caso, ed è più breve.

julia> sum(x.*y) 
10 

julia> dot(vec(x),vec(y)) 
10 
+0

' punto ([1,2,3], [4,5,6]) 'ora funziona su build notturno. –