"""
Last change: 30.07.2018
"""

# Some imports
import numpy as np
import math
from scipy import stats

class Standardization:

    def __init__(self):
        pass

    def standardize(self, x):

        """
        Standardization: x_std = (x - x_mean) / std_dev

        Inputs:
        - x: input vector (has to be a row vector)

        Returns:
        - x_norm: standardized vector of the inputed vector
        """

        mean = self.compute_mean(x)
        std_dev = self.compute_standard_deviation(x)

        x_norm = np.zeros_like(x)
        for i in range(x.shape[1]):

            x_norm[0, i] = (x[0, i] - mean) / std_dev

        return x_norm

    def compute_mean(self, x):

        """
         Computes mean of the inputed vector.

        Inputs:
         - x: input vector (has to be a row vector)

        Returns:
        - mean: mean value of the inputed vector
        """

        sm = np.sum(x)
        ln = x.shape[1]

        mean = sm / ln

        return mean


    def compute_standard_deviation(self, x):

        """
        Computes standard deviation of the inputed vector.

        Inputs:
        - x: input vector (has to be a row vector)

        Returns:
        - std_dev: standard deviation of the inputed vector
        """

        sm = np.sum(x)
        mean = self.compute_mean(x)

        summ = 0
        for i in range(x.shape[1]):
            summ = summ + (x[0, i] - mean)**2

        std_dev = math.sqrt(summ/x.shape[1])

        return std_dev

"""
# Test

# Instantiate class
obj = Normalization()

# Generate random vector
np.random.seed(5)
v = 10*np.random.random([1, 10])
print('Vector: ', v)

# Compute mean
mean = np.mean(v)
print('Mean: ', mean)

# Compute manual mean
mean_manual = obj.compute_mean(v)
print('Mean manual', mean_manual)

# Compute standard deviation
std_dev = np.std(v)
print('Standard deviation: ', std_dev)

# Compute manual standard deviation
std_dev_manual = obj.compute_standard_deviation(v)
print('Standard deviation manual', std_dev_manual)

# Standardize
standard = stats.zscore(v, axis=1)
print('Standardized: ', standard)

# Manual standardized
standard_manual = obj.standardize(v)
print('Standardized manual: ', standard_manual)
"""