@@ -108,50 +108,45 @@ def _check_set_k(self, operator: BaseOperator | PauliSumOp) -> None:
108
108
self ._k = self ._in_k
109
109
110
110
def _solve (self , operator : BaseOperator | PauliSumOp ) -> None :
111
- if isinstance (operator , PauliSumOp ):
112
- sp_mat = operator .to_spmatrix ()
111
+ if isinstance (operator , Operator ):
112
+ # Sparse SciPy matrix not supported, use dense NumPy computation.
113
+ op_matrix = operator .data
114
+ if op_matrix .all () == op_matrix .conj ().T .all ():
115
+ eigval , eigvec = np .linalg .eigh (op_matrix )
116
+ else :
117
+ eigval , eigvec = np .linalg .eig (op_matrix )
118
+ else :
119
+ if isinstance (operator , PauliSumOp ):
120
+ op_matrix = operator .to_spmatrix ()
121
+ else :
122
+ op_matrix = operator .to_matrix (sparse = True )
123
+
113
124
# If matrix is diagonal, the elements on the diagonal are the eigenvalues. Solve by sorting.
114
- if scisparse .csr_matrix (sp_mat .diagonal ()).nnz == sp_mat .nnz :
115
- diag = sp_mat .diagonal ()
125
+ if scisparse .csr_matrix (op_matrix .diagonal ()).nnz == op_matrix .nnz :
126
+ diag = op_matrix .diagonal ()
116
127
indices = np .argsort (diag )[: self ._k ]
117
128
eigval = diag [indices ]
118
- eigvec = np .zeros ((sp_mat .shape [0 ], self ._k ))
129
+ eigvec = np .zeros ((op_matrix .shape [0 ], self ._k ))
119
130
for i , idx in enumerate (indices ):
120
131
eigvec [idx , i ] = 1.0
121
132
else :
122
133
if self ._k >= 2 ** operator .num_qubits - 1 :
123
134
logger .debug (
124
135
"SciPy doesn't support to get all eigenvalues, using NumPy instead."
125
136
)
126
- if operator . is_hermitian () :
137
+ if ( op_matrix != op_matrix . H ). nnz == 0 :
127
138
eigval , eigvec = np .linalg .eigh (operator .to_matrix ())
128
139
else :
129
140
eigval , eigvec = np .linalg .eig (operator .to_matrix ())
130
141
else :
131
- if operator . is_hermitian () :
132
- eigval , eigvec = scisparse .linalg .eigsh (sp_mat , k = self ._k , which = "SA" )
142
+ if ( op_matrix != op_matrix . H ). nnz == 0 :
143
+ eigval , eigvec = scisparse .linalg .eigsh (op_matrix , k = self ._k , which = "SA" )
133
144
else :
134
- eigval , eigvec = scisparse .linalg .eigs (sp_mat , k = self ._k , which = "SR" )
135
-
136
- indices = np .argsort (eigval )[: self ._k ]
137
- eigval = eigval [indices ]
138
- eigvec = eigvec [:, indices ]
139
- else :
140
- logger .debug ("SciPy not supported, using NumPy instead." )
141
-
142
- if isinstance (operator , Operator ):
143
- op_matrix = operator .data
144
- else :
145
- op_matrix = operator .to_matrix ()
146
-
147
- if op_matrix .all () == op_matrix .conj ().T .all ():
148
- eigval , eigvec = np .linalg .eigh (op_matrix )
149
- else :
150
- eigval , eigvec = np .linalg .eig (op_matrix )
145
+ eigval , eigvec = scisparse .linalg .eigs (op_matrix , k = self ._k , which = "SR" )
151
146
152
- indices = np .argsort (eigval )[: self ._k ]
153
- eigval = eigval [indices ]
154
- eigvec = eigvec [:, indices ]
147
+ indices = np .argsort (eigval )[: self ._k ]
148
+ eigval = eigval [indices ]
149
+ eigvec = eigvec [:, indices ]
155
150
156
151
result = NumPyEigensolverResult ()
157
152
result .eigenvalues = eigval
0 commit comments