-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlagrangians.py
86 lines (66 loc) · 2.59 KB
/
lagrangians.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import numpy as np
class LMLagrangian():
def __init__(self, fun, init_guess, args, constraints) -> None:
self.args = args
self.init_guess = init_guess
self.dim = int(len(init_guess)/2)
self.fun = fun
self.n_constr = len(constraints)
self.constraints = constraints
G = np.zeros((self.n_constr, self.dim*2))
for n, constr in enumerate(constraints):
jac = constr['args'][0]
G[n] = jac
self.constr_mat = np.copy(G)
def get_guess(self):
guess = np.zeros(self.dim*2 + self.n_constr)
guess[:self.dim*2] = self.init_guess
return guess
def min_func(self, x_in, *args):
lam = x_in[self.dim*2:]
x = x_in[0:self.dim*2]
f, df = self.fun(x, *self.args)
constr_vals = np.zeros(self.n_constr)
for n, constr in enumerate(self.constraints):
constr_vals[n] = constr['fun'](x, constr['args'])
f += lam @ constr_vals
deriv = np.zeros_like(x_in)
deriv[0:self.dim*2] = df - self.constr_mat.T @ lam
deriv[self.dim*2:] = constr_vals
return f, deriv
class CostLagrangian():
def __init__(self, fun, init_guess, args, constraints, cost) -> None:
self.args = args
self.init_guess = init_guess
self.dim = int(len(init_guess)/2)
self.fun = fun
self.n_constr = len(constraints)
self.constraints = constraints
self.cost = cost
G = np.zeros((self.n_constr, self.dim*2))
for n, constr in enumerate(constraints):
jac = constr['args'][0]
G[n] = jac
self.constr_mat = np.copy(G)
def get_guess(self):
return self.init_guess
def min_func(self, x_in, *args):
x = x_in[0:self.dim*2]
f, df = self.fun(x, *self.args)
constr_vals = np.zeros(self.n_constr)
for n, constr in enumerate(self.constraints):
constr_vals[n] = constr['fun'](x, constr['args'])
f += self.cost * np.sum(constr_vals**2)
#print(self.cost * np.sum(constr_vals**2))
deriv = np.zeros_like(x_in)
deriv[0:self.dim*2] = df + 2*self.constr_mat.T @ constr_vals*self.cost
return f, deriv
def project(self, x):
G = self.constr_mat
G_GT_int = np.linalg.inv(G @ G.T)
G_prod = G.T @ G_GT_int
#I = np.eye(self.dim*2)
constr_vals = np.zeros(self.n_constr)
for n, constr in enumerate(self.constraints):
constr_vals[n] = constr['fun'](x, constr['args'])
return x - G_prod @ constr_vals