ある条件を満たすリストと定数を求めたい
s = [s1, s2, s3]
t = [t1, t2, t3]
が与えられた時、 以下の条件を満たす p = [p1, p2, p3] と h を求めたいです。
(条件)
・ pk = max{ tk(sk - h), 0 } k = 1,2,3
・ h は p1 + p2 + p3 = 1 を満たす為の定数
この条件下で出来るだけ p を 0 にしないようなコードを書きたいと考えております。
(0 を許可するコードなら既に書けております)
どういったコードが考えられますでしょうか。
考え方でもご教授頂けると幸いです。
よろしくお願い申し上げます。
返信が遅れまして大変申し訳ございません。
またご回答くださり誠に有難うございます。
以下、コードです。
python
1def calculate_send_power(bits, A, r0, a, b): 2 num_stream = len(bits) 3 over = 0 4 under = 0 5 for k in range(num_stream): 6 rk = A[k] * r0 7 ak = a[bits[k]] 8 bk = b[bits[k]] 9 mk = bits[k] 10 11 over += bk/rk * math.log(ak * mk * rk / bk) 12 under += bk/rk 13 14 xi = (over - 1) / under 15 p = [] 16 17 for k in range(num_stream): 18 rk = A[k] * r0 19 ak = a[bits[k]] 20 bk = b[bits[k]] 21 mk = bits[k] 22 23 if bk/rk * (math.log(ak * mk * rk / bk) - xi) > 0: 24 p.append(bk/rk * (math.log(ak * mk * rk / bk) - xi)) 25 26 if len(p) != num_stream: 27 p = calculate_send_power(bits[:-1], A, r0, a, b) 28 29 return p 30 31if __name__ == '__main__': 32 for bits in bit_pattern: 33 num_stream = len(bits) 34 p = calculate_send_power(bits, A, r0, a, b) 35 36 if len(p) != num_stream: 37 for i in range(num_stream - len(p)): 38 p.append(0)
かなり分かりにくいかと思いますが、 calculate_send_power() における over が s を表し、under が t を表し、 xi が h を表しているとお考えください。
以下にそれぞれの変数を述べておきます。
a = [0,0,1/2,0,3/8,0,7/24,0,15/64] b = [0,0,2,0,10,0,42,0,170] bit_pattern = [[8], [6, 2], [4, 4], [4, 2, 2], [2, 2, 2, 2]] H = (4,4)の複素行列 実部、虚部ともに正規分布に従う乱数 gram_H = np.conjugate(H.T) @ H U, A, Uh = svd(gram_H) SNR = 0 Ps = 1.0 sigma = math.sqrt( Ps / (2 * math.pow(10.0, SNR/10))) Pn = 2*sigma*sigma r0 = Ps/Pn
このコードは bit_pattern = [[8], [6, 2], [4, 4], [4, 2, 2], [2, 2, 2, 2]] のそれぞれに割り当てる電力(電力総和 = 1)を決定するもので以下のようになります。
bits | p(ower) | sum |
---|---|---|
[8] | [1.000] | 1.0 |
[6, 2] | [0.453, 0.546] | 1.0 |
以下に実行結果を述べます。
for bits in bit_pattern: num_stream = len(bits) tmp = 0 p = calculate_send_power(bits, A, r0, a, b) if len(p) != num_stream: for i in range(num_stream - len(p)): p.append(0) print("bits = {} , power = {}, sum = {}".format(bits, p, sum(p))) >>> bits = [8] , power = [1.00], sum = 1.0 bits = [6, 2] , power = [0.39036578941718647, 0.6096342105828132], sum = 1.0 bits = [4, 4] , power = [0.6905457297074978, 0.30945427029250216], sum = 1.0 bits = [4, 2, 2] , power = [0.4747411414947003, 0.35540013052184316, 0.1698587279834565], sum = 1.0 bits = [2, 2, 2, 2] , power = [0.3157712110211322, 0.40062777763337526, 0.2836010113454926, 0], sum = 1.0
と出来ているのですが、 bits = [2, 2, 2, 2] の4項目に割り当てる電力が 0 になってしまいます。この条件下で出来るだけ p を 0 にしないようなコードを書きたいと考えており、考え方でもご教授頂けると幸いです。よろしくお願い申し上げます。