def calc_r(u, L): # calculate r """ Calculates r as: r = u[L] / (1 - norm2^2( u[L-1] ) ) * u[1:L-1] """ if (L==2): # 0, 1 -> L-1=1 r = u[L-1] / (1-fun.norm2(u[0])) * u[0] else: # r = u[L-1] / (1-fun.norm2(u[0:L-1])) * u[0:L-1] return r
def qp_relax(h, P, Ku, L): """ Implementation of the proposed algorithm by [ZM15]. Returns a tuple with the calculated computation rate and the integer valued coefficient vector aQ. Parameters ---------- h: array-like channel coefficient vector P: float Power Ku: int upper bound for K (maximal possible value in aQ) L: int length of channel vector/ aQ (=number of senders in the system) """ K = 0 # K Kl = 0 # running K d = 0.0 h_abs = np.absolute(h)# calculates the absolute of h t = np.ones(L) # signs of original channel vector a = np.ones(L) # coefficient vector t = np.copysign(t, h)# copies signs of h elementwise to t (+/-1) p = np.argsort(h_abs, kind='quicksort') # indexes of sorted channel vector h_abs_sorted = np.copy(h_abs[p]) # ascending ordered vector b = 1 + P * fun.norm2(h) # part of denominator in Computation Rate formula in [1] u = normalize_vector(P, b, h_abs_sorted) # normalized channel vector r = calc_r(u, L) # aC1 = init_aC(L, r) # normalized initial a aC = np.zeros(L) # used to test k*aC1 """ DETERMINE K """ if fun.nf(Ku, aC1) < b: K = Ku else: Kl = 1 while (Ku != (Kl+1)): K = fun.fl(0.5*(Ku+Kl)) if fun.nf(K, aC1) < b: Kl = K else: Ku = K K = Kl """ Quantization """ aQ = np.zeros(L, dtype=np.int) aQ[L-1] = 1 """ norm2(aQ) = 1 , (aQ)^T * u = u[L-1] """ # initially the maximum comp rate achievable is at fmin # fmin is reached if only one element in coeff vector is 1 fmin = 1 - np.power(u[L-1], 2) if K == 1: # prevent from having empty range at K=1 k_range = [1] else: k_range = range(1, K+1) for k in k_range: aC = k * aC1 d = np.dot(aC, u) """ QUESTION: paper: for l <-1 to L-1 in python: range(0, L) ? or range(0, L-1) alg python 1 0 2 1 3 2 … … L-1 L-2 L L-1 range(0, L) = 0, 1, 2 … L-1 L=4: 0,1,2,3 range(0, L-1) = 0, 1, 2 … L-1-1 L=4: 0,1,2 """ for l in range(0, L-1): # 1 -> L-1 v = aC[l] aC[l] = np.floor( aC[l] ) d += (aC[l] - v) * u[l] # calculate condition term x = (2*aC[l]) - 2*d*u[l] + 1 - u[l]**2 if x<0: aC[l] += 1 d += u[l] # print "l={}, aC={}, x<0={}".format(l, aC, x<0) f = fun.norm2(aC) - np.power(d, 2) # print "\tR={0}, Rmax={1}, Rref={2}".format(comp_rate(f), comp_rate(fmin), fun.comp_rate(h_abs_sorted, aC, P)) # print "\tk={}, fmin={}, f={}, aQ={}".format(k, fmin, f, aQ) if f<fmin: # the less fmin, the bigger compRate aQ = np.copy(aC) fmin = f # recover coefficient vector for l in range(0,L): sign = t[p[l]] a[p[l]] = sign * aQ[l] compRate = comp_rate(fmin) # computation rate # print "R={1:.4}, a={0}".format(a, compRate) return (compRate, a)
def calc_fmin(aQ, u): aQ_norm2 = fun.norm2(aQ) dotprod = np.dot(aQ, u) return aQ_norm2 - np.power(dotprod, 2)