# -*- coding: utf-8 -*-
import plotly
from plotly.graph_objs import Scatter, Line
import torch
from torch import multiprocessing as mp

# Constants
STATE_SIZE = (3, 18, 18)
ACTION_SIZE = 3


# Global counter
class GlobalVar():
  def __init__(self):
    self.val = mp.Value('i', 0)
    self.lock = mp.Lock()

  def increment(self):
    with self.lock:
      self.val.value += 1

  def set(self, value):
    with self.lock:
      self.val.value = value

  def value(self):
    with self.lock:
      return self.val.value


# Converts an action index and action space size into a one-hot batch tensor
def action_to_one_hot(action_index, action_size):
  action = torch.zeros(1, action_size)
  action[0, action_index] = 1
  return action


# Creates an extended input (state + previous action + reward + timestep)
def extend_input(state, action, reward, timestep):
  reward = torch.Tensor([reward]).unsqueeze(0)
  timestep = torch.Tensor([timestep]).unsqueeze(0)
  return torch.cat((state.view(1, -1), action, reward, timestep), 1)


# Plots min, max and mean + standard deviation bars of a population over time
def plot_line(xs, ys_population, filename, y_title=''):
  max_colour = 'rgb(0, 132, 180)'
  mean_colour = 'rgb(0, 172, 237)'
  std_colour = 'rgba(29, 202, 255, 0.2)'

  ys = torch.Tensor(ys_population)
  ys_min = ys.min(1)[0].squeeze()
  ys_max = ys.max(1)[0].squeeze()
  ys_mean = ys.mean(1).squeeze()
  ys_std = ys.std(1).squeeze()
  ys_upper, ys_lower = ys_mean + ys_std, ys_mean - ys_std

  trace_max = Scatter(x=xs, y=ys_max.numpy(), line=Line(color=max_colour, dash='dash'), name='Max')
  trace_upper = Scatter(x=xs, y=ys_upper.numpy(), line=Line(color='transparent'), name='+1 Std. Dev.', showlegend=False)
  trace_mean = Scatter(x=xs, y=ys_mean.numpy(), fill='tonexty', fillcolor=std_colour, line=Line(color=mean_colour), name='Mean')
  trace_lower = Scatter(x=xs, y=ys_lower.numpy(), fill='tonexty', fillcolor=std_colour, line=Line(color='transparent'), name='-1 Std. Dev.', showlegend=False)
  trace_min = Scatter(x=xs, y=ys_min.numpy(), line=Line(color=max_colour, dash='dash'), name='Min')

  plotly.offline.plot({
    'data': [trace_upper, trace_mean, trace_lower, trace_min, trace_max],
    'layout': dict(xaxis={'title': 'Step'},
                   yaxis={'title': y_title})
  }, filename=filename, auto_open=False)

# -*- coding: utf-8 -*-
import plotly
from plotly.graph_objs import Scatter, Line
import torch
from torch import multiprocessing as mp

# Constants
STATE_SIZE = (3, 18, 18)
ACTION_SIZE = 3


# Global counter
class GlobalVar():
  def __init__(self):
    self.val = mp.Value('i', 0)
    self.lock = mp.Lock()

  def increment(self):
    with self.lock:
      self.val.value += 1

  def set(self, value):
    with self.lock:
      self.val.value = value

  def value(self):
    with self.lock:
      return self.val.value


# Converts an action index and action space size into a one-hot batch tensor
def action_to_one_hot(action_index, action_size):
  action = torch.zeros(1, action_size)
  action[0, action_index] = 1
  return action


# Creates an extended input (state + previous action + reward + timestep)
def extend_input(state, action, reward, timestep):
  reward = torch.Tensor([reward]).unsqueeze(0)
  timestep = torch.Tensor([timestep]).unsqueeze(0)
  return torch.cat((state.view(1, -1), action, reward, timestep), 1)


# Plots min, max and mean + standard deviation bars of a population over time
def plot_line(xs, ys_population, filename, y_title=''):
  max_colour = 'rgb(0, 132, 180)'
  mean_colour = 'rgb(0, 172, 237)'
  std_colour = 'rgba(29, 202, 255, 0.2)'

  ys = torch.Tensor(ys_population)
  ys_min = ys.min(1)[0].squeeze()
  ys_max = ys.max(1)[0].squeeze()
  ys_mean = ys.mean(1).squeeze()
  ys_std = ys.std(1).squeeze()
  ys_upper, ys_lower = ys_mean + ys_std, ys_mean - ys_std

  trace_max = Scatter(x=xs, y=ys_max.numpy(), line=Line(color=max_colour, dash='dash'), name='Max')
  trace_upper = Scatter(x=xs, y=ys_upper.numpy(), line=Line(color='transparent'), name='+1 Std. Dev.', showlegend=False)
  trace_mean = Scatter(x=xs, y=ys_mean.numpy(), fill='tonexty', fillcolor=std_colour, line=Line(color=mean_colour), name='Mean')
  trace_lower = Scatter(x=xs, y=ys_lower.numpy(), fill='tonexty', fillcolor=std_colour, line=Line(color='transparent'), name='-1 Std. Dev.', showlegend=False)
  trace_min = Scatter(x=xs, y=ys_min.numpy(), line=Line(color=max_colour, dash='dash'), name='Min')

  plotly.offline.plot({
    'data': [trace_upper, trace_mean, trace_lower, trace_min, trace_max],
    'layout': dict(xaxis={'title': 'Step'},
                   yaxis={'title': y_title})
  }, filename=filename, auto_open=False)

# -*- coding: utf-8 -*- # Constants # Global counter # Converts an action index and action space size into a one-hot batch tensor # Creates an extended input (state + previous action + reward + timestep) # Plots min, max and mean + standard deviation bars of a population over time