I am trying to solve the following minimization problem:
$$ \min\lvert\lvert{x}\rvert\rvert_1 + \beta\lvert\lvert{x}\rvert\rvert^2_2 s.t. \sum_{m = 1}^M (y - \lvert{c}^{H} . x\rvert^2)^2 \le \epsilon $$
x
: my unknown value (input) with complex elements and known size, here (4x1)y
: the output vector (known)c
: a 'skaling' vector
I am very new to this so my approach may seem basic. I simply loop over all combination of c
(non-redundant) and according to the computed minimization value and condition I update my results.
My questions are the following:
- Is this correct and is there a better approach to this?
- This code fails with a small step due to the huge size of combinations, so how can I solve that?
from itertools import combinations
from random import randint
import numpy as np
def deg2rad(phase):
return round(((phase*3.14)/180),3)
def excitation(amplitude, phase):
return complex(round(amplitude * (np.cos(deg2rad(phase))),3), round(amplitude*(np.sin(deg2rad(phase))),3))
def compute_subject_equation_result(x):
M = 12
difference = []
y = [randint(10, 20) for i in range(M)]
for m in range(0, M):
c = np.array([randint(0, 9), randint(10,20), randint(0, 9), randint(0,20)]).reshape(4,1)
ch = c.conjugate().T
eq = (y[m] - (abs(np.dot(ch, x))[0])**2)**2
difference.append(eq**2)
return round(sum(difference)[0], 3)
def compute_main_equation_result(x, beta):
norm1 = np.linalg.norm(x,1)
norm2 = np.linalg.norm(x,2)
return round(norm1 + beta*(norm2**2), 3)
def optimize(x, min_x, min_phi_x):
min_result = 10**25
# compute the optimization formals and check for the min value
main_equation_result = compute_main_equation_result(c, beta)
subject_equation_result = compute_subject_equation_result(c)
# update min value if min detected'
if subject_equation_result < epsilon and main_equation_result < min_result:
min_result = main_equation_result
min_x = x
min_phi_x = phx
return min_x, min_phi_x
# initialization
phases = [alpha for alpha in range(0, 361, 90)]
beta = 1
epsilon = 10**25
min_x = np.array([])
min_phi_x = np.array([])
phases_combinations = [list(comb) for comb in combinations(phases, 4)]
# start checking all combinations
for phx in phases_combinations:
phi1, phi2, phi3, phi4 = phx[0], phx[1], phx[2], phx[3]
# build the hypothesis for the excitations vector c
c = np.array([ excitation(1, phi1), excitation(1, phi2), excitation(1, phi3), excitation(1, phi4) ]).T.reshape(4,1)
min_x, min_phi_x = optimize(c, min_x, min_phi_x)
print(' --------------------------------------------------')
print('-----> new_min_c = ', list(min_x))
print('-----> new_min_phi_c = ', min_phi_x)
Remark: When trying phases = [alpha for alpha in range(0, 361, 1)]
I get a "memory error". I can avoid using a higher step. However I am not sure about my approach in general nor of the step change effect on the accuracy.