Files
Astrape/gibil/classes/predictors/math_utils.py
T
rpotter6298 c8e3016fd6 Add new daemons and debug scripts for Sigenergy and Oracle functionalities
- Implement `sigen_daemon.py` to poll Sigenergy plant metrics and store snapshots.
- Create `web_daemon.py` for serving a web interface with various endpoints.
- Add debug scripts:
  - `debug_duplicates.py` to find duplicate target times in forecast data.
  - `debug_energy_forecast.py` to print baseline energy forecast curves.
  - `debug_oracle_evaluations.py` to run the oracle evaluator.
  - `debug_sigen.py` to inspect stored Sigenergy plant snapshots.
  - `debug_weather.py` to trace resolved truth data.
  - `modbus_test.py` for exploring Sigenergy plants or inverters over Modbus TCP.
- Introduce `oracle_evaluator.py` for evaluating stored oracle predictions against actuals.
- Add TCN training scripts in `tcn` directory for training usage sequence models.
2026-04-28 08:14:00 +02:00

70 lines
2.0 KiB
Python

from __future__ import annotations
def fit_ridge_regression(
features: list[list[float]],
targets: list[float],
ridge_lambda: float,
) -> list[float] | None:
if not features:
return None
width = len(features[0])
xtx = [[0.0 for _ in range(width)] for _ in range(width)]
xty = [0.0 for _ in range(width)]
for row, target in zip(features, targets):
for i in range(width):
xty[i] += row[i] * target
for j in range(width):
xtx[i][j] += row[i] * row[j]
for i in range(1, width):
xtx[i][i] += ridge_lambda
return solve_linear_system(xtx, xty)
def solve_linear_system(
matrix: list[list[float]],
vector: list[float],
) -> list[float] | None:
size = len(vector)
rows = [matrix[index][:] + [vector[index]] for index in range(size)]
for pivot_index in range(size):
pivot_row = max(
range(pivot_index, size),
key=lambda row_index: abs(rows[row_index][pivot_index]),
)
if abs(rows[pivot_row][pivot_index]) < 1e-9:
return None
rows[pivot_index], rows[pivot_row] = rows[pivot_row], rows[pivot_index]
pivot = rows[pivot_index][pivot_index]
rows[pivot_index] = [value / pivot for value in rows[pivot_index]]
for row_index in range(size):
if row_index == pivot_index:
continue
factor = rows[row_index][pivot_index]
rows[row_index] = [
value - factor * pivot_value
for value, pivot_value in zip(rows[row_index], rows[pivot_index])
]
return [row[-1] for row in rows]
def dot(left: list[float], right: list[float]) -> float:
return sum(left_value * right_value for left_value, right_value in zip(left, right))
def quantile(values: list[float], q: float) -> float:
if not values:
return 0.0
sorted_values = sorted(values)
index = round((len(sorted_values) - 1) * q)
return sorted_values[index]