import numpy as np
#import pygmo as pg
from scipy import optimize
from functools import partial
from .solver_functions.init_normals_given import init_normals_given
from .solver_functions.init_normals_not_given import init_normals_not_given
#import sys #should remove
#sys.path.append('..') # should remove
from ..kernel.kernel import kernel
[docs]class solver:
def __init__(self,points,normals):
self.points = points
self.normals = normals
self.kernel = kernel(points)
#self.problem = pg.problem(self.kernel)
[docs] def set_solver(self,verbose):
#nlopt_solvers = ['cobyla','bobyqa','newuoa','newuoa','newuoa_bound',
# 'praxis','neldermead','sbplx','mma','ccsaq','slsqp',
# 'lbfgs','tnewton_precond_restart','tnewton_precond',
# 'tnewton','var2','var1','auglag','auglag_eq']
scipy_solvers = ['Nelder-Mead','Powell','CG','BFGS','Newton-CG',
'L-BFGS-B','TNC','COBYLA','SLSQP','trust-constr',
'dogleg','trust-ncg','trust-exact','trust-krylov']
#if self.method in nlopt_solvers:
# nl = pg.nlopt(self.method)
# nl.xtol_rel = 1E-7
# nl.ftol_rel = 1E-7
# if self.method == 'lbfgs':
# nl.maxeval = 3000
# algorithm = pg.algorithm(nl)
# if verbose:
# algorithm.set_verbosity(1)
if self.method in scipy_solvers:
if verbose:
if self.method == 'trust-constr':
options = {'disp':True}
elif self.method == 'L-BFGS-B':
options = {'disp':99}
elif self.method in ['Newton-CG','CG','BFGS','Nelder-Mead',
'Powell','TNC','COBYLA','SLSQP']:
options = {'disp':True}
else:
print('No verbosity allowed for this method.')
options = {}
else:
options = {}
algorithm = partial(optimize.minimize,method=self.method,
tol=1e-07,options=options)
#algorithm = pg.algorithm(scp)
else:
print('Not an available solver method.')
#print('See nlopt methods: {}'.format(nlopt_solvers))
print('See scipy methods: {}'.format(scipy_solvers))
self.algorithm = algorithm
[docs] def vector_solver(self):
#self.population = pg.population(self.problem)
initial_solution = init_normals_given(self.normals)
#self.population.push_back(initial_solution)
#results = self.algorithm.evolve(self.population)
bounds = []
kernel_bounds = self.kernel.get_bounds()
for i in range(len(kernel_bounds[0])):
bounds.append(tuple([kernel_bounds[0][i],kernel_bounds[1][i]]))
results = self.algorithm(self.kernel.fitness,x0=initial_solution,
jac=self.kernel.jac,bounds=bounds)
return results
[docs] def variational_solver(self,lam):
#self.population = pg.population(self.problem)
initial_solution = init_normals_not_given(lam,self.kernel.K00,
self.kernel.K01,
self.kernel.K11)
#self.population.push_back(initial_solution)
#results = self.algorithm.evolve(self.population)
bounds = []
kernel_bounds = self.kernel.get_bounds()
for i in range(len(kernel_bounds)):
bounds.append(tuple([kernel_bounds[0][i],kernel_bounds[1][i]]))
results = self.algorithm(self.kernel.fitness,x0=initial_solution,
jac=self.kernel.jac,bounds=bounds)
return results
[docs] def solve(self,seed_number=1,lb=0.01,ub=1,perturb=0.01,
local_verbosity=False,local_method='L-BFGS-B',
variational=False,solver_method='Bounded',
solver_verbosity=True):
self.method = local_method
self.set_solver(local_verbosity)
if variational:
fit = lambda x: self.variational_solver(x).champion_f
lam = optimize.minimize_scalar(fit,bounds=(lb,ub),tol=1e-07,
method=solver_method,options={'disp':3})
result = self.variational_solver(lam.x)
else:
result = self.vector_solver()
gg = result.x
n = self.kernel.ndim
g = np.ones(n*self.kernel.ddim)
M_inv = self.kernel.A_inv[:n*(self.kernel.ddim+1),:n*(self.kernel.ddim+1)]
N_inv = self.kernel.A_inv[:n*(self.kernel.ddim+1),n*(self.kernel.ddim+1):]
##########################################
# Check normal direction
##########################################
for i in range(n):
g[i] = np.cos(gg[i*2+1])*np.sin(gg[i*2])
g[i+n] = np.sin(gg[i*2+1])*np.sin(gg[i*2])
g[i+2*n] = np.cos(gg[i*2])
s = np.zeros(n)
l_side = np.zeros(M_inv.shape[1])
l_side[:len(s)] = s
l_side[len(s):(len(s)+len(g))] = g
a = np.matmul(M_inv,l_side)
b = np.matmul(N_inv.T,l_side)
return a,b