homotopy-continuation-chann.../python/examples/toy_homotopy.py

132 lines
3.9 KiB
Python

import argparse
import numpy as np
import pandas as pd
# autopep8: off
import sys
import os
sys.path.append(f"{os.path.dirname(os.path.abspath(__file__))}/../")
# TODO: How do I import PathTracker and HomotopyGenerator properly?
from hccd import path_tracker, homotopy_generator
# autopep8: on
class ToyHomotopy:
"""Helper type implementing necessary functions for PathTracker.
Toy example homotopy:
G = [[x1],
[x2]]
F = [[x1 + x2 ],
[x2 + 0.5]]
H = (1-t)*G + t*F
Note that
y := [[x1],
[x2],
[t]]
"""
@staticmethod
def evaluate_H(y: np.ndarray) -> np.ndarray:
"""Evaluate H at y."""
x1 = y[0]
x2 = y[1]
t = y[2]
result = np.zeros(shape=2)
result[0] = x1 + t * x2
result[1] = x2 + t * 0.5
return result
@staticmethod
def evaluate_DH(y: np.ndarray) -> np.ndarray:
"""Evaluate Jacobian of H at y."""
x1 = y[0]
x2 = y[1]
t = y[2]
result = np.zeros(shape=(2, 3))
result[0, 0] = 1
result[0, 1] = t
result[0, 2] = x2
result[1, 0] = 0
result[1, 1] = 1
result[1, 2] = 0.5
return result
def track_path(args):
tracker = path_tracker.PathTracker(ToyHomotopy, args.euler_step_size, args.euler_max_tries,
args.newton_max_iter, args.newton_convergence_threshold, args.sigma)
ys_start, ys_prime, ys_hat_e, ys = [], [], [], []
try:
y = np.zeros(3)
for i in range(args.num_iterations):
y_start, y_prime, y_hat_e, y = tracker.transparent_step(y)
ys_start.append(y_start)
ys_prime.append(y_prime)
ys_hat_e.append(y_hat_e)
ys.append(y)
print(f"Iteration {i}: {y}")
except Exception as e:
print(f"Error: {e}")
ys_start = np.array(ys_start)
ys_prime = np.array(ys_prime)
ys_hat_e = np.array(ys_hat_e)
ys = np.array(ys)
df = pd.DataFrame({"x1b": ys_start[:, 0],
"x2b": ys_start[:, 1],
"tb": ys_start[:, 2],
"x1p": ys_prime[:, 0],
"x2p": ys_prime[:, 1],
"tp": ys_prime[:, 2],
"x1e": ys_hat_e[:, 0],
"x2e": ys_hat_e[:, 1],
"te": ys_hat_e[:, 2],
"x1n": ys[:, 0],
"x2n": ys[:, 1],
"tn": ys[:, 2]
})
if args.output:
df.to_csv(args.output, index=False)
else:
print(df)
def main():
parser = argparse.ArgumentParser(
description='Homotopy continuation path tracker')
parser.add_argument("--verbose", default=False, action='store_true')
parser.add_argument("--euler-step-size", type=float,
default=0.05, help="Step size for Euler predictor")
parser.add_argument("--euler-max-tries", type=int, default=5,
help="Maximum number of tries for Euler predictor")
parser.add_argument("--newton-max-iter", type=int, default=5,
help="Maximum number of iterations for Newton corrector")
parser.add_argument("--newton-convergence-threshold", type=float,
default=0.01, help="Convergence threshold for Newton corrector")
parser.add_argument("-s", "--sigma", type=int, default=1,
help="Direction in which the path is traced")
parser.add_argument("-o", "--output", type=str, help="Output csv file")
parser.add_argument("-n", "--num-iterations", type=int, default=20,
help="Number of iterations of the example program to run")
args = parser.parse_args()
track_path(args)
if __name__ == '__main__':
main()