Conversione di un vettore complesso in un array diagonale sparso in Julia

Aug 24 2020

Sto cercando di replicare un calcolo da Matlab in Julia, ma ho problemi a convertire un array complesso a colonna singola in un array diagonalizzato sparso per la moltiplicazione di matrici.

Ecco il codice Matlab che sto cercando di replicare in Julia:

x*diag(sparse(y)) 

dove xè di taglia 60,600000ed è di tipo: double, ed yè di taglia 600000,1ed è di tipo: double complesso.

Risposte

2 PrzemyslawSzufel Aug 24 2020 at 06:59

Puoi usare Diagonalper questo:

using LinearAlgebra
x=rand(6,60)
y=rand(Complex{Float64},60,1)
x*Diagonal(view(y,:))

Ho usato view(y,:)per convertire yin a Vector- questo è qui un operatore di riduzione della dimensione, puoi anche usare una forma più breve vec(y). A seconda di cosa vuoi fare, potresti dire esplicitamente che vuoi la prima colonna per view(y,:,1).

Si noti che Diagonalè solo una rappresentazione sparsa di una matrice.

julia> Diagonal(1:4)
4×4 Diagonal{Int64,UnitRange{Int64}}:
 1  ⋅  ⋅  ⋅
 ⋅  2  ⋅  ⋅
 ⋅  ⋅  3  ⋅
 ⋅  ⋅  ⋅  4

Un'altra opzione che potrebbe coprire più scenari di casi d'uso sono BandedMatrices:

using BandedMatrices
x*BandedMatrix(0=>view(y,:))

Si noti che BandedMatrixutilizza un insieme di coppie per le bande, dove la banda 0 è in realtà la diagonale.

phipsgabler Aug 24 2020 at 13:58

Immagino che tu non intenda in questo modo, ma si può anche interpretare la domanda nel modo in cui yè un vettore sparso nel senso di Julia, e tu vuoi costruirne una matrice diagonale sparsa. In tal caso puoi fare quanto segue:

julia> y = sprand(10, 0.2)
10-element SparseVector{Float64,Int64} with 2 stored entries:
  [4 ]  =  0.389682
  [5 ]  =  0.232429

julia> I, V = findnz(y)
([4, 5], [0.3896822408908356, 0.2324294021548845])

julia> sparse(I, I, V)
5×5 SparseMatrixCSC{Float64,Int64} with 2 stored entries:
  [4, 4]  =  0.389682
  [5, 5]  =  0.232429

Sfortunatamente, spdiagmnon conserva gli zeri strutturali per un input sparso:

julia> spdiagm(0 => y)
10×10 SparseMatrixCSC{Float64,Int64} with 10 stored entries:
  [1 ,  1]  =  0.0
  [2 ,  2]  =  0.0
  [3 ,  3]  =  0.0
  [4 ,  4]  =  0.389682
  [5 ,  5]  =  0.232429
  [6 ,  6]  =  0.0
  [7 ,  7]  =  0.0
  [8 ,  8]  =  0.0
  [9 ,  9]  =  0.0
  [10, 10]  =  0.0

Non so se questo sia intenzionale, ma ho presentato un problema su questo comportamento.