79 lines
2.0 KiB
Python
79 lines
2.0 KiB
Python
import torch.nn as nn
|
||
from torch.distributions.normal import Normal
|
||
import math
|
||
|
||
|
||
class GaussianChannel(nn.Module):
|
||
def __init__(self):
|
||
super().__init__()
|
||
|
||
# Initialize channel parameters
|
||
sys_rate = 32e9
|
||
r = 0.05
|
||
dispersion = 16.48e-6
|
||
B_2 = dispersion
|
||
non_linear_index = 1.3e3
|
||
gam = non_linear_index
|
||
loss = 10**20
|
||
alpha = loss
|
||
span_count = 20
|
||
N_s = span_count
|
||
span_length = 10e5 # (km)
|
||
L_s = span_length
|
||
noise_figure = 10 ** 0.5 # (dB)
|
||
h = 6.6261e-34
|
||
v = 299792458
|
||
B_WDM = sys_rate * (1 + r)
|
||
B_N = 0.1
|
||
|
||
P_ASE_1 = h * v * B_N * (loss * span_length * noise_figure - 1)
|
||
P_ASE = P_ASE_1 * span_count
|
||
L_eff = 1 - math.exp(-loss * span_length) / 2 / alpha
|
||
|
||
eps = 0.3 * math.log(
|
||
1 + (6 / L_s) * (
|
||
L_eff / math.asinh(
|
||
(math.pi ** 2)
|
||
/ 3
|
||
* B_2
|
||
* L_eff
|
||
* (B_WDM ** 2)
|
||
)
|
||
)
|
||
)
|
||
|
||
b = P_ASE_1 / (
|
||
2
|
||
* (N_s ** eps)
|
||
* B_N
|
||
* (gam ** 2)
|
||
* L_eff * math.asinh(
|
||
(math.pi ** 2) / 3
|
||
* B_2
|
||
* L_eff
|
||
* (B_WDM ** 2)
|
||
)
|
||
)
|
||
|
||
P_ch = sys_rate * (((27 * math.pi * B_2 / 16) * b) ** (1 / 3))
|
||
OSNR = (2 * P_ch / 3 / P_ASE)
|
||
|
||
OSNR_dB = 10 * math.log10(OSNR)
|
||
|
||
p_N_dB = -OSNR_dB
|
||
p_N_watt = 10**(p_N_dB/10)
|
||
|
||
self.noise_std = math.sqrt(p_N_watt * 5000)
|
||
|
||
def get_noise(self, rows):
|
||
"""
|
||
Generate Gaussian random noise according to the channel’s parameters.
|
||
|
||
:param rows: Number of noise vectors to generate.
|
||
:return: Matrix of shape `rows` × 2.
|
||
"""
|
||
return Normal(0, self.noise_std).sample((rows, 2))
|
||
|
||
def forward(self, x):
|
||
return x + self.get_noise(len(x))
|