153 lines
4.6 KiB
Python
153 lines
4.6 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 RepetitionCodeHomotopy:
|
|
# """Helper type implementing necessary functions for PathTracker.
|
|
#
|
|
# Repetiton code homotopy:
|
|
# G = [[x1],
|
|
# [x2],
|
|
# [x1]]
|
|
#
|
|
# F = [[1 - x1**2],
|
|
# [1 - x2**2],
|
|
# [1 - x1*x2]]
|
|
#
|
|
# 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]
|
|
#
|
|
# print(y)
|
|
#
|
|
# result = np.zeros(shape=3)
|
|
# result[0] = -t*x1**2 + x1*(1-t) + t
|
|
# result[1] = -t*x2**2 + x2*(1-t) + t
|
|
# result[2] = -t*x1*x2 + x1*(1-t) + t
|
|
#
|
|
# 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=(3, 3))
|
|
# result[0, 0] = -2*t*x1 + (1-t)
|
|
# result[0, 1] = 0
|
|
# result[0, 2] = -x1**2 - x1 + 1
|
|
# result[1, 0] = 0
|
|
# result[1, 1] = -2*t*x2 + (1-t)
|
|
# result[1, 2] = -x2**2 - x2 + 1
|
|
# result[1, 0] = -t*x2 + (1-t)
|
|
# result[1, 1] = -t*x1
|
|
# result[1, 2] = -x1*x2 - x1 + 1
|
|
#
|
|
# return result
|
|
|
|
|
|
def track_path(args):
|
|
H = np.array([[1, 1, 0, 0],
|
|
[0, 1, 1, 0],
|
|
[0, 0, 1, 1]])
|
|
|
|
homotopy = homotopy_generator.HomotopyGenerator(H)
|
|
|
|
print(f"G: {homotopy.G}")
|
|
print(f"F: {homotopy.F}")
|
|
print(f"H: {homotopy.H}")
|
|
print(f"DH: {homotopy.DH}")
|
|
|
|
tracker = path_tracker.PathTracker(homotopy, 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 = [], [], [], []
|
|
|
|
y = np.zeros(5) + np.array([0.5, 0.48, -0.1, 0.2, 0 ])
|
|
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}")
|
|
|
|
ys_start = np.array(ys_start)
|
|
ys_prime = np.array(ys_prime)
|
|
ys_hat_e = np.array(ys_hat_e)
|
|
ys = np.array(ys)
|
|
|
|
for y in np.transpose(ys):
|
|
plt.plot(y)
|
|
|
|
plt.show()
|
|
|
|
# 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()
|