1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 from numpy import dot, sqrt, trace, transpose
24 from numpy.linalg import LinAlgError, cholesky, solve
25
26
27 -def cholesky(dfk, d2fk, I, n, print_prefix, print_flag, return_matrix=0):
28 """Cholesky with added multiple of the identity.
29
30 Algorithm 6.3 from page 145 of 'Numerical Optimization' by Jorge Nocedal and Stephen J.
31 Wright, 1999, 2nd ed.
32
33 Returns the modified Newton step.
34 """
35
36
37 min_aii = 1e99
38 for i in xrange(n):
39 min_aii = min(d2fk[i, i], min_aii)
40
41
42 norm = sqrt(trace(dot(d2fk, d2fk)))
43 half_norm = norm / 2.0
44
45
46 if min_aii > 0.0:
47 tk = 0.0
48 else:
49 tk = half_norm
50
51
52 if print_flag >= 3:
53 print print_prefix + "Frobenius norm: " + `norm`
54 print print_prefix + "min aii: " + `min_aii`
55 print print_prefix + "tk: " + `tk`
56
57
58 while 1:
59 if print_flag >= 3:
60 print print_prefix + "Iteration"
61
62
63 matrix = d2fk + tk * I
64
65
66 try:
67 L = cholesky(matrix)
68 if print_flag >= 3:
69 print print_prefix + "\tCholesky matrix L:"
70 for i in xrange(n):
71 print print_prefix + "\t\t" + `L[i]`
72 except LinAlgError:
73 if print_flag >= 3:
74 print print_prefix + "\tLinearAlgebraError, matrix is not positive definite."
75
76
77 tk = max(2.0*tk, half_norm)
78 else:
79
80 break
81
82
83 y = solve(L, dfk)
84 import sys; sys.exit()
85 if return_matrix:
86 return -solve(transpose(L), y), matrix
87 else:
88 return -solve(transpose(L), y)
89