bounds_x = (-15, 5) bounds_y = (-15, 5) from FuncDesigner import * from openopt import IP x, y = oovars('x y') f = ff(y, x) # or 00 #f = (exp(-(x-0.1)**2/(2*sigma)) * exp(-(y+0.2)**2/(2*sigma))) / (2*pi*sigma) domain = {x: bounds_x, y: bounds_y} p = IP(f, domain, ftol=0.05) r = p.solve('interalg', maxIter=50, maxNodes=500000, maxActiveNodes=150, iprint=100) print('interalg result: %f' % r.ff) ''' OpenOpt Suite 0.45+ on Intal Atom 1.7 GHz: Solver: Time Elapsed = 1.34 CPU Time Elapsed = 1.34 objFunValue: 1.001662 (feasible, MaxResidual = 0.0369961) (usually solution, obtained by interalg, has real residual 10-100 times less than required tolerance, because interalg works with "most worst case" that extremely rarely occurs. Unfortunately, real obtained residual cannot be revealed). Now let's ensure scipy.integrate dblquad fails to solve the problem and mere lies about obtained residual:''' from scipy.integrate import dblquad val, abserr = dblquad(ff, bounds_x[0], bounds_x[1], lambda y: bounds_y[0],
# required accuracy # I use so big value for good graphical visualization below, elseware 2 lines are almost same and difficult to view ftol = 0.001 # this value is used by interalg only, not by scipy_lsoda t = oovar() f = 1 + t + 1000*(2*t - 9)/(1000000*(t - 4.5)**4 + 1) #f = 1 + 1e-10*t#1000*(2*t - 9)/(1000000*(t - 4.5)**4 + 1) # optional, for graphic visualisation and exact residual calculation - let's check IP result: exact_sol = lambda t: t + t**2 / 2 + arctan(1000*(t-4.5)**2)# + const, that is a function from y0 #exact_sol = lambda t: t#arctan(1000*(t-4.5)**2) y = oovar() domain = {t: (times[0], times[-1])} from openopt import IP p = IP(f, domain, ftol = ftol) r = p.solve('interalg', iprint = 100, maxIter = 1e4, maxActiveNodes = 100000) print('time elapsed: %f' % r.elapsed['solver_time']) equations = {y: f} # i.e. dy/dt = f startPoint = {y: 0} # y(t=0) = 0 # assign ODE. 3rd argument (here "t") is time variable that is involved in differentiation myODE = ode(equations, startPoint, {t: times}, ftol = ftol) T = time() r = myODE.solve('interalg', iprint = -1) print('Time elapsed with user-defined solution time intervals: %0.1f' % (time()-T)) Y = r(y) print('result in final time point: %f' % Y[-1]) realSolution = exact_sol(times) - exact_sol(times[0]) + startPoint[y] print('max difference from real solution: %0.9f (required: %0.9f)' \ % (max(abs(realSolution - Y)), ftol))
from numpy import pi, sqrt sigma = 1e-4 ff = lambda x: exp(-x**2/(2*sigma)) / sqrt(2*pi*sigma) bounds_x = (-20, 10) # integral over whole (-inf, inf) is 1.0 from FuncDesigner import * from openopt import IP x = oovar('x') # f = ff(x) # or mere f = exp(-x**2/(2*sigma)) / sqrt(2*pi*sigma) domain = {x: bounds_x} p = IP(f, domain, ftol = 0.0001) r = p.solve('interalg', maxIter = 5000, maxActiveNodes = 150) print('interalg result: %f' % r.ff) '''Solver: Time Elapsed = 0.2 CPU Time Elapsed = 0.2 objFunValue: 1.0000052 (feasible, MaxResidual = 1.31579e-05) interalg result: 1.000005 (usually solution, obtained by interalg, has real residual 10-100 times less than required tolerance, because interalg works with "most worst case" that extremely rarely occurs. Unfortunately, real obtained residual cannot be revealed). Now let's ensure scipy.integrate quad fails to solve the problem and mere lies about obtained residual: ''' from scipy.integrate import quad val, abserr = quad(ff, bounds_x[0], bounds_x[1]) print('scipy.integrate quad value: %f declared residual: %f' % (val, abserr)) '''scipy.integrate quad value: 0.000000 declared residual: 0.000000 While scipy quad fails already for sigma = 10^-4, interalg works perfectly even for sigma = 10^-30: Solver: Time Elapsed = 0.2 CPU Time Elapsed = 0.17 interalg result: 1.000008
# for FuncDesigner models you shouldn't keep the order in mind ff = lambda y, x: (exp(-(x-0.1)**2/(2*sigma)) * exp(-(y+0.2)**2/(2*sigma))) / (2*pi*sigma) bounds_x = (-15, 5) bounds_y = (-15, 5) from FuncDesigner import * from openopt import IP x, y = oovars('x y') #f = ff(y, x) # or f = (exp(-(x-0.1)**2/(2*sigma)) * exp(-(y+0.2)**2/(2*sigma))) / (2*pi*sigma) domain = {x: bounds_x, y: bounds_y} p = IP(f, domain, ftol = 0.05) r = p.solve('interalg', maxIter = 15000, maxNodes = 500000, maxActiveNodes = 150, iprint = 100) print('interalg result: %f' % p._F) ''' Solver: Time Elapsed = 3.48 CPU Time Elapsed = 3.47 objFunValue: 1.0000214 (feasible, MaxResidual = 0.0450278) (usually solution, obtained by interalg, has real residual 10-100 times less than required tolerance, because interalg works with "most worst case" that extremely rarely occurs. Unfortunately, real obtained residual cannot be revealed). Now let's ensure scipy.integrate dblquad fails to solve the problem and mere lies about obtained residual:''' from scipy.integrate import dblquad val, abserr = dblquad(ff, bounds_x[0], bounds_x[1], lambda y: bounds_y[0], lambda y: bounds_y[1]) print('scipy.integrate dblquad value: %f declared residual: %f' % (val, abserr)) ''' scipy.integrate dblquad value: 0.000000 declared residual: 0.000000 While scipy dblquad fails already for sigma = 10^-4, interalg works perfectly even for sigma = 10^-14: Solver: Time Elapsed = 43.34 CPU Time Elapsed = 43.0
from numpy import pi, sqrt sigma = 1e-4 ff = lambda x: exp(-x**2 / (2 * sigma)) / sqrt(2 * pi * sigma) bounds_x = (-20, 10) # integral over whole (-inf, inf) is 1.0 from FuncDesigner import * from openopt import IP x = oovar('x') # f = ff(x) # or mere f = exp(-x**2 / (2 * sigma)) / sqrt(2 * pi * sigma) domain = {x: bounds_x} p = IP(f, domain, ftol=0.0001) r = p.solve('interalg', maxIter=5000, maxActiveNodes=150) print('interalg result: %f' % r.ff) '''Solver: Time Elapsed = 0.2 CPU Time Elapsed = 0.2 objFunValue: 1.0000052 (feasible, MaxResidual = 1.31579e-05) interalg result: 1.000005 (usually solution, obtained by interalg, has real residual 10-100 times less than required tolerance, because interalg works with "most worst case" that extremely rarely occurs. Unfortunately, real obtained residual cannot be revealed). Now let's ensure scipy.integrate quad fails to solve the problem and mere lies about obtained residual: ''' from scipy.integrate import quad val, abserr = quad(ff, bounds_x[0], bounds_x[1]) print('scipy.integrate quad value: %f declared residual: %f' % (val, abserr)) '''scipy.integrate quad value: 0.000000 declared residual: 0.000000 While scipy quad fails already for sigma = 10^-4, interalg works perfectly even for sigma = 10^-30: Solver: Time Elapsed = 0.2 CPU Time Elapsed = 0.17 interalg result: 1.000008