diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5e43c01 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +/__pycache__ diff --git a/ControlModule.py b/ControlModule.py index ebe085c..a3a5277 100644 --- a/ControlModule.py +++ b/ControlModule.py @@ -8,55 +8,350 @@ def __init__(self): """Dummy constructor to use the Python Class as a namespace""" pass - @staticmethod # Hace que la función no necesite un argumento - def generate_P(probs) -> np.ndarray: + @staticmethod + def generate_P(probs: np.ndarray, n_states: np.int32 = 100) -> np.ndarray: """Function that generates the probabilities (transition) matrix""" - ### TO BE COMPLETED BY THE STUDENTS ### - # 3x3 o 3x3x3 o 100x100x3 - matriz_P = np.zeros((3, 10, 10), dtype=np.float64) + matrix_P = np.zeros((3, n_states, n_states), dtype=np.float64) # cambiar a 100x100 + #saca las probabilidades del Json + probs_decrease = probs[0] probs_maintain = probs[1] - print(probs_maintain) + probs_increase = probs[2] + + #Las probabilidades en los bordes se pierden, así que las filas no suman 1. (Y creo que normalizar es un apaño que no debería estar bien) + #Ej: COn decrease en estado 1, sumas las probabilidad de bajar a 0, pero no a la de bajar a -1 porque nunca se cumple en los IFs + + #Tantas iteraciones creo que son ineficientes, y mi pc es una patata, así que creo que hay que aprovechar mejor el hecho que + #sabemos que solo hay que modificar 3 IJs, no hace falta comprobar los 100, el 97% de las comprobaciones son inncesarias + + # ---------------- DECREASE ---------------- + """ + + DECREASE ANGEL + for estado_inicial in range(n_states): + dest_0 = max(0, estado_inicial - 2) + dest_1 = max(0, estado_inicial - 1) + dest_2 = estado_inicial + + matrix_P[0][estado_inicial][dest_0] += probs_decrease[0] + matrix_P[0][estado_inicial][dest_1] += probs_decrease[1] + matrix_P[0][estado_inicial][dest_2] += probs_decrease[2] + + """ + for estado_inicial in range(n_states): + for estado_final in range(n_states): + if estado_inicial == estado_final: + matrix_P[0][estado_inicial][estado_final] = probs_decrease[2] + elif estado_inicial - 1 == estado_final: + matrix_P[0][estado_inicial][estado_final] = probs_decrease[1] + elif estado_inicial - 2 == estado_final: + matrix_P[0][estado_inicial][estado_final] = probs_decrease[0] + + # ---------------- MAINTAIN ---------------- + for estado_inicial in range(n_states): + for estado_final in range(n_states): + if estado_inicial == estado_final: + matrix_P[1][estado_inicial][estado_final] = probs_maintain[1] + elif estado_inicial + 1 == estado_final: + matrix_P[1][estado_inicial][estado_final] = probs_maintain[2] + elif estado_inicial - 1 == estado_final: + matrix_P[1][estado_inicial][estado_final] = probs_maintain[0] + + # ---------------- INCREASE ---------------- + for estado_inicial in range(n_states): + for estado_final in range(n_states): + if estado_inicial == estado_final: + matrix_P[2][estado_inicial][estado_final] = probs_increase[0] + elif estado_inicial + 1 == estado_final: + matrix_P[2][estado_inicial][estado_final] = probs_increase[1] + elif estado_inicial + 2 == estado_final: + matrix_P[2][estado_inicial][estado_final] = probs_increase[2] + + # ---------------- CORRECCIÓN DE BORDES ---------------- + # Si una acción intenta llevar el reactor por debajo del estado 0 + # o por encima del estado n_states - 1, esa probabilidad no se pierde: + # se acumula en el borde correspondiente. + + # DECREASE: + # En estado 0, los movimientos -2 y -1 se quedan en 0. + matrix_P[0][0][0] += probs_decrease[0] + probs_decrease[1] + + # En estado 1, el movimiento -2 se queda en 0. + matrix_P[0][1][0] += probs_decrease[0] + + # MAINTAIN: + # En estado 0, el movimiento -1 se queda en 0. + matrix_P[1][0][0] += probs_maintain[0] + + # En el último estado, el movimiento +1 se queda en el último estado. + matrix_P[1][n_states - 1][n_states - 1] += probs_maintain[2] + + # INCREASE: + # En el penúltimo estado, el movimiento +2 se queda en el último estado. + matrix_P[2][n_states - 2][n_states - 1] += probs_increase[2] - for i in range(10): - for j in range(10): - if i == j: - matriz_P[1][i][j] = probs_maintain[1] - elif i + 1 == j: - matriz_P[1][i][j] = probs_maintain[2] - elif i-1 == j: - matriz_P[1][i][j] = probs_maintain[0] - + # En el último estado, los movimientos +1 y +2 se quedan en el último estado. + matrix_P[2][n_states - 1][n_states - 1] += probs_increase[1] + probs_increase[2] + - print("Probabilidades:\n", matriz_P.shape) - print(matriz_P) - return matriz_P - ... + """ + [[[0.8 0. 0. 0. 0. 0. 0. 0. 0. 0. ] + [0.025 0.8 0. 0. 0. 0. 0. 0. 0. 0. ] + [0.175 0.025 0.8 0. 0. 0. 0. 0. 0. 0. ] + [0. 0.175 0.025 0.8 0. 0. 0. 0. 0. 0. ] + [0. 0. 0.175 0.025 0.8 0. 0. 0. 0. 0. ] + [0. 0. 0. 0.175 0.025 0.8 0. 0. 0. 0. ] + [0. 0. 0. 0. 0.175 0.025 0.8 0. 0. 0. ] + [0. 0. 0. 0. 0. 0.175 0.025 0.8 0. 0. ] + [0. 0. 0. 0. 0. 0. 0.175 0.025 0.8 0. ] + [0. 0. 0. 0. 0. 0. 0. 0.175 0.025 0.8 ]] + + [[0.6 0.35 0. 0. 0. 0. 0. 0. 0. 0. ] + [0.05 0.6 0.35 0. 0. 0. 0. 0. 0. 0. ] + [0. 0.05 0.6 0.35 0. 0. 0. 0. 0. 0. ] + [0. 0. 0.05 0.6 0.35 0. 0. 0. 0. 0. ] + [0. 0. 0. 0.05 0.6 0.35 0. 0. 0. 0. ] + [0. 0. 0. 0. 0.05 0.6 0.35 0. 0. 0. ] + [0. 0. 0. 0. 0. 0.05 0.6 0.35 0. 0. ] + [0. 0. 0. 0. 0. 0. 0.05 0.6 0.35 0. ] + [0. 0. 0. 0. 0. 0. 0. 0.05 0.6 0.35 ] + [0. 0. 0. 0. 0. 0. 0. 0. 0.05 0.6 ]] + + [[0. 0.2 0.8 0. 0. 0. 0. 0. 0. 0. ] + [0. 0. 0.2 0.8 0. 0. 0. 0. 0. 0. ] + [0. 0. 0. 0.2 0.8 0. 0. 0. 0. 0. ] + [0. 0. 0. 0. 0.2 0.8 0. 0. 0. 0. ] + [0. 0. 0. 0. 0. 0.2 0.8 0. 0. 0. ] + [0. 0. 0. 0. 0. 0. 0.2 0.8 0. 0. ] + [0. 0. 0. 0. 0. 0. 0. 0.2 0.8 0. ] + [0. 0. 0. 0. 0. 0. 0. 0. 0.2 0.8 ] + [0. 0. 0. 0. 0. 0. 0. 0. 0. 0.2 ] + [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. ]]] + """ + + return matrix_P @staticmethod - def generate_R() -> np.ndarray: + def generate_R(demand_t: np.float64, n_states: np.int32 = 100) -> np.ndarray: """Function that generates the rewards (costs) matrix""" - ### TO BE COMPLETED BY THE STUDENTS ### - ... + demand = np.float64(demand_t) # Debug + + matrix_R = np.zeros((3, n_states, n_states), dtype=np.float64) # (3x)100x100 + # quitar DEBUGGING + # son recompensas, poner costes negativos + + # Se calcula la matriz de distancias entre el estado actual s y el estado futuro s' + # Aunque no se pueden alcanzar algunos estados (ej, pasar de s a s + 40), + # como en la matriz de probabilidades esa probabilidad es nula, el coste es indiferente + # Entonces, calculamos la distancia entre 'estado_inicial' y 'estado_final' y la duplicamos + # si la acción elegida se aleja del objetivo 'demand' + + + #al final hacer otra iteración exterior, y probar con np.where + # ---------------- DECREASE ---------------- + for estado_inicial in range(n_states): + for estado_final in range(n_states): + + delta_t = demand - (estado_final/ n_states) + + coste = abs(delta_t) + # Comprobamos si la acción nos aleja del estado final (demanda) + # Si la distancia hasta la demanda es mayor en el estado actual vs. en el estado final, + # nos hemos alejado. Hay que multiplicar x2 la distancia + if demand > (estado_inicial/ n_states): + # print( + # "Nos alejamos (decrease)", + # estado_inicial, + # estado_final, + # "d_t", + # delta_t, + # ) + coste *= 2 + # else: + # delta_t = abs(delta_t) # Para DEBUGING + # Rellenamos la matriz para estado_final x estado_inicial + matrix_R[0][estado_inicial][estado_final] = -coste + + # ---------------- MAINTAIN ---------------- + for estado_inicial in range(n_states): + for estado_final in range(n_states): + + delta_t = demand - (estado_final/ n_states) + + coste = abs(delta_t) + + + matrix_R[1][estado_inicial][estado_final] = -coste + + # ---------------- INCREASE ---------------- + for estado_inicial in range(n_states): + for estado_final in range(n_states): + + delta_t = demand - (estado_final/ n_states) + + coste = abs(delta_t) + # Comprobamos si la acción nos aleja del estado final (demanda) + # Si la distancia hasta la demanda es mayor en el estado actual vs. en el estado final, + # nos hemos alejado. Hay que multiplicar x2 la distancia + if demand < (estado_inicial/ n_states): + # print( + # "Nos alejamos (increase)", + # estado_inicial, + # estado_final, + # "d_t", + # delta_t, + # ) + coste *= 2 + # else: + # delta_t = abs(delta_t) # Para DEBUGING + + matrix_R[2][estado_inicial][estado_final] = -coste + + + + # Creamos unos tests + # print() + # for estado_inicial in range(1, 3): + # for estado_final in range(estado_inicial - 1, estado_inicial + 2): + # coste0 = matrix_R[0][estado_final][estado_inicial] + # coste1 = matrix_R[1][estado_final][estado_inicial] + # coste2 = matrix_R[2][estado_final][estado_inicial] + # print( + # f"ACCIÓN: decrease. Para ir desde {estado_inicial} hasta {estado_final} --> Coste: {coste0}" + # ) + # print( + # f"ACCIÓN: maintain. Para ir desde {estado_inicial} hasta {estado_final} --> Coste: {coste1}" + # ) + # print( + # f"ACCIÓN: increase. Para ir desde {estado_inicial} hasta {estado_final} --> Coste: {coste2}" + # ) + """ + [[[ *4. *4. *4. *4. *4. *4. *4. *4. *4. *4.] + [ *2. *2. *2. *2. *2. *2. *2. *2. *2. *2.] + [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] + [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] + [ 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.] + [ 3. 3. 3. 3. 3. 3. 3. 3. 3. 3.] + [ 4. 4. 4. 4. 4. 4. 4. 4. 4. 4.] + [ 5. 5. 5. 5. 5. 5. 5. 5. 5. 5.] + [ 6. 6. 6. 6. 6. 6. 6. 6. 6. 6.] + [ 7. 7. 7. 7. 7. 7. 7. 7. 7. 7.]] + + [[ *4. *4. *4. *4. *4. *4. *4. *4. *4. *4.] + [ *2. *2. *2. *2. *2. *2. *2. *2. *2. *2.] + [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] + [ *2. *2. *2. *2. *2. *2. *2. *2. *2. *2.] + [ *4. *4. *4. *4. *4. *4. *4. *4. *4. *4.] + [ *6. *6. *6. *6. *6. *6. *6. *6. *6. *6.] + [ *8. *8. *8. *8. *8. *8. *8. *8. *8. *8.] + [*10. *10. *10. *10. *10. *10. *10. *10. *10. *10.] + [*12. *12. *12. *12. *12. *12. *12. *12. *12. *12.] + [*14. *14. *14. *14. *14. *14. *14. *14. *14. *14.]] + + [[ 2. 2. 2. 2. 2. 2. 2. 2. 2. 2.] + [ 1. 1. 1. 1. 1. 1. 1. 1. 1. 1.] + [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] + [ *2. *2. *2. *2. *2. *2. *2. *2. *2. *2.] + [ *4. *4. *4. *4. *4. *4. *4. *4. *4. *4.] + [ *6. *6. *6. *6. *6. *6. *6. *6. *6. *6.] + [ *8. *8. *8. *8. *8. *8. *8. *8. *8. *8.] + [*10. *10. *10. *10. *10. *10. *10. *10. *10. *10.] + [*12. *12. *12. *12. *12. *12. *12. *12. *12. *12.] + [*14. *14. *14. *14. *14. *14. *14. *14. *14. *14.]]] + """ + return matrix_R @staticmethod - def control_iteration() -> np.int32: + def control_iteration(P, R, estado_actual, gamma, max_iter=1000) -> np.int32: """Function that computes one control-iteration""" - ### TO BE COMPLETED BY THE STUDENTS ### - ... + + # ECUACION BELLMAN: V(s) = max_a [ sum_s'( P[s,s',a] * (R[s,s',a] + gamma * V[s']) ) ] + + + # print("P y R", P.shape, R.shape) + # print() + # print(P[0][:3][:3]) + # print("P\n", P) + # print(R[0][:3][:3]) + # print() + + # -- Comprobacion provisional de si la matriz P es estocastica + # La última fila tiene todo ceros, rellenamos con uno en la posicion final + # print() + # print("P normalizada\n", P) + # print(check_stochastic(P)) + # print() + """ + #politica optima con la libreria .... + pi = mdptoolbox.mdp.PolicyIteration(P, R, gamma, max_iter=max_iter) + pi.setVerbose() + pi.run() + print("Policy: ", pi.policy) + return pi.policy[estado_actual]""" + + mdp = mdptoolbox.mdp.ValueIteration( + transitions=P, + reward=R, + discount=gamma, + max_iter=max_iter + ) + + mdp.run() + + return np.int32(mdp.policy[estado_actual]) + + @staticmethod - def control_loop( - demand: np.ndarray, - probs: np.ndarray, - n_states: np.int32, - n_actions: np.int32, - gamma: np.float64, - ) -> np.ndarray: + def control_loop(demand: np.ndarray, + probs: np.ndarray, + n_states: np.int32, + n_actions: np.int32, + gamma: np.float64,) -> np.ndarray: + """Function that computes all the required iterations (control-loop) to satisfy the power demand""" - ### TO BE COMPLETED BY THE STUDENTS ### - ### DUMMY BEHAVIOUR TO PREVENT CRASHING (MUST BE DELETED AFTER THE FULL IMPLEMENTATION) ### - return np.zeros_like(a=demand, dtype=np.float64) - ### ### + + respuesta = np.zeros_like(a=demand, dtype=np.float64) # Almacena las acciones para cada demanda + current_state = np.int32(0) # Estado inicial, se puede modificar si se desea empezar en otro estado + + action_deltas = [np.array([-2, -1, 0], dtype=np.int32), np.array([-1, 0, 1], dtype=np.int32),np.array([ 0, 1, 2], dtype=np.int32)] + ControlModule._P = ControlModule.generate_P(probs, n_states) + + for t in range(demand.shape[0]): # La demanda cambia en el tiempo + + ControlModule._demand_t = np.float64(demand[t]) + ControlModule._current_state = current_state + + ControlModule._R = ControlModule.generate_R(ControlModule._demand_t, n_states) # esta demanda concreta. + action = ControlModule.control_iteration(P= ControlModule._P, R= ControlModule._R, estado_actual = ControlModule._current_state, gamma=gamma) + + state_increment = np.random.choice( a=action_deltas[action], p=probs[action]) + current_state = current_state + state_increment + current_state = np.int32(np.clip(a=current_state, a_min=0, a_max=n_states - 1)) + respuesta[t] = current_state / n_states + return respuesta + +""" +def check_stochastic(P, tol=1e-6): + + P = np.array(P) + assert P.ndim == 3, f"P debe ser (A, S, S), tiene forma {P.shape}" + A, S, _ = P.shape + ok = True + for a in range(A): + row_sums = P[a].sum(axis=1) + bad = np.where(np.abs(row_sums - 1.0) > tol)[0] + if len(bad) > 0: + ok = False + for s in bad: + print(f" Acción {a}, Estado {s}: suma = {row_sums[s]:.8f}") + if ok: + print("✅ Matriz estocástica: todas las filas suman 1.") + else: + print("❌ Matriz NO estocástica.") + return ok + +""" + diff --git a/Metrics.py b/Metrics.py index 2515656..e31c215 100644 --- a/Metrics.py +++ b/Metrics.py @@ -3,32 +3,23 @@ def MAE(y_true: np.ndarray, y_pred: np.ndarray) -> np.float64: """ Implementation of the Mean Absolute Error (MAE) """ - ### TO BE COMPLETED BY THE STUDENTS ### - - ### DUMMY BEHAVIOUR TO PREVENT CRASHING (MUST BE DELETED AFTER THE FULL IMPLEMENTATION) ### - return 0.0 - ### ### + return np.float64((np.sum(abs(y_pred - y_true)))/len(y_pred)) + # return 0.0 DUMMY def MSE(y_true: np.ndarray, y_pred: np.ndarray) -> np.float64: """ Implementation of the Mean Squared Error (MSE) """ - ### TO BE COMPLETED BY THE STUDENTS ### - - ### DUMMY BEHAVIOUR TO PREVENT CRASHING (MUST BE DELETED AFTER THE FULL IMPLEMENTATION) ### - return 0.0 - ### ### + return np.float64(np.sum(abs((y_pred - y_true)**2))/len(y_pred)) + # return 0.0 DUMMY def R2(y_true: np.ndarray, y_pred: np.ndarray) -> np.float64: """ Implementation of the R2 metric """ - ### TO BE COMPLETED BY THE STUDENTS ### - - ### DUMMY BEHAVIOUR TO PREVENT CRASHING (MUST BE DELETED AFTER THE FULL IMPLEMENTATION) ### - return 0.0 - ### ### + return np.float64(1-(np.sum((y_true - y_pred)**2)/np.sum((y_true - np.mean(y_true))**2))) + # return 0.0 DUMMY def Corr(y_true: np.ndarray, y_pred: np.ndarray) -> np.float64: - """ Implementation of the Pearson's Correlation Coefficient """ - ### TO BE COMPLETED BY THE STUDENTS ### - - ### DUMMY BEHAVIOUR TO PREVENT CRASHING (MUST BE DELETED AFTER THE FULL IMPLEMENTATION) ### - return 0.0 - ### ### + """Implementation of the Pearson's Correlation Coefficient""" + + if np.std(y_true) == 0 or np.std(y_pred) == 0: + return np.float64(0.0) + + return np.float64(np.corrcoef(y_true, y_pred)[0, 1]) \ No newline at end of file diff --git a/Reactor.py b/Reactor.py index 2fcfb3a..9a65604 100644 --- a/Reactor.py +++ b/Reactor.py @@ -31,20 +31,19 @@ def __str__(self) -> str: def compute_max_power(self) -> np.float64: """ Computes the maximum power of a reactor based on its physical features """ - ### TO BE COMPLETED BY THE STUDENTS ### - ... + return np.float64(self.effective_section * self.neutron_flux * self.core_volume * self.fision_energy) def compute_k(self) -> np.float64: """ Computes the value of the k-constant """ - ### TO BE COMPLETED BY THE STUDENTS ### - ... + self.P_max = self.compute_max_power() + return - np.log(10** -6/self.P_max) def compute_power(self, control_bars_insertion: np.float64) -> np.float64: """ Computes the power delivered (%) by the reactor based on the % of control-bars inserted """ - ### TO BE COMPLETED BY THE STUDENTS ### - ... + k = self.compute_k() + return np.float64(self.P_max * (np.e**(-k * control_bars_insertion))) def compute_control_bars_insertion(self, power: np.float64) -> np.float64: """ Computes the % of controls-bars inserted based on the % of power delivered by the reactor """ ### TO BE COMPLETED BY THE STUDENTS ### - ... + diff --git a/__pycache__/ControlModule.cpython-312.pyc b/__pycache__/ControlModule.cpython-312.pyc index 5d3bcb1..cfc526d 100644 Binary files a/__pycache__/ControlModule.cpython-312.pyc and b/__pycache__/ControlModule.cpython-312.pyc differ diff --git a/__pycache__/ControlModule.cpython-313.pyc b/__pycache__/ControlModule.cpython-313.pyc index 8788832..43629b4 100644 Binary files a/__pycache__/ControlModule.cpython-313.pyc and b/__pycache__/ControlModule.cpython-313.pyc differ diff --git a/__pycache__/Reactor.cpython-312.pyc b/__pycache__/Reactor.cpython-312.pyc index 5544cfa..6b6c8b8 100644 Binary files a/__pycache__/Reactor.cpython-312.pyc and b/__pycache__/Reactor.cpython-312.pyc differ diff --git a/main.py b/main.py index 94ed703..026f352 100644 --- a/main.py +++ b/main.py @@ -8,39 +8,49 @@ from Metrics import * from Plotter import * -def get_args() -> tuple[Reactor, np.float64, np.float64]: # 3 salidas (?) + +def get_args() -> tuple[Reactor, np.float64, np.float64]: # 3 salidas (?) # Define the parser object parser = argparse.ArgumentParser() # Define the expected arguments to parse and their data types - parser.add_argument("--input-reactor", "-i", type=str, help="Path of the reactor's JSON file") - parser.add_argument("--gamma", "-g", type=float, help="Discount factor used in the MDP") - parser.add_argument("--random-seed", "-r", type=int, help="Pseudo-random number generator seed") + parser.add_argument( + "--input-reactor", "-i", type=str, help="Path of the reactor's JSON file" + ) + parser.add_argument( + "--gamma", "-g", type=float, help="Discount factor used in the MDP" + ) + parser.add_argument( + "--random-seed", "-r", type=int, help="Pseudo-random number generator seed" + ) # Parse the arguments args = parser.parse_args() - + # Some verbose to check the correct parsing of the input arguments print(f"Loading reactor from file: {args.input_reactor}") print(f"Using gamma (discount factor): {args.gamma}") print(f"Using {args.random_seed} as random seed") # Build the Reactor object by reading the reactor's JSON file - with open(args.input_reactor, 'r', encoding='utf-8') as file: + with open(args.input_reactor, "r", encoding="utf-8") as file: json_data = json.load(fp=file) - reactor = Reactor(model=json_data['model'], - effective_section=float(json_data['effective_section']), - neutron_flux=float(json_data['neutron_flux']), - core_volume=float(json_data['core_volume']), - fision_energy=float(json_data['fision_energy']), - probabilities=dict(json_data['probabilities'])) - + reactor = Reactor( + model=json_data["model"], + effective_section=float(json_data["effective_section"]), + neutron_flux=float(json_data["neutron_flux"]), + core_volume=float(json_data["core_volume"]), + fision_energy=float(json_data["fision_energy"]), + probabilities=dict(json_data["probabilities"]), + ) + # Some verbose of the reactor loaded print(reactor) # Overloaded in the __str__ method of Reactor's class - + # Return the Reactor object, gamma and the random seed return reactor, args.gamma, args.random_seed + def main() -> None: # Parse the main arguments reactor, gamma, random_seed = get_args() @@ -49,30 +59,50 @@ def main() -> None: np.random.seed(random_seed) # Get the probabilities from the reactor's dynamics - probs = np.array([reactor.probabilities['decrease'], - reactor.probabilities['maintain'], - reactor.probabilities['increase']], dtype=np.float64) - - matriz_P = ControlModule.generate_P(probs) - + probs = np.array( + [ + reactor.probabilities["decrease"], + reactor.probabilities["maintain"], + reactor.probabilities["increase"], + ], + dtype=np.float64, + ) + + matriz_P = ControlModule.generate_P(probs, 100) + # Make a radar-plot with the reactor probabilities - plot_reactor_as_radar(probs=probs) - + # plot_reactor_as_radar(probs=probs) + + # Generate a random power demand # Generate a random power demand demand = generate_demand(n_samples=512) + # print("Demand:\n", demand) + + estado_actual = 5 + i = 90 + if True: + demand_test = i / 100 + matriz_R = ControlModule.generate_R(demand_test) + + response_test = ControlModule.control_iteration( + matriz_P, + matriz_R, + estado_actual, + gamma + ) + print("Response 'unitaria':", response_test) # Define the number of MDP's states, actions and the discount factor (gamma) - n_states = 100 + n_states = 100 n_actions = 3 - # Get the response time-series (answer to the demand time-series) - response = ControlModule.control_loop(demand=demand, - probs=probs, - n_states=n_states, - n_actions=n_actions, - gamma=gamma) - + response = ControlModule.control_loop( + demand=demand, probs=probs, n_states=n_states, n_actions=n_actions, gamma=gamma + ) + + # print("Response:\n", response) # Array con 512 respuestas + # Plot the original power demand plot_demand(demand=demand) @@ -86,9 +116,9 @@ def main() -> None: plot_correlation(demand=demand, response=response) # Print the four regression metrics for the current demand-response data - _MAE = MAE(y_true=demand, y_pred=response) - _MSE = MSE(y_true=demand, y_pred=response) - _R2 = R2(y_true=demand, y_pred=response) + _MAE = MAE(y_true=demand, y_pred=response) + _MSE = MSE(y_true=demand, y_pred=response) + _R2 = R2(y_true=demand, y_pred=response) _Corr = Corr(y_true=demand, y_pred=response) print(f"MAE={_MAE:.6f}") print(f"MSE={_MSE:.6f}") @@ -101,5 +131,6 @@ def main() -> None: # Plot the R2 and the Corr in a bar-plot plot_r2_and_pearson(R2=_R2, Pearson=_Corr) -if __name__ == '__main__': + +if __name__ == "__main__": main()