├── cellsys ├── __init__.py ├── __pycache__ │ ├── draw.cpython-35.pyc │ ├── geom.cpython-35.pyc │ ├── __init__.cpython-35.pyc │ └── window.cpython-35.pyc ├── window.py ├── geom.py └── draw.py ├── __pycache__ ├── core.cpython-35.pyc ├── allocate.cpython-35.pyc └── channel.cpython-35.pyc ├── README ├── config.json ├── ratebarplot.py ├── allocate.py ├── nd2d.py ├── hexagon.py ├── range.py ├── channel.py └── core.py /cellsys/__init__.py: -------------------------------------------------------------------------------- 1 | from .draw import * 2 | from .geom import * 3 | from .window import * 4 | -------------------------------------------------------------------------------- /__pycache__/core.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shyamal-dhua/D2D/HEAD/__pycache__/core.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/allocate.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shyamal-dhua/D2D/HEAD/__pycache__/allocate.cpython-35.pyc -------------------------------------------------------------------------------- /__pycache__/channel.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shyamal-dhua/D2D/HEAD/__pycache__/channel.cpython-35.pyc -------------------------------------------------------------------------------- /cellsys/__pycache__/draw.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shyamal-dhua/D2D/HEAD/cellsys/__pycache__/draw.cpython-35.pyc -------------------------------------------------------------------------------- /cellsys/__pycache__/geom.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shyamal-dhua/D2D/HEAD/cellsys/__pycache__/geom.cpython-35.pyc -------------------------------------------------------------------------------- /cellsys/__pycache__/__init__.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shyamal-dhua/D2D/HEAD/cellsys/__pycache__/__init__.cpython-35.pyc -------------------------------------------------------------------------------- /cellsys/__pycache__/window.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shyamal-dhua/D2D/HEAD/cellsys/__pycache__/window.cpython-35.pyc -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Basically just D2D communication stuff ! 2 | 3 | EE764 Wireless & Mobile Communication Project 2018 4 | 5 | Pratik, Ritesh & Shyamal 6 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "Rc" : 500, 3 | "ntiers" : 0, 4 | "Pc" : 0.25, 5 | "bw" : 160e3, 6 | "N_dBm" : -174, 7 | "tSNR_dB" : 7.7, 8 | "Nc" : 20, 9 | "Nd" : 20, 10 | "Nrb" : 25, 11 | "RWindowSize" : 50, 12 | "d2dDistance" : 30, 13 | "rbPerD2DPair" : 1 14 | } 15 | -------------------------------------------------------------------------------- /cellsys/window.py: -------------------------------------------------------------------------------- 1 | # 2 | # EE 764 3 | # Wireless & Mobile Communication 4 | # Simulation Assignment 1 5 | # 6 | # Hexagonal geometry functions 7 | # 8 | # Author: Ritesh 9 | # RollNo: 163079001 10 | # 11 | # # # # # # # # # # # # # # # # # # # # # 12 | 13 | import numpy as np 14 | import math 15 | import random 16 | 17 | class meanwindow(object): 18 | def __init__(self, values, wSize): 19 | self.values = [[values[i] for x in range(wSize)] for i in range(len(values))] 20 | 21 | # Checks if point p(i, j) is a reuse cell or not 22 | # for reuse factor 3 23 | def update(self, newValues): 24 | [x.pop(0) for x in self.values] 25 | [x.append(newValue) for x,newValue in zip(self.values, newValues)] 26 | return [np.mean(x) for x in self.values] 27 | def get(self): 28 | return [np.mean(x) for x in self.values] 29 | -------------------------------------------------------------------------------- /ratebarplot.py: -------------------------------------------------------------------------------- 1 | # 2 | # EE 764 3 | # Wireless & Mobile Communication 4 | # Course Project 5 | # 6 | # Initial Cell Allocation Diagram 7 | # 8 | # Authors: Pratik, Ritesh, Shyamal 9 | # 10 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 11 | # created by us 12 | import cellsys as cs 13 | import core 14 | 15 | import numpy as np 16 | import pylab as pl 17 | import sys 18 | import json 19 | 20 | with open('config.json', 'r') as f: 21 | config = json.load(f) 22 | 23 | # radius of hexagon 24 | Rc = config["Rc"] 25 | ntiers = config["ntiers"] 26 | 27 | # Tx power from CU 28 | Pc = config["Pc"] 29 | 30 | # Bandwidth (180 khz without guard band) 31 | bw = config["bw"] 32 | 33 | # Noise PSD in dBm 34 | N_dBm = config["N_dBm"] 35 | N0 = (10**(N_dBm / 10)) * 10**(-3) 36 | N0 = N0 * bw 37 | 38 | # Target SNR at BS from CU (dB) 39 | tSNR_dB = config["tSNR_dB"] 40 | tSNR = 10**(tSNR_dB / 10) 41 | 42 | # no. of cell users 43 | Nc = config["Nc"] 44 | 45 | # no of D2D pairs 46 | Nd = config["Nd"] 47 | 48 | # no. of resource blocks 49 | Nrb = config["Nrb"] 50 | 51 | # max window 52 | RWindowSize = config["RWindowSize"] 53 | 54 | # D2D distance 55 | d2dDistance = config["d2dDistance"] 56 | 57 | # Rb per D2D pair 58 | rbPerD2DPair = config["rbPerD2DPair"] 59 | 60 | brush = cs.draw(0.1) 61 | g = cs.geom(Rc) 62 | 63 | cellUsers = [g.getRandomPointInHex() for i in range(Nc)] 64 | 65 | 66 | throughputCell, throughPutD2d = core.core(Rc, Pc, bw, N0, tSNR, cellUsers, 67 | Nc, Nd, Nrb, d2dDistance, 68 | rbPerD2DPair, RWindowSize, 400, True) 69 | 70 | pl.show() 71 | -------------------------------------------------------------------------------- /allocate.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import sys 3 | from munkres import Munkres, make_cost_matrix, print_matrix 4 | import channel 5 | 6 | def cellAllocate(Nc, Nrb, Pc, bw, N0, msCh, preAv): 7 | assignment = [[] for x in range(Nc)] 8 | assignmentRB = [-1 for x in range(Nrb)] 9 | assigned = [] 10 | currentRates = np.asarray([0 for x in range(Nc)]) 11 | currentRatesRB = [] 12 | 13 | lambdas = [] 14 | rates = [] 15 | for ms,R in zip(msCh, preAv): 16 | rates.append(channel.chGainsToRates(ms, Pc, bw, N0)) 17 | lambdas.append(channel.chGainsToRates(ms, Pc, bw, N0) / R) 18 | lambdast = lambdas 19 | lambdas = np.transpose(lambdas) 20 | 21 | # for each RB that is 22 | for i in range(len(lambdas)): 23 | sortedLambdas = np.argsort(lambdas[i]) 24 | toAssign = len(sortedLambdas) - 1 25 | while(sortedLambdas[toAssign] in assigned): 26 | toAssign -= 1 27 | if(len(assignment[sortedLambdas[toAssign]]) == 0): 28 | if(i > 0): 29 | assigned.append(assignmentRB[i - 1]) 30 | assignment[sortedLambdas[toAssign]].append(i) 31 | assignmentRB[i] = sortedLambdas[toAssign] 32 | currentRatesRB.append(rates[sortedLambdas[toAssign]][i]) 33 | for i in range(Nc): 34 | for y in assignment[i]: 35 | currentRates[i] += rates[i][y] 36 | if(len(assignment[i]) == 0): 37 | currentRates[i] = 1 38 | gcBs = [msCh[assignmentRB[i]][i] for i in range(len(assignmentRB))] 39 | return assignment, assignmentRB, gcBs, currentRates, currentRatesRB 40 | 41 | def d2dAllocate(lambda_matrix,maximum_rb_allowed): 42 | #if multiple resource blocks are allowed for d2d users then repeat the rows 43 | if(not(maximum_rb_allowed==1)): 44 | lambda_matrix_new = [] 45 | for i in range(0,len(lambda_matrix)): 46 | for j in range(0,maximum_rb_allowed): 47 | lambda_matrix_new.append(lambda_matrix[i]) 48 | lambda_matrix = lambda_matrix_new 49 | 50 | #convert profit matrix to cost matrix 51 | cost_matrix = make_cost_matrix(lambda_matrix, lambda cost: sys.maxsize - cost) 52 | 53 | m = Munkres() 54 | indexes = m.compute(cost_matrix) #indexes contains the 2d indexes of the maximum weight allocations 55 | 56 | allocated_d2d_in_channels = np.zeros(len(lambda_matrix[0]))-1 57 | 58 | d2d_and_indexes = [] #indexes to return 59 | 60 | for row, column in indexes: 61 | allocated_d2d_in_channels[column] = int(row/maximum_rb_allowed) 62 | 63 | allocated_d2d_in_channels = allocated_d2d_in_channels.astype(int) 64 | 65 | for i in range(0,len(allocated_d2d_in_channels)): 66 | if(not(allocated_d2d_in_channels[i]==-1)): 67 | d2d_and_indexes.append([allocated_d2d_in_channels[i],[allocated_d2d_in_channels[i],i]]) 68 | 69 | return d2d_and_indexes 70 | -------------------------------------------------------------------------------- /nd2d.py: -------------------------------------------------------------------------------- 1 | # 2 | # EE 764 3 | # Wireless & Mobile Communication 4 | # Course Project 5 | # 6 | # Variation of Throughput With No. of D2D Users 7 | # 8 | # Authors: Pratik, Ritesh, Shyamal 9 | # 10 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 11 | # created by us 12 | import cellsys as cs 13 | import core 14 | 15 | import numpy as np 16 | import pylab as pl 17 | import sys 18 | import json 19 | 20 | with open('config.json', 'r') as f: 21 | config = json.load(f) 22 | 23 | # radius of hexagon 24 | Rc = config["Rc"] 25 | ntiers = config["ntiers"] 26 | 27 | # Tx power from CU 28 | Pc = config["Pc"] 29 | 30 | # Bandwidth (180 khz without guard band) 31 | bw = config["bw"] 32 | 33 | # Noise PSD in dBm 34 | N_dBm = config["N_dBm"] 35 | N0 = (10**(N_dBm / 10)) * 10**(-3) 36 | N0 = N0 * bw 37 | 38 | # Target SNR at BS from CU (dB) 39 | tSNR_dB = config["tSNR_dB"] 40 | tSNR = 10**(tSNR_dB / 10) 41 | 42 | # no. of cell users 43 | Nc = config["Nc"] 44 | 45 | # no of D2D pairs 46 | Nd = config["Nd"] 47 | 48 | # no. of resource blocks 49 | Nrb = config["Nrb"] 50 | 51 | # max window 52 | RWindowSize = config["RWindowSize"] 53 | 54 | # D2D distance 55 | d2dDistance = config["d2dDistance"] 56 | 57 | # Rb per D2D pair 58 | rbPerD2DPair = config["rbPerD2DPair"] 59 | 60 | brush = cs.draw(0.1) 61 | g = cs.geom(Rc) 62 | 63 | cellUsers = [g.getRandomPointInHex() for i in range(Nc)] 64 | 65 | Ndmin = 4 66 | Ndmax = 22 67 | step = 2 68 | Ndvariation = range(Ndmin, Ndmax, step) 69 | 70 | rateVariationCell = [] 71 | rateVariationD2d = [] 72 | rateVariationBoth = [] 73 | print("\n Variation of Throughput With No. of D2D Users\n") 74 | for Nd in Ndvariation: 75 | sys.stdout.write("\r") 76 | progress = int(100 * ((Nd - Ndmin) / (Ndmax - Ndmin - step))) 77 | percent = "{:2}".format(progress) 78 | sys.stdout.write(" " + percent + " % ") 79 | [sys.stdout.write("##") for x in range(int(Nd / step))] 80 | sys.stdout.flush() 81 | throughputCell, throughPutD2d = core.core(Rc, Pc, bw, N0, tSNR, cellUsers, 82 | Nc, Nd, Nrb, d2dDistance, 83 | rbPerD2DPair, RWindowSize, 400, False) 84 | rateVariationCell.append(throughputCell) 85 | rateVariationD2d.append(throughPutD2d) 86 | rateVariationBoth.append(throughputCell + throughPutD2d) 87 | print("") 88 | pl.figure(2) 89 | pl.plot(Ndvariation, np.asarray(rateVariationCell) / 1e6, label="Cell Users") 90 | pl.scatter(Ndvariation, np.asarray(rateVariationCell) / 1e6, marker=">") 91 | pl.plot(Ndvariation, np.asarray(rateVariationD2d) / 1e6, label="D2D Pairs") 92 | pl.scatter(Ndvariation, np.asarray(rateVariationD2d) / 1e6, marker=">") 93 | pl.plot(Ndvariation, np.asarray(rateVariationBoth) / 1e6, label="Both") 94 | pl.scatter(Ndvariation, np.asarray(rateVariationBoth) / 1e6, marker=">") 95 | pl.xlabel("No. of D2D Pairs") 96 | pl.ylabel("Throughput (Mbits/sec)") 97 | pl.legend(loc="upper left") 98 | pl.grid(True) 99 | pl.show() 100 | -------------------------------------------------------------------------------- /hexagon.py: -------------------------------------------------------------------------------- 1 | # 2 | # EE 764 3 | # Wireless & Mobile Communication 4 | # Course Project 5 | # 6 | # Plot of a Hexagonal Cell With Users 7 | # 8 | # Authors: Pratik, Ritesh, Shyamal 9 | # 10 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 11 | # created by us 12 | import cellsys as cs 13 | import core 14 | 15 | import numpy as np 16 | import pylab as pl 17 | import sys 18 | import json 19 | 20 | with open('config.json', 'r') as f: 21 | config = json.load(f) 22 | 23 | # radius of hexagon 24 | Rc = config["Rc"] 25 | ntiers = config["ntiers"] 26 | 27 | # Tx power from CU 28 | Pc = config["Pc"] 29 | 30 | # Bandwidth (180 khz without guard band) 31 | bw = config["bw"] 32 | 33 | # Noise PSD in dBm 34 | N_dBm = config["N_dBm"] 35 | N0 = (10**(N_dBm / 10)) * 10**(-3) 36 | N0 = N0 * bw 37 | 38 | # Target SNR at BS from CU (dB) 39 | tSNR_dB = config["tSNR_dB"] 40 | tSNR = 10**(tSNR_dB / 10) 41 | 42 | # no. of cell users 43 | Nc = config["Nc"] 44 | 45 | # no of D2D pairs 46 | Nd = config["Nd"] 47 | 48 | # no. of resource blocks 49 | Nrb = config["Nrb"] 50 | 51 | # max window 52 | RWindowSize = config["RWindowSize"] 53 | 54 | # D2D distance 55 | d2dDistance = config["d2dDistance"] 56 | 57 | # Rb per D2D pair 58 | rbPerD2DPair = config["rbPerD2DPair"] 59 | 60 | brush = cs.draw(Rc) 61 | g = cs.geom(Rc) 62 | 63 | cellUsers = [g.getRandomPointInHex() for i in range(Nc)] 64 | 65 | fig1 = pl.figure(1) 66 | pl.scatter(0, 0, color="#777777", zorder=1000, s=24, facecolors='#DDDDDD', label="eNB (Base Station)") 67 | for i in range(len(cellUsers) - 1): 68 | pl.scatter(cellUsers[i][0], cellUsers[i][1], color="#32DB36", zorder=1000, s=6) 69 | pl.scatter(cellUsers[len(cellUsers) - 1][0], cellUsers[len(cellUsers) - 1][1], 70 | color="#32DB36", zorder=1000, s=6, label="Cell Users") 71 | 72 | d2d_tx = [] 73 | d2d_rx = [] 74 | plotted = 0 75 | for i in range(0, Nd): 76 | t,r = g.getD2DInHex(d2dDistance) 77 | d2d_tx.append(t) 78 | d2d_rx.append(r) 79 | 80 | if(plotted == 0): 81 | pl.scatter(t[0], t[1], color="#DB3236", zorder=1000, s=8, label="D2D Transmitter") 82 | pl.scatter(r[0], r[1], color="#2E58D5", zorder=1000, s=8, label="D2D Receiver") 83 | line = g.lineFromPoints(t, r, 100) 84 | xx, yy = zip(*line) 85 | pl.plot(xx, yy, color="#888888", zorder = 999, linewidth=1) 86 | plotted = 1 87 | else: 88 | pl.scatter(t[0], t[1], color="#DB3236", zorder=1000, s=8) 89 | pl.scatter(r[0], r[1], color="#2E58D5", zorder=1000, s=8) 90 | line = g.lineFromPoints(t, r, 100) 91 | xx, yy = zip(*line) 92 | pl.plot(xx, yy, color="#888888", zorder = 999, linewidth=1) 93 | 94 | brush.drawHex(0, 0, fig1, "#EEEEEE") 95 | #brush.drawTiers(0, (0, 0), fig1, "#EEEEEE") 96 | ax = fig1.gca() 97 | ax.set_xlim(-Rc, Rc) 98 | ax.set_ylim(-Rc, Rc) 99 | ax.set_aspect('equal') 100 | 101 | pl.xlabel("distance (m)") 102 | pl.ylabel("distance (m)") 103 | pl.legend(loc="upper right") 104 | 105 | pl.show() 106 | -------------------------------------------------------------------------------- /range.py: -------------------------------------------------------------------------------- 1 | # 2 | # EE 764 3 | # Wireless & Mobile Communication 4 | # Course Project 5 | # 6 | # Variation of Throughput With Distance Between D2D Users 7 | # 8 | # Authors: Pratik, Ritesh, Shyamal 9 | # 10 | # # # # # # # # # # # # # # # # # # # # # # # # # # # # # 11 | # created by us 12 | import cellsys as cs 13 | import core 14 | 15 | import numpy as np 16 | import pylab as pl 17 | import sys 18 | import json 19 | 20 | with open('config.json', 'r') as f: 21 | config = json.load(f) 22 | 23 | # radius of hexagon 24 | Rc = config["Rc"] 25 | ntiers = config["ntiers"] 26 | 27 | # Tx power from CU 28 | Pc = config["Pc"] 29 | 30 | # Bandwidth (180 khz without guard band) 31 | bw = config["bw"] 32 | 33 | # Noise PSD in dBm 34 | N_dBm = config["N_dBm"] 35 | N0 = (10**(N_dBm / 10)) * 10**(-3) 36 | N0 = N0 * bw 37 | 38 | # Target SNR at BS from CU (dB) 39 | tSNR_dB = config["tSNR_dB"] 40 | tSNR = 10**(tSNR_dB / 10) 41 | 42 | # no. of cell users 43 | Nc = config["Nc"] 44 | 45 | # no of D2D pairs 46 | Nd = config["Nd"] 47 | 48 | # no. of resource blocks 49 | Nrb = config["Nrb"] 50 | 51 | # max window 52 | RWindowSize = config["RWindowSize"] 53 | 54 | # D2D distance 55 | d2dDistance = config["d2dDistance"] 56 | 57 | # Rb per D2D pair 58 | rbPerD2DPair = config["rbPerD2DPair"] 59 | 60 | brush = cs.draw(0.1) 61 | g = cs.geom(Rc) 62 | 63 | cellUsers = [g.getRandomPointInHex() for i in range(Nc)] 64 | 65 | dmin = 20 66 | dmax = 110 67 | step = 10 68 | distanceVariation = range(20, 110, 10) 69 | 70 | rateVariationCell = [] 71 | rateVariationD2d = [] 72 | rateVariationBoth = [] 73 | print("\n Variation of Throughput With Distance Between D2D Users\n") 74 | for d2dDistance in distanceVariation: 75 | sys.stdout.write("\r") 76 | progress = int(100 * ((d2dDistance - dmin) / (dmax - dmin - step))) 77 | percent = "{:2}".format(progress) 78 | sys.stdout.write(" " + percent + " % ") 79 | [sys.stdout.write("##") for x in range(int(d2dDistance / step))] 80 | sys.stdout.flush() 81 | throughputCell, throughPutD2d = core.core(Rc, Pc, bw, N0, tSNR, cellUsers, 82 | Nc, Nd, Nrb, d2dDistance, 83 | rbPerD2DPair, RWindowSize, 200, False) 84 | rateVariationCell.append(throughputCell) 85 | rateVariationD2d.append(throughPutD2d) 86 | rateVariationBoth.append(throughputCell + throughPutD2d) 87 | print("") 88 | pl.figure(2) 89 | pl.plot(distanceVariation, np.asarray(rateVariationCell) / 1e6, label="Cell Users") 90 | pl.scatter(distanceVariation, np.asarray(rateVariationCell) / 1e6, marker=">") 91 | pl.plot(distanceVariation, np.asarray(rateVariationD2d) / 1e6, label="D2D Pairs") 92 | pl.scatter(distanceVariation, np.asarray(rateVariationD2d) / 1e6, marker=">") 93 | pl.plot(distanceVariation, np.asarray(rateVariationBoth) / 1e6, label="Both") 94 | pl.scatter(distanceVariation, np.asarray(rateVariationBoth) / 1e6, marker=">") 95 | pl.xlabel("Distance between D2D Users in a Pair (m)") 96 | pl.ylabel("Throughput (Mbits/sec)") 97 | pl.legend(loc="upper left") 98 | pl.grid(True) 99 | pl.show() 100 | -------------------------------------------------------------------------------- /channel.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import random 3 | 4 | # contact Shyamal 5 | def getGcbMatrix(Nc, ms, number_of_channels): 6 | g1 = np.random.rayleigh(1, [Nc, number_of_channels]) 7 | g_CB = np.zeros([Nc, number_of_channels]) 8 | d_CB = [] # Distance of CU from Base station 9 | for i in range(0, Nc): 10 | a = ms[i] 11 | d_CB.append(np.sqrt(a[0]**2 + a[1]**2) / 1000) 12 | pL_1 = 128.1 + 37.6 * np.log10(d_CB) # Path loss in dB 13 | pl_1 = 10**(pL_1 / 10) # Path loss in linear scale 14 | for i in range(Nc): 15 | g_CB[i] = (g1[i]**2) / pl_1[i] 16 | return g_CB 17 | 18 | # contact Ritesh 19 | def chGainsToRates(gains, Pc, bw, sigmaNsq): 20 | rates = [] 21 | for gain in gains: 22 | snr = (Pc * gain) / sigmaNsq 23 | rate = bw * np.log2(1 + snr) 24 | rates.append(rate) 25 | return rates 26 | 27 | # contact Shyamal 28 | def chGains(Nd, number_of_channels, cellUsers, allocated_cell_users, d2d_tx, d2d_rx, Pc, d_dTdR): 29 | P=Pc # tx power from CU 30 | d_dTB=[] # distance of D2D Transmitter from Base station (1xNd) 31 | #d_dTdR=0.01 # distance between D2D Tx and D2D Rx 32 | d_CdR=[] # distance between cell user and d2d receiver 33 | 34 | g_d2b = np.random.rayleigh(1,[Nd,number_of_channels]) # D2D Tx to BS rayleigh fading 35 | g_dTB = np.zeros([Nd,number_of_channels]) 36 | 37 | g_d2dR = np.random.rayleigh(1,[1,number_of_channels]) # D2D Tx and D2D Rx rayleigh fading 38 | g_dTdR = np.zeros([1,number_of_channels]) 39 | 40 | g_cdR = np.random.rayleigh(1,[Nd,number_of_channels]) # cell user to d2d receiver rayleigh fading 41 | g_CdR = np.zeros([Nd,number_of_channels]) 42 | 43 | for i in range(0,len(d2d_tx)): 44 | distance = np.sqrt((d2d_tx[i][0]**2) + (d2d_tx[i][1]**2)) 45 | distance = distance / 1000 46 | d_dTB.append(distance) 47 | 48 | for i in range(0,len(d2d_rx)): 49 | dist = [] 50 | for j in range(0,len(allocated_cell_users)): 51 | cell_x = cellUsers[allocated_cell_users[j]][0] 52 | cell_y = cellUsers[allocated_cell_users[j]][1] 53 | d2d_x = d2d_rx[i][0] 54 | d2d_y = d2d_rx[i][1] 55 | distance =np.sqrt(((cell_x-d2d_x)**2) + ((cell_y-d2d_y)**2)) 56 | distance=distance/1000 57 | dist.append(distance) 58 | d_CdR.append(dist) 59 | 60 | pL_dTB = 128.1 + 37.6*np.log10(d_dTB) # d_dTB=distance in kms 61 | pL_dTdR = 128.1 + 37.6*np.log10(d_dTdR / 1000) 62 | 63 | pL_CdR = np.zeros([Nd,number_of_channels]) 64 | pl_CdR = np.zeros([Nd,number_of_channels]) 65 | for i in range(0,Nd): 66 | pL_CdR[i] = 128.1 + 37.6*np.log10(d_CdR[i]) 67 | for i in range(0,Nd): 68 | pl_CdR[i] = 10**(pL_CdR[i]/10) 69 | 70 | 71 | pl_dTB = 10**(pL_dTB/10) # Path loss in linear scale (1xNd) 72 | pl_dTdR = 10**(pL_dTdR/10) #(1x1 -> scalar) 73 | 74 | for i in range(0,Nd): 75 | g_dTB[i] = (g_d2b[i]**2)/(pl_dTB[i]) # Channel Gains : from D2D Tx to BS (Ndxnumber_of_channels) 76 | 77 | g_dTdR = ((g_d2dR**2)/pl_dTdR) # Channel Gains : from D2D Tx to D2D Rx (1xnumber_of_channels) 78 | 79 | for i in range(0,Nd): 80 | g_CdR[i] = (g_cdR[i]**2)/(pl_CdR[i]) # Channel Gains : from CU to D2D Rx (Ndxnumber_of_channels) 81 | 82 | g_dTB_list = [] 83 | g_dTdR_list = g_dTdR.tolist() 84 | g_CdR_list = [] 85 | 86 | for i in range(0,Nd): 87 | g_dTB_list.append(list(g_dTB[i])) 88 | g_CdR_list.append(list(g_CdR[i])) 89 | 90 | return np.asarray(g_dTB_list),np.asarray(g_dTdR_list[0]),np.asarray(g_CdR_list) 91 | -------------------------------------------------------------------------------- /core.py: -------------------------------------------------------------------------------- 1 | import cellsys as cs 2 | import allocate 3 | import channel 4 | 5 | import numpy as np 6 | import pylab as pl 7 | 8 | def valid(a): 9 | for i in range(0,len(a)): 10 | if(a[i] > 0.25): 11 | a[i] = 0.25 12 | elif(a[i] < 0): 13 | a[i] = 0 14 | return a 15 | 16 | def core(Rc, Pc, bw, N0, tSNR, cellUsers, Nc, Nd, Nrb, d2dDistance, rbPerD2DPair, RWindowSize, simTime, barplot): 17 | g = cs.geom(Rc) 18 | d2d_tx = [] 19 | d2d_rx = [] 20 | for i in range(0, Nd): 21 | t,r = g.getD2DInHex(d2dDistance) 22 | d2d_tx.append(t) 23 | d2d_rx.append(r) 24 | 25 | totalTime = simTime 26 | 27 | cellR = [1 for x in range(Nc)] 28 | d2dR = [1 for x in range(Nd)] 29 | 30 | cellRwindow = cs.meanwindow(cellR, RWindowSize) 31 | d2dRwindow = cs.meanwindow(d2dR, RWindowSize) 32 | 33 | tempRateCell = [] 34 | tempRateD2d = [] 35 | 36 | for i in range(totalTime): 37 | gcB = channel.getGcbMatrix(Nc, cellUsers, Nrb) 38 | allocC, allocRB, gcBs, rates, ratesRB = allocate.cellAllocate(Nc, Nrb, Pc, bw, N0, gcB, cellRwindow.get()) 39 | Rcell = cellRwindow.update(rates) 40 | 41 | tempRateCell.append(np.sum(rates)) 42 | 43 | rates = [] 44 | g_dTB, g_dTdR, g_CdR = channel.chGains(Nd, Nrb, cellUsers, allocRB, d2d_tx, d2d_rx, Pc, d2dDistance) 45 | g_CB = np.asarray(gcBs) 46 | for d in range(Nd): 47 | P_dT = (((Pc * g_CB) / (tSNR * g_dTB[d])) - (N0 / g_dTB[d])) 48 | # Power of D2D transmitter for all RBs (checking for all RB occupied by cell users) 49 | P_dT = valid(P_dT) 50 | #print(" A. Power that can be sent by d2d Txs", d, ": ", P_dT) 51 | r = (1 + ((P_dT * g_dTdR) / (N0 + (Pc * g_CdR[d])))) 52 | r_d2d = bw * np.log2(r) 53 | r_d2dN = r_d2d 54 | # Rate achievable by D2D for all K s. 55 | #print(" B. Rate achievable by D2D",d,": ", r_d2d) 56 | #print("\n") 57 | rates.append(list(r_d2d)) 58 | lambdas = [] 59 | for ratelist, Rd2d in zip(rates, d2dRwindow.get()): 60 | lambdas.append(ratelist / Rd2d) 61 | alloc = allocate.d2dAllocate(lambdas, rbPerD2DPair) 62 | d2dRates = [rates[x[1][0]][x[1][1]] for x in alloc] 63 | 64 | d2dRatesRB = [0 for x in range(Nrb)] 65 | for j in range(Nrb): 66 | for x in alloc: 67 | if(x[1][1] == j): 68 | d2dRatesRB[j] = rates[x[1][0]][x[1][1]] 69 | 70 | if(barplot): 71 | if(i == 150): 72 | ind = np.arange(Nrb) # the x locations for the groups 73 | width = 0.35 # the width of the bars: can also be len(x) sequence 74 | barfig = pl.figure(1) 75 | pl.grid(True, color="#DDDDDD") 76 | ax = barfig.gca() 77 | ax.set_axisbelow(True) 78 | p1 = pl.bar(ind, np.asarray(ratesRB) / 1e6, width) 79 | p2 = pl.bar(ind, np.asarray(d2dRatesRB) / 1e6, width, bottom = np.asarray(ratesRB) / 1e6) 80 | #pl.title('Rate Allocation in One LTE frame') 81 | pl.xlabel("Resource Blocks") 82 | pl.ylabel("Rate (Mbits/s)") 83 | pl.xticks(ind, [(x + 1) for x in range(Nrb)]) 84 | pl.yticks(np.arange(0, 8, 1)) 85 | pl.legend((p1[0], p2[0]), ('Cellular User', 'D2D Pair')) 86 | 87 | brush = cs.draw(np.sqrt(2) / 10) 88 | figAlloc = pl.figure(2) 89 | pl.xlabel("Resource Blocks -->") 90 | pl.ylabel("Cell Users -->") 91 | ax = figAlloc.gca() 92 | ax.set_xlim(0, (Nrb + 1) * 0.22) 93 | ax.set_ylim(0, (Nc + 1) * 0.22) 94 | ax.set_aspect('equal') 95 | ax.set_yticklabels([]) 96 | ax.set_xticklabels([]) 97 | x = 0 98 | y = 0.2 99 | for ms in allocC: 100 | for i in range(Nrb): 101 | x += 0.22 102 | if(i in ms): 103 | brush.drawSquare(x, y, figAlloc, "#009999") 104 | else: 105 | brush.drawSquare(x, y, figAlloc, "#E7E7E7") 106 | x = 0 107 | y += 0.22 108 | pl.show() 109 | break 110 | d2dRwindow.update(d2dRates) 111 | tempRateD2d.append(np.sum(d2dRates)) 112 | return np.mean(tempRateCell), np.mean(tempRateD2d) 113 | -------------------------------------------------------------------------------- /cellsys/geom.py: -------------------------------------------------------------------------------- 1 | # 2 | # EE 764 3 | # Wireless & Mobile Communication 4 | # Simulation Assignment 1 5 | # 6 | # Hexagonal geometry functions 7 | # 8 | # Author: Ritesh 9 | # RollNo: 163079001 10 | # 11 | # # # # # # # # # # # # # # # # # # # # # 12 | 13 | import numpy as np 14 | import math 15 | import random 16 | 17 | def ss(theta): 18 | return np.sin(theta) 19 | def cc(theta): 20 | return np.cos(theta) 21 | 22 | class geom(object): 23 | def __init__(self, radius): 24 | self.radius = radius 25 | self.redge = radius * cc(np.pi / 6) 26 | ta = np.pi / 3 27 | verts = [ ( 1, 0), 28 | ( cc(ta), ss(ta)), 29 | (-cc(ta), ss(ta)), 30 | ( -1, 0), 31 | (-cc(ta), -ss(ta)), 32 | ( cc(ta), -ss(ta)) ] 33 | self.basis = np.asarray([np.asarray(item) for item in verts]) 34 | self.basis *= radius 35 | 36 | # Checks if point p(i, j) is a reuse cell or not 37 | # for reuse factor 3 38 | def check3(self, p): 39 | if((p[1] - p[0]) % 3 == 0): 40 | return 1 41 | else: 42 | return 0 43 | 44 | # It checks if the p(i, j) is a reuse cell or not 45 | # if n is the reuse factor 46 | def checkReuse(self, p, rf): 47 | if(rf == 3): 48 | return self.check3(p) 49 | k = math.floor(math.sqrt((rf - 1) / 3)) 50 | # basis found (k, k + 1) 51 | if(((k * p[1]) - ((k + 1) * p[0])) % rf == 0): 52 | return 1 53 | else: 54 | return 0 55 | 56 | def checkReuseSectored(self, p): 57 | i = p[0] 58 | j = p[1] 59 | ch = (2 * j) + i 60 | if(ch < 0): 61 | j += int(abs(ch)) 62 | if(j % 2 == 0): 63 | if(i > (-1 * int(abs(j) / 2))): 64 | return 0 65 | else: 66 | if(i >= (-1 * int(abs(j) / 2))): 67 | return 0 68 | return 1 69 | 70 | # Gets the list of all reuse cells for the given 71 | # reuse factor 'rf' upto specified no. of tiers 'ntiers' 72 | def reuseCells(self, ntiers, rf): 73 | thelist = [] 74 | p = -1 * ntiers 75 | q = 0 76 | r = ntiers 77 | while(q < ntiers): 78 | for i in range(p, q + 1): 79 | if(self.checkReuse((i, r), rf)): 80 | thelist.append((i, r)) 81 | r -= 1 82 | q += 1 83 | while(p <= 0): 84 | for i in range(p, q + 1): 85 | if(self.checkReuse((i, r), rf)): 86 | thelist.append((i, r)) 87 | r -= 1 88 | p += 1 89 | if(len(thelist) == 1): 90 | return [] 91 | else: 92 | return thelist 93 | 94 | # Gets the list of all reuse cells for the given 95 | # reuse factor 'rf' upto specified no. of tiers 'ntiers' 96 | def reuseCellsSectored(self, ntiers): 97 | thelist = [] 98 | p = -1 * ntiers 99 | q = 0 100 | r = ntiers 101 | while(q < ntiers): 102 | for i in range(p, q + 1): 103 | if(self.checkReuseSectored((i, r))): 104 | thelist.append((i, r)) 105 | r -= 1 106 | q += 1 107 | while(p <= 0): 108 | for i in range(p, q + 1): 109 | if(self.checkReuseSectored((i, r))): 110 | thelist.append((i, r)) 111 | r -= 1 112 | p += 1 113 | return thelist 114 | 115 | def ijtoxy(self, pij): 116 | res = [] 117 | for point in pij: 118 | x = point[0] * np.cos(np.pi / 6) 119 | y = point[1] + (point[0] * np.sin(np.pi / 6)) 120 | res.append((2 * self.redge * x, 2 * self.redge * y)) 121 | return res 122 | 123 | def lineFromPoints(self, p1, p2, res): 124 | p1 = np.asarray(p1) 125 | p2 = np.asarray(p2) 126 | alphas = np.arange(0, 1, 1 / res) 127 | diff = p2 - p1 128 | points = [(p1 + (alpha * diff)) for alpha in alphas] 129 | return points 130 | 131 | def isContainedInHex(self, center, pt): 132 | pts = self.ijtoxy([center]) 133 | x = pts[0][0] 134 | y = pts[0][1] 135 | center = np.asarray([x, y]) 136 | pt = np.asarray(pt) 137 | 138 | vertices = [(center + z) for z in self.basis] 139 | dists = [] 140 | for i in range(0, len(vertices)): 141 | dists.append((np.linalg.norm(pt - vertices[i]), i)) 142 | dists.sort() 143 | vect1 = pt - vertices[dists[0][1]] 144 | vect2 = pt - vertices[dists[1][1]] # not actually required, one is enough 145 | pav = (vertices[dists[0][1]] + vertices[dists[1][1]]) / 2 146 | vectc = pav - center 147 | if(np.dot(vect1, vectc) < 0): 148 | return 1 149 | else: 150 | return 0 151 | 152 | def getRandomPointInHex(self): 153 | precision = 3 154 | pr = np.sqrt(self.radius * self.radius * random.randint(0, 10 ** precision) / float(10 ** precision)) 155 | theta = 2 * np.pi * random.random() 156 | thePoint = (pr * np.cos(theta), pr * np.sin(theta)) 157 | while((pr < 10) or (not self.isContainedInHex((0, 0), thePoint))): 158 | pr = np.sqrt(self.radius * self.radius * random.randint(0, 10 ** precision) / float(10 ** precision)) 159 | theta = 2 * np.pi * random.random() 160 | thePoint = (pr * np.cos(theta), pr * np.sin(theta)) 161 | return thePoint 162 | 163 | def getD2DInHex(self, distanceD2D): 164 | precision = 3 165 | pr = np.sqrt( (self.radius-20) * (self.radius-20) * random.randint(0, 10 ** precision) / float(10 ** precision)) 166 | pr1 = pr - distanceD2D # 10 is d2d distance 167 | theta = 2 * np.pi * random.random() 168 | thePoint = (pr * np.cos(theta), pr * np.sin(theta)) 169 | thePoint1 = (pr1 * np.cos(theta), pr1 * np.sin(theta)) 170 | while((pr < 10) or (not self.isContainedInHex((0, 0), thePoint))): 171 | pr = np.sqrt( (self.radius-20) * (self.radius-20) * random.randint(0, 10 ** precision) / float(10 ** precision)) 172 | pr1 = pr - 10 173 | theta = 2 * np.pi * random.random() 174 | thePoint = (pr * np.cos(theta), pr * np.sin(theta)) 175 | thePoint1 = (pr1 * np.cos(theta), pr1 * np.sin(theta)) 176 | return thePoint,thePoint1 177 | 178 | def getRandomPointInSector(self): 179 | precision = 3 180 | pr = np.sqrt(self.radius * self.radius * random.randint(0, 10 ** precision) / float(10 ** precision)) 181 | theta = (2 * (np.pi / 3) * random.random()) - (np.pi / 3) 182 | thePoint = (pr * np.cos(theta), pr * np.sin(theta)) 183 | while((pr < 10) or (not self.isContainedInHex((0, 0), thePoint))): 184 | pr = np.sqrt(self.radius * self.radius * random.randint(0, 10 ** precision) / float(10 ** precision)) 185 | theta = (2 * (np.pi / 3) * random.random()) - (np.pi / 3) 186 | thePoint = (pr * np.cos(theta), pr * np.sin(theta)) 187 | return thePoint 188 | -------------------------------------------------------------------------------- /cellsys/draw.py: -------------------------------------------------------------------------------- 1 | # 2 | # EE 764 3 | # Wireless & Mobile Communication 4 | # Simulation Assignment 1 5 | # 6 | # Drawing class to draw hexagons and clusters of hexagons 7 | # 8 | # Author: Ritesh 9 | # RollNo: 163079001 10 | # 11 | # # # # # # # # # # # # # # # # # # # # # 12 | 13 | import numpy as np 14 | import pylab as pl 15 | import math 16 | import random 17 | import matplotlib.patches as patches 18 | 19 | from mpl_toolkits.mplot3d import Axes3D 20 | 21 | from .geom import * 22 | 23 | def ss(theta): 24 | return np.sin(theta) 25 | def cc(theta): 26 | return np.cos(theta) 27 | 28 | # for color adjustment 29 | # in hex colors, this function keeps a digit from being less than 0 30 | def keepzero(some): 31 | if(some < 97): 32 | return 97 33 | elif(some < 47): 34 | return 48 35 | else: 36 | return some 37 | 38 | class draw(object): 39 | def __init__(self, radius): 40 | ta = np.pi / 3 41 | verts = [ ( 1, 0), 42 | ( cc(ta), ss(ta)), 43 | (-cc(ta), ss(ta)), 44 | ( -1, 0), 45 | (-cc(ta), -ss(ta)), 46 | ( cc(ta), -ss(ta)) ] 47 | self.radius = radius 48 | self.redge = radius * cc(np.pi / 6) 49 | self.basis = np.asarray([np.asarray(item) for item in verts]) 50 | self.basisdef = self.basis 51 | self.basis *= radius 52 | 53 | def drawHex(self, ci, cj, fig, fclr): 54 | x = ci * np.cos(np.pi / 6) 55 | y = cj + (ci * np.sin(np.pi / 6)) 56 | center = np.asarray([2 * self.redge * x, 2 * self.redge * y]) 57 | vertices = [(center + z) for z in self.basis] 58 | eclr = [chr(keepzero(ord(vl) - 1)) for vl in fclr] 59 | eclr[0] = '#' 60 | axis = fig.gca() 61 | axis.add_patch(patches.RegularPolygon((center[0], center[1]), 6, self.radius, orientation=(np.pi/2), fc=fclr, ec=''.join(eclr))) 62 | 63 | def drawSquare(self, x, y, fig, fclr): 64 | axis = fig.gca() 65 | axis.add_patch(patches.RegularPolygon((x, y), 4, self.radius, orientation=(np.pi/4), fc=fclr)) 66 | 67 | def drawHexSectored(self, ci, cj, fig, fclr): 68 | x = ci * np.cos(np.pi / 6) 69 | y = cj + (ci * np.sin(np.pi / 6)) 70 | center = np.asarray([2 * self.redge * x, 2 * self.redge * y]) 71 | vertices = [(center + z) for z in self.basis] 72 | sverts = [ 73 | [vertices[0], vertices[1], center, vertices[5]], 74 | [vertices[1], vertices[2], vertices[3], center], 75 | [vertices[3], vertices[4], vertices[5], center] 76 | ] 77 | axis = fig.gca() 78 | axis.add_patch(patches.Polygon(np.asarray(vertices), fill=False, ec="#DB3236", zorder=50)) 79 | for i in range(0, 3): 80 | axis.add_patch(patches.Polygon(np.asarray(sverts[i]), fc=fclr[i], ec=fclr[i])) 81 | 82 | def drawTiers(self, ntiers, off, fig, clr): 83 | hexlist = [] 84 | ####### 85 | x = off[0] * cc(np.pi / 6) 86 | y = off[1] + (off[0] * ss(np.pi / 6)) 87 | if(off == (0, 0)): 88 | pl.scatter(2 * self.redge * x, 2 * self.redge * y, s=10, 89 | facecolors='none', color='#FFFFFF', zorder=100) 90 | else: 91 | pl.scatter(2 * self.redge * x, 2 * self.redge * y, s=10, 92 | facecolors='none', color='#00FF00', zorder=100) 93 | ####### 94 | p = -1 * ntiers 95 | q = 0 96 | r = ntiers 97 | while(q < ntiers): 98 | for i in range(p, q + 1): 99 | if((i, r) == (0, 0)): 100 | self.drawHex(i + off[0], r + off[1], fig, '#009999') 101 | else: 102 | hexlist.append((i, r)) 103 | self.drawHex(i + off[0], r + off[1], fig, clr) 104 | r -= 1 105 | q += 1 106 | while(p <= 0): 107 | for i in range(p, q + 1): 108 | if((i, r) == (0, 0)): 109 | self.drawHex(i + off[0], r + off[1], fig, '#009999') 110 | else: 111 | hexlist.append((i, r)) 112 | self.drawHex(i + off[0], r + off[1], fig, clr) 113 | r -= 1 114 | p += 1 115 | return hexlist 116 | 117 | def drawTiersSectored(self, ntiers, off, fig, clr): 118 | ax = fig.gca() 119 | figsz = math.ceil((2 * (ntiers + 1)) * self.redge) 120 | ax.set_xlim(-figsz, figsz) 121 | ax.set_ylim(-figsz, figsz) 122 | ax.set_aspect('equal') 123 | geome = geom(1.0) 124 | # darker colors 125 | dclr = clr[1] 126 | lclr = clr[0] 127 | ####### 128 | x = off[0] * cc(np.pi / 6) 129 | y = off[1] + (off[0] * ss(np.pi / 6)) 130 | pl.scatter(2 * self.redge * x, 2 * self.redge * y, s=2, facecolors='none', color='#00FF00', zorder=100) 131 | ####### 132 | p = -1 * ntiers 133 | q = 0 134 | r = ntiers 135 | while(q < ntiers): 136 | for i in range(p, q + 1): 137 | if(geome.checkReuseSectored((i, r))): 138 | self.drawHexSectored(i + off[0], r + off[1], fig, dclr) 139 | else: 140 | self.drawHexSectored(i + off[0], r + off[1], fig, lclr) 141 | r -= 1 142 | q += 1 143 | while(p <= 0): 144 | for i in range(p, q + 1): 145 | if(geome.checkReuseSectored((i, r))): 146 | self.drawHexSectored(i + off[0], r + off[1], fig, dclr) 147 | else: 148 | self.drawHexSectored(i + off[0], r + off[1], fig, lclr) 149 | r -= 1 150 | p += 1 151 | 152 | def drawTiersSectoredHet(self, ntiers, incells, off, fig, clr): 153 | ax = fig.gca() 154 | figsz = math.ceil((2 * (ntiers + 1)) * self.redge) 155 | ax.set_xlim(-figsz, figsz) 156 | ax.set_ylim(-figsz, figsz) 157 | ax.set_aspect('equal') 158 | geome = geom(1.0) 159 | # darker colors 160 | dclr = clr[1] 161 | lclr = clr[0] 162 | ####### 163 | x = off[0] * cc(np.pi / 6) 164 | y = off[1] + (off[0] * ss(np.pi / 6)) 165 | pl.scatter(2 * self.redge * x, 2 * self.redge * y, s=2, facecolors='none', color='#00FF00', zorder=100) 166 | ####### 167 | p = -1 * ntiers 168 | q = 0 169 | r = ntiers 170 | while(q < ntiers): 171 | for i in range(p, q + 1): 172 | if((i, r) in incells): 173 | if(geome.checkReuseSectored((i, r))): 174 | self.drawHexSectored(i + off[0], r + off[1], fig, dclr) 175 | else: 176 | self.drawHexSectored(i + off[0], r + off[1], fig, lclr) 177 | else: 178 | self.drawHex(i + off[0], r + off[1], fig, "#EEEEEE") 179 | r -= 1 180 | q += 1 181 | while(p <= 0): 182 | for i in range(p, q + 1): 183 | if((i, r) in incells): 184 | if(geome.checkReuseSectored((i, r))): 185 | self.drawHexSectored(i + off[0], r + off[1], fig, dclr) 186 | else: 187 | self.drawHexSectored(i + off[0], r + off[1], fig, lclr) 188 | else: 189 | self.drawHex(i + off[0], r + off[1], fig, "#EEEEEE") 190 | r -= 1 191 | p += 1 192 | 193 | def drawLayout(self, ntiers, freuse, cells, fig): 194 | ax = fig.gca() 195 | figsz = math.ceil((2 * (ntiers + 1) + 1) * self.redge) 196 | ax.set_xlim(-figsz, figsz) 197 | ax.set_ylim(-figsz, figsz) 198 | ax.set_aspect('equal') 199 | ntiersToPlot = int(np.floor(np.sqrt((freuse - 1) / 3))) 200 | if(freuse == 3): 201 | ntiersToPlot = 1 202 | for cell in cells: 203 | #clr = "#%06x" % random.randint(0, 0xFFFFFF) 204 | clr = "#EEEEEE" 205 | self.drawTiers(ntiersToPlot, cell, fig, clr) 206 | pl.scatter(0, 0, s=10, 207 | facecolors='none', color='#00FF00', zorder=0, 208 | label="Interfering Base Stations") 209 | 210 | def drawPointsInHexagon(self, pointsList, hexCenter, hexRadius, fig): 211 | # Plot of random user points in the hexagon 212 | # need fix for hexCenter not (0, 0) 213 | #ax = fig.gca() 214 | #ax.set_xlim(-hexRadius, hexRadius) 215 | #ax.set_ylim(-hexRadius, hexRadius) 216 | #ax.set_aspect('equal') 217 | 218 | x = hexCenter[0] * np.cos(np.pi / 6) 219 | y = hexCenter[1] + (hexCenter[0] * np.sin(np.pi / 6)) 220 | center = np.asarray([2 * self.redge * x, 2 * self.redge * y]) 221 | pointsList = [(center + np.asarray(z)) for z in pointsList] 222 | 223 | xsc, ysc = zip(*pointsList) 224 | #self.updateRadius(hexRadius) 225 | #self.drawHex(0, 0, fig, "#EEEEEE") 226 | ax = fig.gca() 227 | ax.scatter(xsc, ysc, s=1.0, color='#DB3236', zorder=200, label='Users') 228 | ax.legend(scatterpoints=5) 229 | 230 | def updateRadius(self, radius): 231 | self.radius = radius 232 | self.redge = radius * cc(np.pi / 6) 233 | self.basis = radius * self.basisdef 234 | --------------------------------------------------------------------------------