Remove editor module
This commit is contained in:
parent
e5959268c1
commit
c966866abc
37 changed files with 4063 additions and 3656 deletions
6
src/utils/__init__.py
Normal file
6
src/utils/__init__.py
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
from .random import random
|
||||
from .compute_histogram import compute_histogram
|
||||
from .generate_rotation_matrices import generate_rotation_matrices
|
||||
from .get_next_run_name import get_next_run_name
|
||||
from .kldiv import kldiv
|
||||
from .set_up_logging import set_up_logging
|
||||
22
src/utils/compute_histogram.py
Normal file
22
src/utils/compute_histogram.py
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
from PIL import Image
|
||||
import numpy as np
|
||||
|
||||
|
||||
def compute_histogram(
|
||||
image: Image.Image | np.ndarray,
|
||||
bins: int,
|
||||
value_range=(0, 256),
|
||||
normalize: bool = True,
|
||||
) -> np.ndarray:
|
||||
image = np.array(image) if isinstance(image, Image.Image) else image
|
||||
|
||||
histogram, _ = np.histogramdd(
|
||||
image.reshape(-1, 3), bins=bins, range=[value_range, value_range, value_range]
|
||||
)
|
||||
|
||||
histogram = histogram.astype(np.float32)
|
||||
|
||||
if normalize:
|
||||
histogram = histogram / np.sum(histogram)
|
||||
|
||||
return histogram
|
||||
66
src/utils/generate_rotation_matrices.py
Normal file
66
src/utils/generate_rotation_matrices.py
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
from random import shuffle
|
||||
from typing import List, Tuple
|
||||
import numpy as np
|
||||
from functools import lru_cache
|
||||
from numpy.typing import NDArray
|
||||
|
||||
|
||||
@lru_cache
|
||||
def generate_rotation_matrices(count: int) -> List[NDArray[np.float64]]:
|
||||
axes = fibonacci_sphere(count)
|
||||
shuffle(axes)
|
||||
angles = np.linspace(0, 2 * np.pi, count, endpoint=False)
|
||||
matrices = [_rotation_matrix(axis, angle) for axis, angle in zip(axes, angles)]
|
||||
for matrix in matrices:
|
||||
_check_rotation_matrix(matrix)
|
||||
return matrices
|
||||
|
||||
|
||||
def fibonacci_sphere(samples: int) -> List[Tuple[float, float, float]]:
|
||||
points = []
|
||||
phi = np.pi * (3.0 - np.sqrt(5.0)) # Golden angle in radians
|
||||
for i in range(samples):
|
||||
y = 1 - (i / float(samples - 1)) * 2 # y goes from 1 to -1
|
||||
radius = np.sqrt(1 - y * y) # radius at y
|
||||
|
||||
theta = phi * i # golden angle increment
|
||||
|
||||
x = np.cos(theta) * radius
|
||||
z = np.sin(theta) * radius
|
||||
|
||||
points.append([x, y, z])
|
||||
return points
|
||||
|
||||
|
||||
def _rotation_matrix(
|
||||
axis: Tuple[float, float, float], theta: float
|
||||
) -> NDArray[np.float64]:
|
||||
axis = np.asarray(axis)
|
||||
axis = axis / np.sqrt(np.dot(axis, axis))
|
||||
a = np.cos(theta / 2.0)
|
||||
b, c, d = -axis * np.sin(theta / 2.0)
|
||||
|
||||
aa, bb, cc, dd = a * a, b * b, c * c, d * d
|
||||
bc, ad, ac, ab, bd, cd = b * c, a * d, a * c, a * b, b * d, c * d
|
||||
return np.array(
|
||||
[
|
||||
[aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac)],
|
||||
[2 * (bc - ad), aa + cc - bb - dd, 2 * (cd + ab)],
|
||||
[2 * (bd + ac), 2 * (cd - ab), aa + dd - bb - cc],
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def _check_rotation_matrix(R: NDArray[np.float64]):
|
||||
# Check if the matrix is square
|
||||
if R.shape != (3, 3):
|
||||
raise ValueError("Matrix must be 3x3.")
|
||||
|
||||
# Check orthogonality: R.T * R should be close to the identity matrix
|
||||
I = np.eye(3)
|
||||
if not np.allclose(np.dot(R.T, R), I):
|
||||
raise ValueError("allclose")
|
||||
|
||||
# Check determinant: Should be +1
|
||||
if not np.isclose(np.linalg.det(R), 1.0):
|
||||
raise ValueError(f"det {np.linalg.det(R)}")
|
||||
7
src/utils/get_next_run_name.py
Normal file
7
src/utils/get_next_run_name.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
from pathlib import Path
|
||||
|
||||
|
||||
def get_next_run_name(path: Path, prefix: str = "run") -> str:
|
||||
run_ids = [int(run.stem.split("_")[1]) for run in path.glob(f"{prefix}_*")]
|
||||
next_run_id = max(run_ids, default=-1) + 1
|
||||
return f"{prefix}_{next_run_id}"
|
||||
11
src/utils/kldiv.py
Normal file
11
src/utils/kldiv.py
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import numpy as np
|
||||
|
||||
|
||||
def kldiv(P: np.ndarray, Q: np.ndarray) -> float:
|
||||
P /= P.sum()
|
||||
Q /= Q.sum()
|
||||
|
||||
P_safe = np.maximum(P, np.finfo(float).eps)
|
||||
Q_safe = np.maximum(Q, np.finfo(float).eps)
|
||||
|
||||
return np.sum(P_safe * np.log(P_safe / Q_safe))
|
||||
10
src/utils/random.py
Normal file
10
src/utils/random.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import numpy as np
|
||||
|
||||
|
||||
def random(min: float = 0, max: float = 1):
|
||||
mu = (max + min) / 2 # Mean of the distribution
|
||||
sigma = (
|
||||
max - min
|
||||
) / 6 # Standard deviation, chosen so that ~99.7% fall within [min_val, max_val]
|
||||
sample = np.random.normal(mu, sigma)
|
||||
return np.clip(sample, min, max)
|
||||
20
src/utils/set_up_logging.py
Normal file
20
src/utils/set_up_logging.py
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import logging
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def set_up_logging(logs_path: Optional[str] = None):
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s - %(levelname)s - %(message)s",
|
||||
handlers=[
|
||||
logging.StreamHandler(),
|
||||
(
|
||||
logging.FileHandler(
|
||||
logs_path / f"{datetime.now().isoformat(timespec='minutes')}.log"
|
||||
)
|
||||
if logs_path
|
||||
else logging.NullHandler()
|
||||
),
|
||||
],
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue