This repository has been archived by the owner on Nov 18, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck_autograd.py
81 lines (74 loc) · 2.45 KB
/
check_autograd.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
# Copyright (C) 2018 University of Vienna
# All rights reserved.
# BSD license.
# Author: Ali Baharev <[email protected]>
from __future__ import print_function, division
from os.path import isfile
from six import iteritems, exec_
from dag import create_dag, get_J_rowwise
from dag_to_py import print_node as print_fwd_node
from utils import StdoutHijack, serialize, deserialize
def main():
g, problem = create_dag('eco9')
numeric_diff(g, problem)
PREAMBLE = \
'''
import autograd.numpy as np
from autograd import jacobian
from autograd.numpy import exp, log
# name: {name}, nodes: {n_nodes}, edges: {n_edges}
'''
POSTAMBLE = \
'''
jac = jacobian(f)
J = jac(np.array([{x}], dtype=np.double))
'''
def numeric_diff(g, problem):
n_vars = problem.nl_header.n_vars
n_cons = problem.nl_header.n_cons
#
preamble = PREAMBLE.format(name=problem.name, n_nodes=g.number_of_nodes(),
n_edges=g.number_of_edges())
#
def_f = 'def f(x):'
assign = '\n'.join(' v{i} = x[{i}]'.format(i=i) for i in range(n_vars))
#
with StdoutHijack() as logger:
for n, d in iteritems(g.node):
print_fwd_node(g, n, d)
code = logger.captured_text()
code = '\n'.join(' ' + line for line in code.splitlines())
#
retval = ', '.join('C%d' % i for i in range(n_cons))
retval = ' return np.array([%s])' % retval
#
sols = problem.solutions
postamble = POSTAMBLE.format(x=', '.join(sols[0]))
#
return '\n'.join((preamble, def_f, assign, '\n', code, retval, postamble))
def get_numeric_jacobian(problem_name):
# Always return the Jacobian as list of (i, j, J_ij)
jacfile = 'data/' + problem_name + '.jac.pkl.gz'
if isfile(jacfile):
print('Using cached Jacobian for', problem_name)
return deserialize(jacfile)
#
print('Computing then saving the Jacobian for', problem_name)
g, problem = create_dag(problem_name)
code = numeric_diff(g, problem)
globals_ = {}
try:
exec_(code, globals_)
except:
print('===============================================================')
print(code)
print('===============================================================')
raise
J = globals_['J']
#
Jrows = get_J_rowwise(problem)
jac = [(i, j, J[i,j]) for i, cols in enumerate(Jrows) for j in cols]
serialize(jac, 'data/' + problem.name + '.jac.pkl.gz')
return jac
if __name__ == '__main__':
main()