FuncDesigner
From OpenOpt
FuncDesigner is a computer algebra system (CAS) written in Python + NumPy, that makes it cross-platform (Linux, Windows, Mac OS X etc), with completely free license: BSD.
- Enhances RAD abilities of Python language for developing scientific software, especially for numerical optimization and solving systems of linear/non-linear equations
- Perfectly stacks with NumPy arrays and other Python functions and code, thus you can connect parts of code written in C, Fortran, MATLAB etc and import/export data in formats of text, HDF5, xml/xls, weka arff, mtx, netcdf, MATLAB mat files etc (via numpy.io and scipy.io modules)
- Key feature of the framework is Automatic differentiation (AD) (not to be confused with Numerical differentiation via finite-differences derivatives approximation and symbolic differentiation provided by Maxima, SymPy etc). It seriously benefits some numerical optimization solvers. BTW, commercial tool TOMLAB / MAD for automatic differentiation costs over 4000$
- See FuncDesigner AD usage Example
from FuncDesigner import *
a, b, c = oovars('a', 'b', 'c')
f1, f2 = sin(a) + cos(b) - log2(c) + sqrt(b), sum(c) + c * cosh(b) / arctan(a) + c[0] * c[1] + c[-1] / (a * c.size)
f3 = f1*f2 + 2*a + sin(b) * (1+2*c.size + 3*f2.size)
f = 2*a*b*c + f1*f2 + f3 + dot(a+c, b+c)
point = {a:1, b:2, c:[3, 4, 5]} # however, you'd better use numpy arrays instead of Python lists
print(f(point))
print(f.D(point))
print(f.D(point, a))
print(f.D(point, [b]))
print(f.D(point, fixedVars = [a, c]))
Expected output:
[ 140.9337138 110.16255336 80.67870244]
{a: array([ 69.75779959, 88.89020412, 109.93551537]), b: array([-23.10565554, -39.41138045, -59.08378522]),
c: array([[-20.52297003, 13.03660168, 13.67886723],
[ 7.39537711, -20.15709726, 12.57210056],
[ 4.17609616, 7.14087693, -17.54104071]])}
[ 69.75779959 88.89020412 109.93551537]
{b: array([-23.10565554, -39.41138045, -59.08378522])}
{b: array([-23.10565554, -39.41138045, -59.08378522])}
- You can use "for" cycle in FuncDesigner code Example
from FuncDesigner import *
a, b, c = oovars('a', 'b', 'c')
f1, f2 = sin(a) + cos(b) - log2(c) + sqrt(b), sum(c) + c * cosh(b) / arctan(a) + c[0] * c[1] + c[-1] / (a * c.size)
f3 = f1*f2 + 2*a + sin(b) * (1+2*c.size + 3*f2.size)
F = sin(f2)*f3 + 1
M = 15
for i in range(M): F = 0.5*F + 0.4*f3*cos(f1+2*f2)
point = {a:1, b:2, c:[3, 4, 5]} # however, you'd better use numpy arrays instead of Python lists
print(F(point))
print(F.D(point))
print(F.D(point, a))
print(F.D(point, [b]))
print(F.D(point, fixedVars = [a, c]))
[ 4.63468686 0.30782902 1.21725266]
{a: array([-436.83015952, 204.25331181, 186.38788436]), b: array([ 562.63390316, -273.23484496, -256.32464645]),
c: array([[ 395.96975635, 167.24928464, 55.74976155],
[ -74.80518167, -129.34496329, -19.94804845],
[ -57.42472654, -45.93978123, -66.30049589]])}
[-436.83015952 204.25331181 186.38788436]
{b: array([ 562.63390316, -273.23484496, -256.32464645])}
{b: array([ 562.63390316, -273.23484496, -256.32464645])}
- If some your functions had been written on other languages (C, Fortran, etc), or are beyond FuncDesigner AD capabilities due to any other reason (has "for"/"while" loops, routines for solving systems of nonlinear, mb differential equations etc), you can define your own oofun with wrapper around the function, and the missing derivatives will be covered up by finite-differences derivatives approximation via DerApproximator
-
(coming) You can use operator "ifThenElse" where ordinary Python language operator if-then-else can't deal with condition because it has type oofun (that hasn't been invoked on a point yet and thus preliminary unknown) instead of boolean Example
from FuncDesigner import *
a, b = oovars('a', 'b')
point = {a:10, b:[2, -5, -4]}
f1 = ifThenElse(a+sum(b)<1, 3*a, 15*(a+5/b[0]))
f2 = 4*sin(a) + 5 * ifThenElse(a+sum(abs(b))>1, 3, 4*a)
f3 = 15 + 25 * ifThenElse(2>1, -100, 3*sum(log2(abs(b))))
f4 = 15 + 25 * ifThenElse(1>2, -100, 3*sum(log2(abs(b))))
for f in [f1, f2, f3, f4]: print(f(point))
for f in [f1, f2, f3, f4]: print(f.D(point))
[ 187.5]
[ 12.82391556]
[-2485]
[ 414.14460712]
{a: array([ 15.]), b: array([-18.75, -0. , -0. ])}
{a: array([-3.35628612])}
{}
{b: array([ 54.10106403, -21.64042561, -27.05053202])}
- If your condition has type boolean when Python loads it (for example when you have "if myOOFun(startPoint)"), then you can use ordinary python if-elif-...-then-else in spite of type of other data involved
- You can solve systems of linear equations (SLE), dense and sparse (examples)
- You can solve systems of non-linear equations (examples)
- FuncDesigner as well as DerApproximator was excluded from OpenOpt framework as independent Python module.
OpenOpt can optimize FuncDesigner models with no needs to provide 1st derivatives Example
from FuncDesigner import *
from openopt import NLP
a, b, c = oovars('a', 'b', 'c')
f = sum(a*[1, 2])**2+b**2+c**2
startPoint = {a:[100, 12], b:2, c:40} # however, you'd better use numpy arrays instead of Python lists
p = NLP(f, startPoint)
p.constraints = [(2*c+a-10)**2 < 1.5 + 0.1*b, (a-10)**2<1.5, a[0]>8.9, a+b > [ 7.97999836, 7.8552538 ], \
a < 9, (c-2)**2 < 1, b < -1.02, c > 1.01, ((b + c * log10(a).sum() - 1) ** 2).eq(0)]
r = p.solve('ralg')
print r.xf
Expected output:
...
objFunValue: 717.75631 (feasible, max constraint = 7.44605e-07)
{a: array([ 8.99999792, 8.87525277]), b: array([-1.01999971]), c: array([ 1.0613562])}
| Made by Dmitrey |
See also:
- FuncDesigner documentation (also it includes some more optimization examples for LP, MILP, NSP, LLSP etc)
- Download and installation instructions at our Install webpage
- FuncDesigner linux.softpedia.com entry
- DerApproximator


