forked from diffpy/diffpy.snmf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoptimizers.py
53 lines (40 loc) · 2.32 KB
/
optimizers.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
import numpy as np
import cvxpy
def get_weights(stretched_component_gram_matrix, linear_coefficient, lower_bound, upper_bound):
"""Finds the weights of stretched component signals under a two-sided constraint
Solves min J(y) = (linear_coefficient)' * y + (1/2) * y' * (quadratic coefficient) * y where lower_bound <= y <=
upper_bound and stretched_component_gram_matrix is symmetric positive definite. Finds the weightings of stretched
component signals under a two-sided constraint.
Parameters
----------
stretched_component_gram_matrix: 2d array like
The Gram matrix constructed from the stretched component matrix. It is a square positive definite matrix. It has
dimensions C x C where C is the number of component signals. Must be symmetric positive definite.
linear_coefficient: 1d array like
The vector containing the product of the stretched component matrix and the transpose of the observed data matrix.
Has length C.
lower_bound: 1d array like
The lower bound on the values of the output weights. Has the same dimensions of the function output. Each
element in 'lower_bound' determines the minimum value the corresponding element in the function output may take.
upper_bound: 1d array like
The upper bound on the values of the output weights. Has the same dimensions of the function output. Each element
in 'upper_bound' determines the maximum value the corresponding element in the function output may take.
Returns
-------
1d array like
The vector containing the weightings of the components needed to reconstruct a given input signal from the input
set. Has length C
"""
stretched_component_gram_matrix = np.asarray(stretched_component_gram_matrix)
linear_coefficient = np.asarray(linear_coefficient)
upper_bound = np.asarray(upper_bound)
lower_bound = np.asarray(lower_bound)
problem_size = max(linear_coefficient.shape)
solution_variable = cvxpy.Variable(problem_size)
objective = cvxpy.Minimize(
linear_coefficient.T @ solution_variable
+ 0.5 * cvxpy.quad_form(solution_variable, stretched_component_gram_matrix)
)
constraints = [lower_bound <= solution_variable, solution_variable <= upper_bound]
cvxpy.Problem(objective, constraints).solve()
return solution_variable.value