Commit 3174ca5e authored by Ashkan's avatar Ashkan
Browse files

Add get_redundant_information function.

parent 14415b99
Loading
Loading
Loading
Loading
+30 −10
Original line number Diff line number Diff line
@@ -9,6 +9,8 @@ cimport cprrt
import datetime
import socket
import ipaddress
import numpy as np
from scipy.special import comb

include "sockets.pxd"

@@ -148,33 +150,51 @@ class ApplicationParameters:


class PrrtCodingConfiguration:
    def __init__(self, n, k, n_cycle=None):
    def __init__(self, n, k, p_e, n_p=None):
        if n < k:
            raise ValueError("n must be greater or equal k.")
        self.n = n
        self.k = k
        self.r = n - k
        self.p_e = p_e

        if self.r != 0 and n_cycle is None:
            raise ValueError("n_cycle cannot be None if (n-k) != 0.")

        if sum(n_cycle) != (n-k):
            raise ValueError("The elements in n_cycle must sum up to n-k.")
        if self.r != 0 and n_p is None:
            raise ValueError("n_p cannot be None if (n-k) != 0.")
        #
        if sum(n_p) != (n-k):
            raise ValueError("The elements in n_p must sum up to n-k.")

        self.n_cycle = n_cycle if n_cycle is not None else [0]
        self.n_p = n_p if n_p is not None else [0]

    def __repr__(self):
        return "PrrtCodingConfiguration(n={},k={},n_cycle={})".format(self.n, self.k, self.n_cycle)
        return "PrrtCodingConfiguration(n={},k={},n_p={})".format(self.n, self.k, self.n_p)

    def __str__(self):
        return "({},{},{})".format(self.n, self.k, self.n_cycle)
        return "({},{},{})".format(self.n, self.k, self.n_p)

    # TODO
    # def __eq__()

    # TODO
    # Calculate the redundancy information this coding configuration causes, given a certain channel.
    # ri = PrrtChannelParameters.get_ri_opt(applicationParameters)
    def sum_error_prob_over_sent_packets(self, sent_packets_item):
        error_prob = 0
        for i in range(sent_packets_item + 1, sent_packets_item + self.k + 1):
            error_prob += self.get_error_prob(i, sent_packets_item + self.k)
        print(error_prob)
        return error_prob

    def get_error_prob(self, i, sent_packets_item):
        return comb(sent_packets_item, i) * (self.p_e ** i) * ((1 - self.p_e) ** (sent_packets_item - i))

    def get_redundant_information(self):
        sent_redundant_packets = np.cumsum(self.n_p)  # Cumulative sum of all redundant packets up to each cycle
        print(sent_redundant_packets)
        error_prob_up_to_every_cycle = list(map(lambda x : self.sum_error_prob_over_sent_packets(x), sent_redundant_packets[1:]))

        ri = 1 / self.k * self.n_p[0] + 1 / self.k * np.dot(error_prob_up_to_every_cycle, self.n_p[1:])
        return ri


    # TODO
    # Check if it is able to fulfill application parameters given channel parameters.