Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__pycache__/
/__pycache__
367 changes: 331 additions & 36 deletions ControlModule.py

Large diffs are not rendered by default.

33 changes: 12 additions & 21 deletions Metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])
13 changes: 6 additions & 7 deletions Reactor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 ###
...

Binary file modified __pycache__/ControlModule.cpython-312.pyc
Binary file not shown.
Binary file modified __pycache__/ControlModule.cpython-313.pyc
Binary file not shown.
Binary file modified __pycache__/Reactor.cpython-312.pyc
Binary file not shown.
99 changes: 65 additions & 34 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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)

Expand All @@ -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}")
Expand All @@ -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()