| 1 |
""" |
|---|
| 2 |
Solving system of equations: |
|---|
| 3 |
|
|---|
| 4 |
x[0]**3 + x[1]**3 - 9 = 0 |
|---|
| 5 |
x[0] - 0.5*x[1] - 0.15*x[2]= 0 |
|---|
| 6 |
sinh(x[2]) + x[0] - 15 = 0 |
|---|
| 7 |
!! with numerical noise 1e-8 !! |
|---|
| 8 |
|
|---|
| 9 |
Note that both fsolve and nssolve |
|---|
| 10 |
get same gradient - |
|---|
| 11 |
if no user-supplied one is available, |
|---|
| 12 |
then same OO finite-difference one |
|---|
| 13 |
is used (according to p.diffInt value) |
|---|
| 14 |
|
|---|
| 15 |
If you have matplotlib installed, |
|---|
| 16 |
you'll get a figure. |
|---|
| 17 |
Typical fsolve fails number |
|---|
| 18 |
(for scipy 0.6.0) |
|---|
| 19 |
is ~ 10-15% |
|---|
| 20 |
|
|---|
| 21 |
This test runs ~ a minute on my AMD 3800+ |
|---|
| 22 |
""" |
|---|
| 23 |
noise = 1e-8 |
|---|
| 24 |
|
|---|
| 25 |
from scikits.openopt import NLSP |
|---|
| 26 |
from numpy import asfarray, zeros, cos, sin, arange, cosh, sinh, log10, ceil, floor, arange, inf |
|---|
| 27 |
from time import time |
|---|
| 28 |
from scipy import rand |
|---|
| 29 |
|
|---|
| 30 |
x0 = [8, 15, 0.80] |
|---|
| 31 |
global count1, count2, count3 |
|---|
| 32 |
count1 = count2 = count3 = 0 |
|---|
| 33 |
def Count1(): |
|---|
| 34 |
global count1; count1 +=1; return 0 |
|---|
| 35 |
def Count2(): |
|---|
| 36 |
global count2; count2 +=1; return 0 |
|---|
| 37 |
def Count3(): |
|---|
| 38 |
global count3; count3 +=1; return 0 |
|---|
| 39 |
|
|---|
| 40 |
|
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
|
|---|
| 44 |
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 |
|
|---|
| 48 |
|
|---|
| 49 |
f_without_noise = \ |
|---|
| 50 |
[lambda x: x[0]**2+x[1]**2-9, lambda x: x[0]-0.5*x[1] - 0.15*x[2], lambda x: sinh(x[2])+x[0]-15] |
|---|
| 51 |
def fvn(x): |
|---|
| 52 |
r = -inf |
|---|
| 53 |
for f in f_without_noise: r = max(r, abs(f(x))) |
|---|
| 54 |
return r |
|---|
| 55 |
f = [lambda x: x[0]**2+x[1]**2-9 + noise*rand(1)+Count1(), lambda x: x[0]-0.5*x[1] - 0.15*x[2] + noise*rand(1)+Count2(), \ |
|---|
| 56 |
lambda x: sinh(x[2])+x[0]-15 + noise*rand(1)+Count3()] |
|---|
| 57 |
|
|---|
| 58 |
|
|---|
| 59 |
|
|---|
| 60 |
|
|---|
| 61 |
|
|---|
| 62 |
|
|---|
| 63 |
|
|---|
| 64 |
|
|---|
| 65 |
|
|---|
| 66 |
|
|---|
| 67 |
|
|---|
| 68 |
|
|---|
| 69 |
|
|---|
| 70 |
N = 100 |
|---|
| 71 |
desired_ftol = 1e-6 |
|---|
| 72 |
assert desired_ftol - noise*len(x0) > 1e-7 |
|---|
| 73 |
|
|---|
| 74 |
scipy_fsolve_failed, fs = 0, [] |
|---|
| 75 |
print '----------------------------------' |
|---|
| 76 |
print 'desired ftol:', desired_ftol, 'objFunc noise:', noise |
|---|
| 77 |
|
|---|
| 78 |
print '---------- fsolve fails ----------' |
|---|
| 79 |
t = time() |
|---|
| 80 |
print 'N log10(MaxResidual) MaxResidual' |
|---|
| 81 |
for i in xrange(N): |
|---|
| 82 |
p = NLSP(f, x0, ftol = desired_ftol - noise*len(x0), iprint = -1, maxFunEvals = int(1e7)) |
|---|
| 83 |
r = p.solve('scipy_fsolve') |
|---|
| 84 |
v = fvn(r.xf) |
|---|
| 85 |
fs.append(log10(v)) |
|---|
| 86 |
if v > desired_ftol: |
|---|
| 87 |
scipy_fsolve_failed += 1 |
|---|
| 88 |
print i+1, ' %0.2f ' % log10(v), v |
|---|
| 89 |
else: |
|---|
| 90 |
print i+1, 'OK' |
|---|
| 91 |
print 'fsolve time elapsed', time()-t |
|---|
| 92 |
if scipy_fsolve_failed == 0: print 'None' |
|---|
| 93 |
|
|---|
| 94 |
print 'counters:', count1, count2, count3 |
|---|
| 95 |
|
|---|
| 96 |
count1 = count2 = count3 = 0 |
|---|
| 97 |
t = time() |
|---|
| 98 |
print '---------- nssolve fails ---------' |
|---|
| 99 |
nssolve_failed, ns = 0, [] |
|---|
| 100 |
print 'N log10(MaxResidual) MaxResidual' |
|---|
| 101 |
for i in xrange(N): |
|---|
| 102 |
p = NLSP(f, x0, ftol = desired_ftol - noise*len(x0), noise = noise, iprint = -1, maxFunEvals = int(1e7)) |
|---|
| 103 |
r = p.solve('nssolve') |
|---|
| 104 |
v = fvn(r.xf) |
|---|
| 105 |
ns.append(log10(v)) |
|---|
| 106 |
if v > desired_ftol: |
|---|
| 107 |
nssolve_failed += 1 |
|---|
| 108 |
print i+1, ' %0.2f ' % log10(v), v |
|---|
| 109 |
else: |
|---|
| 110 |
print i+1, 'OK' |
|---|
| 111 |
print 'nssolve time elapsed', time()-t |
|---|
| 112 |
if nssolve_failed == 0: print 'None' |
|---|
| 113 |
print 'nssolve_failed number:', nssolve_failed , '(from', N, '),', 100.0 * nssolve_failed / N, '%' |
|---|
| 114 |
print 'counters:', count1, count2, count3 |
|---|
| 115 |
|
|---|
| 116 |
print '------------ SUMMARY -------------' |
|---|
| 117 |
print 'fsolve_failed number:', scipy_fsolve_failed , '(from', N, '),', 100.0*scipy_fsolve_failed / N, '%' |
|---|
| 118 |
print 'nssolve_failed number:', nssolve_failed , '(from', N, '),', 100.0 * nssolve_failed / N, '%' |
|---|
| 119 |
|
|---|
| 120 |
try: |
|---|
| 121 |
from pylab import * |
|---|
| 122 |
subplot(2,1,1) |
|---|
| 123 |
grid(1) |
|---|
| 124 |
title('scipy.optimize fsolve fails to achive desired ftol: '+ str(100.0*scipy_fsolve_failed / N) +'%') |
|---|
| 125 |
xmin1, xmax1 = floor(min(fs)), ceil(max(fs))+1 |
|---|
| 126 |
hist(fs, arange(xmin1, xmax1)) |
|---|
| 127 |
|
|---|
| 128 |
axvline(log10(desired_ftol), color='green', linewidth=3, ls='--') |
|---|
| 129 |
[ymin1, ymax1] = ylim() |
|---|
| 130 |
|
|---|
| 131 |
|
|---|
| 132 |
subplot(2,1,2) |
|---|
| 133 |
grid(1) |
|---|
| 134 |
title('scikits.openopt nssolve fails to achive desired ftol: '+ str(100.0*nssolve_failed / N) +'%') |
|---|
| 135 |
xmin2, xmax2 = floor(min(ns)), ceil(max(ns))+1 |
|---|
| 136 |
|
|---|
| 137 |
hist(ns, arange(xmin2, xmax2)) |
|---|
| 138 |
xlabel('log10(maxResidual)') |
|---|
| 139 |
axvline(log10(desired_ftol), color='green', linewidth=3, ls='--') |
|---|
| 140 |
[ymin2, ymax2] = ylim() |
|---|
| 141 |
|
|---|
| 142 |
|
|---|
| 143 |
xmin, xmax = min(xmin1, xmin2) - 0.1, max(xmax1, xmax2) + 0.1 |
|---|
| 144 |
ymin, ymax = 0, max(ymax1, ymax2) * 1.05 |
|---|
| 145 |
subplot(2,1,1) |
|---|
| 146 |
xlim(xmin, xmax) |
|---|
| 147 |
ylim(0, ymax) |
|---|
| 148 |
subplot(2,1,2) |
|---|
| 149 |
xlim(xmin, xmax) |
|---|
| 150 |
show() |
|---|
| 151 |
except: |
|---|
| 152 |
pass |
|---|