-
Notifications
You must be signed in to change notification settings - Fork 0
/
hysime.py
105 lines (79 loc) · 3.19 KB
/
hysime.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#
#
# HySime: Hyperspectral signal subspace estimation
# Input:
# y hyperspectral data set (each column is a pixel)
# with (L x N), where L is the number of bands
# and N the number of pixels
# w (L x N) matrix with the noise in each pixel
# Rw noise correlation matrix (L x L)
# verbose [optional] (on)/off
# Output
# kf signal subspace dimension
# Ek matrix which columns are the eigenvectors that span
# the signal subspace
#
# import needed packages and classes
import numpy as np
from scipy.sparse import csc_matrix
from scipy.sparse.linalg import svds
from scipy.linalg import block_diag
from numpy.linalg import inv
import warnings
import sys
import cvxopt
import matplotlib.pyplot as plt
def hysime(y, n, Rn, verbose = true):
y = arg[0]; # 1st parameter is the data set
L, N = y.shape
if not np.prod(y.shape):
raise ValueError("the data set is empty")
n = arg[1] # the 2nd parameter is the noise
Ln, Nn = n.shape
Rn = arg[2] # the 3rd parameter is the noise correlation matrix
d1, d2 = Rn.shape
#if nargin == 4, verbose = ~strcmp(lower(varargin{4}),'off');
if ln != L or Nn != N: # n is an empty matrix or with different size
raise ValueError("empty noise matrix or its size does",
"not agree with size of y\n")
if d1 != d2 or d1 != L:
print("Bad noise correlation matrix\n")
Rn = n * n.getH() / N
x = y - n
if verbose:
print(1, "Computing the correlation matrices\n")
L, N = y.shape
Ry = y * y.getH() / N # sample correlation matrix
Rx = x * x.getH() / N # signal correlation matrix estimates
if verbose:
print(1, "Computing the eigen vectors of the signal correlation matrix\n")
E, D = svds(Rx) # eigen values of Rx in decreasing order, equation (15)
dx = block_diag(D)
if verbose:
print(1, "Estimating the number of endmembers\n")
Rn = Rn + np.sum(block_diag(Rx)) / L / 10**10 * np.identity(L)
Py = block_diag(E.getH() * Ry * E) # equation (23)
Pn = block_diag(E.getH() * Rn * E) # equation (24)
cost_F = -Py + 2 * Pn # equation (22)
# syntax might need revision
kf = np.sum(cost_F < 0)
dummy, ind_asc = np.sort(cost_F)
Ek = E[:, ind_asc[1:kf]]
if verbose:
print(1, "The signal subspace dimension is: k = %d\n", kf)
# only for plot purposes, equation (19)
Py_sort = np.trace(Ry) - np.cumsum(Py(ind_asc))
Pn_sort = 2 * np.cumsum(Pn(ind_asc))
cost_F_sort = Py_sort + Pn_sort
fig = plt.figure()
semilogy(indice, cost_F_sort(indice), indice,Py_sort(indice), indice,Pn_sort(indice), 2, 5, **kwargs)
plt.semilogx([1, 10, 100], [1, 10, 100])
plt.xlabel("k")
plt.ylabel("mse(k)")
plt.title('HySime')
legend('Mean Squared Error','Projection Error','Noise Power')
plt.show()
return kf, Ek
# ------------------------------------------------------------------------------
# end of function [varargout]=hysime(varargin
# ------------------------------------------------------------------------------