# -*- coding: utf-8 -*-
"""WHM.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1SQiR2HPVu8j5VT8pJ5tMBfhTrNDvx7fr

**Řešení inverzní úlohy vedení tepla pomocí neuronových sítí**

"Whole History Mapping"

1. Použíté knihovny
"""

import pandas as pd
import numpy as np
import tensorflow as tf
import io
import matplotlib.pyplot as plt
from google.colab import files
from sklearn.preprocessing import StandardScaler

"""2. Whole History Mapping - vytvoření modelu: 50-20-50 (input-hidden-output) """

inputs = tf.keras.Input(shape=50, name="inputs")
x = tf.keras.layers.Dense(20, activation="sigmoid", name="hidden")(inputs)
outputs = tf.keras.layers.Dense(50, activation='linear', name="outputs")(x)
model = tf.keras.Model(inputs=inputs, outputs=outputs, name='WholeHistoryMapppingModel')
model.summary()
tf.keras.utils.plot_model(model, "model.png", show_shapes=True)

"""3. Načtení trénovacích dat - vygenerována řešením přímé úlohy vedení tepla"""

training_set = files.upload()

"""4. Data je potřeba rozdělit na "features" a "labels", výstupní vektory jsou normalizovány"""

from matplotlib import axes
frames = list()
n = 0
for file in training_set:
  frame = pd.read_csv(io.BytesIO(training_set[file]), header=None, delimiter=';')
  if frame.shape == (50,2):
    n = n + 1
    frames.append(frame)
data = pd.concat(frames)
data.rename(columns={0:'temperature', 1:'heat flux'}, inplace=True)
labels = data.pop('heat flux').to_numpy()
features = data.pop('temperature').to_numpy()
x_train = np.reshape(features,(n,50)).astype('float32')
y_train = np.reshape(labels,(n,50)).astype('float32')
scaler = StandardScaler()
scaler.fit(y_train.T)
y_train = scaler.transform(y_train.T).T

"""5. Trénování modelu"""

model.compile(loss=tf.keras.losses.mean_squared_error, optimizer=tf.keras.optimizers.Adam(0.001))
history = model.fit(x_train, y_train, epochs=150, batch_size=5, validation_split=0.2)
plt.title('Loss / Mean Squared Error')
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='test')

model.compile(loss=tf.keras.losses.mean_squared_error, optimizer=tf.keras.optimizers.Adam(0.0001))
history = model.fit(x_train, y_train, epochs=500, batch_size=n, validation_split=0.1)
plt.title('Loss / Mean Squared Error')
plt.plot(history.history['loss'], label='train')
plt.plot(history.history['val_loss'], label='test')

model.compile(loss=tf.keras.losses.mean_squared_error, optimizer=tf.keras.optimizers.Adam(0.001))
history = model.fit(x_train, y_train, epochs=1000, batch_size=n, validation_split=0.0)
plt.title('Loss / Mean Squared Error')
plt.plot(history.history['loss'], label='train')

"""6. Načtení dat testovacích úloh"""

testing_set = files.upload()

"""7. Hustota tepelného toku q_1"""

frame = pd.read_csv('triangularT_a=2_b=5_c=8_M=500000.csv', header=None, delimiter=';')
frame.rename(columns={0:'temperature', 1:'heat flux'}, inplace=True)
test_labels = frame.pop('heat flux')
test_features = frame.pop('temperature')
x_test = test_features.to_numpy()
x_test = np.reshape(x_test, (1,50))
y_real = test_labels.to_numpy()
y_real = np.reshape(y_real, (1,50))
y_predicted = model.predict(x_test)
time_steps = np.linspace(0, 10, 50)
print(np.mean(scaler.mean_))
print(np.mean(scaler.var_))
y_predicted = y_predicted * np.sqrt(np.mean(scaler.var_)) + np.mean(scaler.mean_)
#y_predicted = scaler.inverse_transform(y_predicted)
#plt.scatter(time_steps, y_predicted, color='red')
#plt.scatter(time_steps, scaler.fit_transform(y_real.T), color='blue')
plt.scatter(time_steps, y_predicted, color='red')
plt.scatter(time_steps, y_real, color='blue')

"""8. Uložení výsledků a modelu na GoogleDrive"""

from google.colab import drive
drive.mount('/content/gdrive')
model.save('/content/gdrive/MyDrive/Models/WHM_model_tri_200_01')
pd.DataFrame(y_predicted).to_csv('/content/gdrive/MyDrive/Models/q_tri_2.csv')

"""# Nová sekce

8. Hustota tepeln0ho toku q_2
"""

frame = pd.read_csv('rectangularT_a=2_b=5_M=500000.csv', header=None, delimiter=';')
frame.rename(columns={0:'temperature', 1:'heat flux'}, inplace=True)
test_labels = frame.pop('heat flux')
test_features = frame.pop('temperature')
x_test = test_features.to_numpy()
x_test = np.reshape(x_test, (1,50))
y_real = test_labels.to_numpy()
y_real = np.reshape(y_real, (1,50))
y_predicted = model.predict(x_test)
time_steps = np.linspace(0, 10, 50)
y_predicted = y_predicted * np.sqrt(np.mean(scaler.var_)) + np.mean(scaler.mean_)
#y_predicted = scaler.inverse_transform(y_predicted)
plt.scatter(time_steps, y_predicted, color='red')
plt.scatter(time_steps, y_real, color='blue')
#plt.scatter(time_steps, y_predicted, color='red')
#plt.scatter(time_steps, scaler.fit_transform(y_real.T), color='blue')