Numpy Example
In this example, we will use numpy to perform matrix rotation using simulated annealing. We will define a fitness function that evaluates the rotation of a candidate matrix, and use simulated annealing to find the optimal rotation matrix.
from pathlib import Path
from numpy import array, zeros, matvec, ndarray, flip
from numpy.random import default_rng
from numpy.linalg import norm
from altbacken.external.neighbourhood.numeric import ArrayNeighbourhood
from altbacken.external.annealing import SimpleSimulatedAnnealing
from altbacken.internal.analysis.convergence import ConvergenceAnalyzer
from altbacken.internal.analysis.acceptance import AcceptanceAnalyzer
from altbacken.internal.report.file import JSONLineReport
Fitness function
We will use a simple fitness function to evaluate the rotation of a candidate matrix. The fitness function is the sum of the absolute difference between the rotated candidate and the optimal solution. For testings, we will use 100 random vectors.
rng = default_rng(None)
CANDIDATES: list[ndarray] = [
(v := rng.normal(size=2)) / norm(v)
for _ in range(100)
]
def apply_matrix(matrix: ndarray) -> float:
return sum(norm(flip(candidate) - matvec(matrix, candidate))**2 for candidate in CANDIDATES)
Annealing strategy
We choose a simple simulated annealing strategy with a temperature of 10000.0 and a neighbourhood size of 0.1.
annealing: SimpleSimulatedAnnealing = SimpleSimulatedAnnealing(
apply_matrix,
ArrayNeighbourhood(0.1),
10000.0
)
annealing.tracer = JSONLineReport(
Path("rotation_log.json_line"),
[ConvergenceAnalyzer(), AcceptanceAnalyzer(annealing.energy)],
)
Evaluation
The best values are printed, together with the norm of the difference between the matrix obtained by annealing and the rotation matrix.
best_match, best_value = annealing.simulate(zeros((2,2)))
annealing.tracer.close()
print("Best match", best_match)
print("Best value", best_value)
print("Distance from optimum", norm(best_match - array([[0,1], [1, 0]])))
Best match [[0.01098449 0.98603174]
[0.99981828 0.00534302]]
Best value 0.016596983069443485
Distance from optimum 0.01855673291866348