-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathutil.py
109 lines (87 loc) · 2.57 KB
/
util.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
106
107
108
109
import numpy as np
from scipy import linalg
def norm_of_columns(A, p=2):
"""Vector p-norm of each column of a matrix.
Parameters
----------
A : array_like
Input matrix.
p : int, optional
p-th norm.
Returns
-------
array_like
p-norm of each column of A.
"""
_, N = A.shape
return np.asarray([linalg.norm(A[:, j], ord=p) for j in range(N)])
def coherence_of_columns(A):
"""Mutual coherence of columns of A.
Parameters
----------
A : array_like
Input matrix.
p : int, optional
p-th norm.
Returns
-------
array_like
Mutual coherence of columns of A.
"""
A = np.asmatrix(A)
_, N = A.shape
A = A * np.asmatrix(np.diag(1/norm_of_columns(A)))
Gram_A = A.H*A
for j in range(N):
Gram_A[j, j] = 0
return np.max(np.abs(Gram_A))
def asarray_1d(a, **kwargs):
"""Squeeze the input and check if the result is one-dimensional.
Returns *a* converted to a `numpy.ndarray` and stripped of
all singleton dimensions. Scalars are "upgraded" to 1D arrays.
The result must have exactly one dimension.
If not, an error is raised.
"""
result = np.squeeze(np.asarray(a, **kwargs))
if result.ndim == 0:
result = result.reshape((1,))
elif result.ndim > 1:
raise ValueError("array must be one-dimensional")
return result
def matdiagmul(A, b):
"""Efficient multiplication of matrix and diagonal matrix .
Returns the multiplication of a matrix *A* and a diagonal matrix. The
diagonal matrix is given by the vector *b* containing its elements on
the main diagonal. If *b* is a matrix, it is treated as a stack of vectors
residing in the last index and broadcast accordingly.
Parameters
----------
A : array_like
Input matrix.
b : array_like
Main diagonal elements or stack of main diagonal elements.
Returns
-------
array_like
Result of matrix multiplication.
"""
if len(b.shape) == 1:
b = b[np.newaxis, :]
K, N = b.shape
M, N = A.shape
C = np.zeros([K, M, N], dtype=A.dtype)
for k in range(K):
C[k, :, :] = A * b[k, :]
return C
def db(x, power=False):
"""Convert *x* to decibel.
Parameters
----------
x : array_like
Input data. Values of 0 lead to negative infinity.
power : bool, optional
If ``power=False`` (the default), *x* is squared before
conversion.
"""
with np.errstate(divide='ignore'):
return 10 if power else 20 * np.log10(np.abs(x))