Home Install Documentation Problems Tree Applications Forum

Save your money
via IT outsourcing!

Ukrainian HI-TECH Initiative

DerApproximatorDoc

From OpenOpt

Jump to: navigation, search
DerApproximator Documentation


Made by Dmitrey

Contents


Introduction

DerApproximator is a small yet important package for getting/checking derivatives (currently only 1st ones), extracted from OpenOpt framework to be standalone Python module. It is required by FuncDesigner (for obtaining derivatives of oofuns beyond standard set without routines to yield them directly) and some OpenOpt solvers (when there are some functions without user-supplied derivatives). Maybe some parallel calculations will be involved in future.

Requirements for the package (as well as for OpenOpt and FuncDesigner) are NumPy and python-setuptools; OS - any where Python and numpy work (Linux, Windows, Mac OS X etc). See Install for more details.

Attention Hint: if your architecture has type float128 (you can check it via 'float128' in dir(numpy) or hasattr(numpy,'float128')), then you can involve this type (convert your point where derivatives have to be obtained) and get more precise answer (by default float64 is used). Also, to improve precision all stencils should be set to maximum value (that is 3 for now).

Obtaining first-order derivatives

To perform this you should use function get_d1.
Usage: get_d1(fun, x, diffInt=1.5e-8, pointVal = None, args=(), stencil = 3, varForDifferentiation = None, exactShape = False)
Parameters:

fun: R^n -> R^m, x0 from R^n: function and point where derivatives should be obtained 
diffInt - step for stencil
pointVal - fun(x) if known (it is used from OpenOpt and FuncDesigner)
args - additional args for fun, if not equalk to () then fun(x, *args) will be involved 
stencil = 1: (f(x+diffInt) - f(x)) / diffInt
stencil = 2: (f(x+diffInt) - f(x-diffInt)) / (2*diffInt)
stencil = 3: (-f(x+2*diffInt) + 8*f(x+diffInt) - 8*f(x-diffInt) + f(x-2*diffInt)) / (12*diffInt)
varForDifferentiation - the parameter is used from FuncDesigner
exactShape - set True to forbid possible flattering for 1D arrays

Example:

from DerApproximator import *
print(get_d1(lambda x: (x**2).sum(), [1,2,3]))
print(get_d1(lambda x: x**2, [1,2,3]))
"""
Expected output: 
[ 1.99999993  3.99999998  5.99999996]
[[ 2.          0.          0.        ]
[ 0.          3.99999996  0.        ]
[ 0.          0.          5.99999996]]
"""


Obtaining second-order derivatives

To perform this you should use function get_d2. Please pay attention: currently this function is optimized for avoiding NaNs and (lesser) for more exact result, but not for speed.
Usage: get_d2(fun, vars, fun_d = None, diffInt = 1.5e-4, pointVal = None, args=(), stencil = 3, varForDifferentiation = None, exactShape = True, pointD1 = None)
Parameters:

fun: R^n -> R^m, x0 from R^n: function and point where derivatives should be obtained 
currently implemented for m=1 only!
    
diffInt - step for stencil
pointVal - fun(x) if known (it is used from OpenOpt and FuncDesigner)
args - additional args for fun, if not equalk to () then fun(x, *args) will be involved 
    
stencil - parameter for lower-level routine get_d1 that is currently used in get_d2, default stencil=3
stencil = 1: (f(x+diffInt) - f(x)) / diffInt
stencil = 2: (f(x+diffInt) - f(x-diffInt)) / (2*diffInt)
stencil = 3: (-f(x+2*diffInt) + 8*f(x+diffInt) - 8*f(x-diffInt) + f(x-2*diffInt)) / (12*diffInt)
    
varForDifferentiation - the parameter is used from FuncDesigner
exactShape - set True to forbid possible flattering for 1D arrays
pointD1 - value of 1st derivatives in the point involved (if known)

Example:

from DerApproximator import *
from numpy import *
ff=lambda x: sum(x**2) + x[0]*x[2]
x = [1, 2, 3]
print(get_d2(ff, x))
[[  2.00000008e+00   7.01739901e-08   9.99999692e-01]
 [  7.01774441e-08   1.99999976e+00  -2.80707803e-07]
 [  9.99999692e-01  -2.80703855e-07   1.99999994e+00]]


Check a routine that provides first-order derivatives

To perform this you should use function check_d1.
Usage: check_d1(fun, fun_d, x, func_name='func', diffInt=1.5e-8, pointVal = None, args=(), stencil = 3, maxViolation=0.01, varForCheck = None)
Parameters:

    
fun: R^n -> R^m, x0 from R^n: function and point where derivatives should be obtained 
fun_d - user-provided routine for derivatives evaluation to be checked 
diffInt - step for stencil
pointVal - fun(x) if known (it is used from OpenOpt and FuncDesigner)
args - additional args for fun, if not equalk to () then fun(x, *args) will be involved 
stencil = 1: (f(x+diffInt) - f(x)) / diffInt
stencil = 2: (f(x+diffInt) - f(x-diffInt)) / (2*diffInt)
stencil = 3: (-f(x+2*diffInt) + 8*f(x+diffInt) - 8*f(x-diffInt) + f(x-2*diffInt)) / (12*diffInt)
maxViolation - threshold for reporting of incorrect derivatives
varForCheck - the parameter is used from FuncDesigner  
"""
Note that one of output values RD (relative difference) is defined as
int(ceil(log10(abs(Diff) / maxViolation + 1e-150)))
where
Diff = 1 - (info_user+1e-8)/(info_numerical + 1e-8) 
"""
from numpy import *
from DerApproximator import *
 
func = lambda x: (x**4).sum()
func_d = lambda x: 40 * x**3
x = arange(1.0, 6.0)
r = check_d1(func, func_d, x)
 
func = lambda x: x**4
func_d = lambda x: 40 * diag(x**3)
x = arange(1.0, 6.0)
r = check_d1(func, func_d, x)

Expected output:

func num         user-supplied     numerical               RD
    0             +4.000e+01     +4.000e+00              3
    1             +3.200e+02     +3.200e+01              3
    2             +1.080e+03     +1.080e+02              3
    3             +2.560e+03     +2.560e+02              3
    4             +5.000e+03     +5.000e+02              3
max(abs(d_user - d_numerical)) = 4500.00002147
(is registered in func number 4)
***************************************************************************
func num   i,j: dfunc[i]/dx[j]   user-supplied     numerical               RD
    0              0 / 0         +4.000e+01     +4.000e+00              3
    6              1 / 1         +3.200e+02     +3.200e+01              3
    12             2 / 2         +1.080e+03     +1.080e+02              3
    18             3 / 3         +2.560e+03     +2.560e+02              3
    24             4 / 4         +5.000e+03     +5.000e+02              3
max(abs(d_user - d_numerical)) = 4500.00002147
(is registered in func number 24)
***************************************************************************
Future plans
  • (500) improve get_d2 speed
  • involve parallel calculations where it's possible
  • write function check_d2
  • make get_d2 working on general f: R^n -> R^m (currently it was tested for m=1 only)
  • write higher-order derivatives get_d3, maybe more
Personal tools
    Latest OOSuite 0.38

    from 2012-03-15

    Next release:

    2012-06-15

    Development