# Path: echotorch/datasets/NARMADataset.py
# class NARMADataset(Dataset):
#     """
#     xth order NARMA task
#     WARNING: this is an unstable dataset. There is a small chance the system becomes
#     unstable, leading to an unusable dataset. It is better to use NARMA30 which
#     where this problem happens less often.
#     """
# 
#     # Constructor
#     def __init__(self, sample_len, n_samples, system_order=10, seed=None):
#         """
#         Constructor
#         :param sample_len: Length of the time-series in time steps.
#         :param n_samples: Number of samples to generate.
#         :param system_order: th order NARMA
#         :param seed: Seed of random number generator.
#         """
#         # Properties
#         self.sample_len = sample_len
#         self.n_samples = n_samples
#         self.system_order = system_order
# 
#         # System order
#         self.parameters = torch.zeros(4)
#         if system_order == 10:
#             self.parameters[0] = 0.3
#             self.parameters[1] = 0.05
#             self.parameters[2] = 9
#             self.parameters[3] = 0.1
#         else:
#             self.parameters[0] = 0.2
#             self.parameters[1] = 0.04
#             self.parameters[2] = 29
#             self.parameters[3] = 0.001
#         # end if
# 
#         # Init seed if needed
#         if seed is not None:
#             torch.manual_seed(seed)
#         # end if
# 
#         # Generate data set
#         self.inputs, self.outputs = self._generate()
#     # end __init__
# 
#     #############################################
#     # OVERRIDE
#     #############################################
# 
#     # Length
#     def __len__(self):
#         """
#         Length
#         :return:
#         """
#         return self.n_samples
#     # end __len__
# 
#     # Get item
#     def __getitem__(self, idx):
#         """
#         Get item
#         :param idx:
#         :return:
#         """
#         return self.inputs[idx], self.outputs[idx]
#     # end __getitem__
# 
#     ##############################################
#     # PRIVATE
#     ##############################################
# 
#     # Generate
#     def _generate(self):
#         """
#         Generate dataset
#         :return:
#         """
#         inputs = list()
#         outputs = list()
#         for i in range(self.n_samples):
#             ins = torch.rand(self.sample_len, 1) * 0.5
#             outs = torch.zeros(self.sample_len, 1)
#             for k in range(self.system_order - 1, self.sample_len - 1):
#                 outs[k + 1] = self.parameters[0] * outs[k] + self.parameters[1] * outs[k] * torch.sum(
#                     outs[k - (self.system_order - 1):k + 1]) + 1.5 * ins[k - int(self.parameters[2])] * ins[k] + \
#                                  self.parameters[3]
#             # end for
#             inputs.append(ins)
#             outputs.append(outs)
#         # end for
# 
#         return inputs, outputs
#     # end _generate


import torch
import echotorch.nn as etnn
import echotorch.utils
import numpy as np
import mdp
from echotorch.datasets.NARMADataset import NARMADataset
from torch.autograd import Variable
from torch.utils.data.dataloader import DataLoader
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright Nils Schaetti <nils.schaetti@unine.ch>


# Imports

# Dataset params
train_sample_length = 5000
test_sample_length = 1000
n_train_samples = 1
n_test_samples = 1
batch_size = 1
spectral_radius = 0.9
leaky_rates = [1.0, 0.5, 0.1]
input_dim = 1
n_hidden = [100, 100, 100]

# Use CUDA?
use_cuda = False
use_cuda = torch.cuda.is_available() if use_cuda else False

# Manual seed
mdp.numx.random.seed(1)
np.random.seed(2)
torch.manual_seed(1)

# NARMA30 dataset
narma10_train_dataset = NARMADataset(train_sample_length, n_train_samples, system_order=10, seed=1)

# Path: echotorch/datasets/NARMADataset.py
# class NARMADataset(Dataset):
#     """
#     xth order NARMA task
#     WARNING: this is an unstable dataset. There is a small chance the system becomes
#     unstable, leading to an unusable dataset. It is better to use NARMA30 which
#     where this problem happens less often.
#     """
# 
#     # Constructor
#     def __init__(self, sample_len, n_samples, system_order=10, seed=None):
#         """
#         Constructor
#         :param sample_len: Length of the time-series in time steps.
#         :param n_samples: Number of samples to generate.
#         :param system_order: th order NARMA
#         :param seed: Seed of random number generator.
#         """
#         # Properties
#         self.sample_len = sample_len
#         self.n_samples = n_samples
#         self.system_order = system_order
# 
#         # System order
#         self.parameters = torch.zeros(4)
#         if system_order == 10:
#             self.parameters[0] = 0.3
#             self.parameters[1] = 0.05
#             self.parameters[2] = 9
#             self.parameters[3] = 0.1
#         else:
#             self.parameters[0] = 0.2
#             self.parameters[1] = 0.04
#             self.parameters[2] = 29
#             self.parameters[3] = 0.001
#         # end if
# 
#         # Init seed if needed
#         if seed is not None:
#             torch.manual_seed(seed)
#         # end if
# 
#         # Generate data set
#         self.inputs, self.outputs = self._generate()
#     # end __init__
# 
#     #############################################
#     # OVERRIDE
#     #############################################
# 
#     # Length
#     def __len__(self):
#         """
#         Length
#         :return:
#         """
#         return self.n_samples
#     # end __len__
# 
#     # Get item
#     def __getitem__(self, idx):
#         """
#         Get item
#         :param idx:
#         :return:
#         """
#         return self.inputs[idx], self.outputs[idx]
#     # end __getitem__
# 
#     ##############################################
#     # PRIVATE
#     ##############################################
# 
#     # Generate
#     def _generate(self):
#         """
#         Generate dataset
#         :return:
#         """
#         inputs = list()
#         outputs = list()
#         for i in range(self.n_samples):
#             ins = torch.rand(self.sample_len, 1) * 0.5
#             outs = torch.zeros(self.sample_len, 1)
#             for k in range(self.system_order - 1, self.sample_len - 1):
#                 outs[k + 1] = self.parameters[0] * outs[k] + self.parameters[1] * outs[k] * torch.sum(
#                     outs[k - (self.system_order - 1):k + 1]) + 1.5 * ins[k - int(self.parameters[2])] * ins[k] + \
#                                  self.parameters[3]
#             # end for
#             inputs.append(ins)
#             outputs.append(outs)
#         # end for
# 
#         return inputs, outputs
#     # end _generate


# Path: examples/timeserie_prediction/narma10_stacked_esn.py
import torch
import echotorch.nn as etnn
import echotorch.utils
import numpy as np
import mdp
from echotorch.datasets.NARMADataset import NARMADataset
from torch.autograd import Variable
from torch.utils.data.dataloader import DataLoader

# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright Nils Schaetti <nils.schaetti@unine.ch>


# Imports

# Dataset params
train_sample_length = 5000
test_sample_length = 1000
n_train_samples = 1
n_test_samples = 1
batch_size = 1
spectral_radius = 0.9
leaky_rates = [1.0, 0.5, 0.1]
input_dim = 1
n_hidden = [100, 100, 100]

# Use CUDA?
use_cuda = False
use_cuda = torch.cuda.is_available() if use_cuda else False

# Manual seed
mdp.numx.random.seed(1)
np.random.seed(2)
torch.manual_seed(1)

# NARMA30 dataset
narma10_train_dataset = NARMADataset(train_sample_length, n_train_samples, system_order=10, seed=1)

narma10_test_dataset = NARMADataset(test_sample_length, n_test_samples, system_order=10, seed=10)