pax_global_header00006660000000000000000000000064117577575050014535gustar00rootroot0000000000000052 comment=8f6e10595ffe24e02428880adafdc99ac43d006f openopt-0.38+svn1589/000077500000000000000000000000001175775750500143045ustar00rootroot00000000000000openopt-0.38+svn1589/COPYING.txt000066400000000000000000000017731175775750500161650ustar00rootroot00000000000000Copyright (c) 2007-2009, Dmitrey Kroshko, www.icyb.kiev.ua optimization department OpenOpt Kernel license is New BSD license, allows using from both open- and closed-code software All connected solvers have their own licenses. ----------------------------------- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. openopt-0.38+svn1589/DOCUMENTATION.html000066400000000000000000000001101175775750500171730ustar00rootroot00000000000000 openopt-0.38+svn1589/INSTALL.txt000066400000000000000000000016761175775750500161650ustar00rootroot00000000000000Do you have any problems with installation for Linux, MS Windows, MacOS? Check webpage http://openopt.org/Install Installation (very briefly, link above leads to more precize): 1. Ensure you have Python (v >= 2.5 is recommended), numpy (v >= 1.1.0 is recommended) and setuptools installed. You can use Linux software channels, like this for Debian/*UBUNTU: [sudo] aptitude install python-numpy [sudo] aptitude install python-setuptools (Linux OSes already have Python installed) # optional, for graphics output: [sudo] aptitude install python-matplotlib # optional packages that may be present in software channels: # python-scipy, python-cvxopt, some others All optional packages and/or solvers could be installed after OO installation, when they will be required for the tasks involved. 2. [sudo] python setup.py install or [sudo] python setup.py develop 3. To check installation you could try running "python nlp_1.py" from /examples directory openopt-0.38+svn1589/README.txt000066400000000000000000000007211175775750500160020ustar00rootroot00000000000000openopt license: BSD openopt usage: from openopt import * #and then see help(NLP), help(LP), help(QP) # ... etc See also directory "examples", using on-line documentation is highly recommended: http://openopt.org/Doc See also: OpenOpt homepage: http://openopt.org New! Numerical optimization forum: http://forum.openopt.org/ Found OpenOpt useful? Please mention it in our guestbook http://forum.openopt.org/viewforum.php?id=11 Regards, OpenOpt developers openopt-0.38+svn1589/openopt/000077500000000000000000000000001175775750500157705ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/__init__.py000066400000000000000000000021371175775750500201040ustar00rootroot00000000000000#! /usr/bin/env python #from .ooVersionNumber import __version__ import os, sys curr_dir = ''.join([elem + os.sep for elem in __file__.split(os.sep)[:-1]]) sys.path += [curr_dir, curr_dir + 'kernel'] from ooVersionNumber import __version__ from oo import * #from kernel.GUI import manage #from kernel.oologfcn import OpenOptException #from kernel.nonOptMisc import oosolver from GUI import manage from oologfcn import OpenOptException from nonOptMisc import oosolver from mfa import MFA isE = False try: import enthought isE = True except ImportError: pass try: import envisage import mayavi isE = True except ImportError: pass try: import xy isE = False except ImportError: pass if isE: s = """ Seems like you are using OpenOpt from commercial Enthought Python Distribution; consider using free GPL-licensed alternatives PythonXY (http://www.pythonxy.com) or Sage (http://sagemath.org) instead. """ print(s) #__all__ = filter(lambda s:not s.startswith('_'),dir()) #from numpy.testing import NumpyTest #test = NumpyTest().test openopt-0.38+svn1589/openopt/doc/000077500000000000000000000000001175775750500165355ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/doc/DOCUMENTATION.html000066400000000000000000000001101175775750500214240ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/doc/badlyScaled.py000066400000000000000000000045161175775750500213240ustar00rootroot00000000000000from numpy import * from openopt import * coeff = 1e-7 f = lambda x: (x[0]-20)**2+(coeff * x[1] - 80)**2 # objFun c = lambda x: (x[0]-14)**2-1 # non-lin ineq constraint(s) c(x) <= 0 # for the problem involved: f_opt =25, x_opt = [15.0, 8.0e9] x0 = [-4,4] # even modification of stop criteria can't help to achieve the desired solution: someModifiedStopCriteria = {'gtol': 1e-15, 'ftol': 1e-13, 'xtol': 1e-13, 'maxIter': 1e3} # using default diffInt = 1e-7 is inappropriate: p = NLP(f, x0, c=c, iprint = 100, **someModifiedStopCriteria) r = p.solve('ralg') print r.ff, r.xf # will print something like "6424.9999886000014 [ 15.0000005 4. ]" """ for to improve the solution we will use changing either p.diffInt from default 1e-7 to [1e-7, 1] or p.scale from default None to [1, 1e-7] latter (using p.scale) is more recommended because it affects xtol for those solvers who use OO stop criteria (ralg, lincher, nsmm, nssolve and mb some others) xtol will be compared to scaled x shift: is || (x[k] - x[k-1]) * scale || < xtol You can define scale and diffInt as numpy arrays, matrices, Python lists, tuples """ p = NLP(f, x0, c=c, scale = [1, coeff], iprint = 100, **someModifiedStopCriteria) r = p.solve('ralg') print r.ff, r.xf # "24.999996490694787 [ 1.50000004e+01 8.00004473e+09]" - much better """ Full Output: ----------------------------------------------------- solver: ralg problem: unnamed goal: minimum iter objFunVal log10(maxResidual) 0 6.976e+03 2.51 51 6.425e+03 -6.10 istop: 4 (|| F[k] - F[k-1] || < ftol) Solver: Time Elapsed = 0.16 CPU Time Elapsed = 0.16 objFunValue: 6424.9999 (feasible, max constraint = 8e-07) 6424.999932 [ 15.0000004 4. ] ----------------------------------------------------- solver: ralg problem: unnamed goal: minimum iter objFunVal log10(maxResidual) 0 6.976e+03 2.51 100 4.419e+01 -5.99 200 2.504e+01 -6.10 300 2.503e+01 -6.10 400 2.503e+01 -6.10 500 2.503e+01 -6.10 506 2.500e+01 -6.91 istop: 3 (|| X[k] - X[k-1] || < xtol) Solver: Time Elapsed = 1.59 CPU Time Elapsed = 1.59 objFunValue: 25.000189 (feasible, max constraint = 1.23911e-07) 25.0001894297 [ 1.50000001e+01 8.00137858e+08] """ openopt-0.38+svn1589/openopt/doc/checkDerivatives.py000066400000000000000000000052071175775750500223760ustar00rootroot00000000000000from openopt import NLP from numpy import cos, arange, ones, asarray, abs, zeros N = 30 M = 5 ff = lambda x: ((x-M)**2).sum() p = NLP(ff, cos(arange(N))) def df(x): r = 2*(x-M) r[0] += 15 #incorrect derivative r[8] += 80 #incorrect derivative return r p.df = df p.c = lambda x: [2* x[0] **4-32, x[1]**2+x[2]**2 - 8] def dc(x): r = zeros((2, p.n)) r[0,0] = 2 * 4 * x[0]**3 r[1,1] = 2 * x[1] r[1,2] = 2 * x[2] + 15 #incorrect derivative return r p.dc = dc p.h = lambda x: (1e1*(x[-1]-1)**4, (x[-2]-1.5)**4) def dh(x): r = zeros((2, p.n)) r[0,-1] = 1e1*4*(x[-1]-1)**3 r[1,-2] = 4*(x[-2]-1.5)**3 + 15 #incorrect derivative return r p.dh = dh p.checkdf() p.checkdc() p.checkdh() """ you can use p.checkdF(x) for other point than x0 (F is f, c or h) p.checkdc(myX) or p.checkdc(x=myX) values with difference greater than maxViolation (default 1e-5) will be shown p.checkdh(maxViolation=1e-4) p.checkdh(myX, maxViolation=1e-4) p.checkdh(x=myX, maxViolation=1e-4) ################################################################################# Typical output (unfortunately, in terminal or other IDEs the blank space used in strings separation can have other lengths): Note that 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) OpenOpt checks user-supplied gradient df (shape: (30,) ) according to: prob.diffInt = [ 1.00000000e-07] |1 - info_user/info_numerical| <= prob.maxViolation = 0.01 df num user-supplied numerical RD 0 +7.000e+00 -8.000e+00 3 8 -2.291e+00 -1.029e+01 2 max(abs(df_user - df_numerical)) = 14.9999995251 (is registered in df number 0) ======================== OpenOpt checks user-supplied gradient dc (shape: (2, 30) ) according to: prob.diffInt = [ 1.00000000e-07] |1 - info_user/info_numerical| <= prob.maxViolation = 0.01 dc num i,j:dc[i]/dx[j] user-supplied numerical RD 32 1 / 2 +1.417e+01 -8.323e-01 4 max(abs(dc_user - dc_numerical)) = 14.9999999032 (is registered in dc number 32) ======================== OpenOpt checks user-supplied gradient dh (shape: (2, 30) ) according to: prob.diffInt = [ 1.00000000e-07] |1 - info_user/info_numerical| <= prob.maxViolation = 0.01 dh num i,j:dh[i]/dx[j] user-supplied numerical RD 58 1 / 28 -4.474e+01 -5.974e+01 2 max(abs(dh_user - dh_numerical)) = 14.9999962441 (is registered in dh number 58) ======================== """ openopt-0.38+svn1589/openopt/doc/lpToMPS.py000066400000000000000000000021571175775750500204120ustar00rootroot00000000000000# Example of export OpenOpt LP to MPS file # you should have lpsolve and its Python binding properly installed # (you may take a look at the instructions from openopt.org/LP) # You can solve problems defined in MPS files # with a variety of solvers at NEOS server for free # http://neos.mcs.anl.gov/ # BTW they have Python API along with web API and other from numpy import * from openopt import LP f = array([15,8,80]) A = mat('1 2 3; 8 15 80; 8 80 15; -100 -10 -1') # numpy.ndarray is also allowed b = [15, 80, 150, -800] # numpy.ndarray, matrix etc are also allowed Aeq = mat('80 8 15; 1 10 100') # numpy.ndarray is also allowed beq = (750, 80) lb = [4, -80, -inf] ub = [inf, -8, inf] p = LP(f, A=A, Aeq=Aeq, b=b, beq=beq, lb=lb, ub=ub, name = 'lp_1') # or p = LP(f=f, A=A, Aeq=Aeq, b=b, beq=beq, lb=lb, ub=ub) # if file name not ends with '.MPS' or '.mps' # then '.mps' will be appended success = p.exportToMPS('asdf') # success is False if a error occurred (read-only file system, no write access, etc) # elseware success is True # objFunValue should be 204.48841578 # x_opt should be [ 9.89355041 -8. 1.5010645 ] openopt-0.38+svn1589/openopt/doc/milpToMPS.py000066400000000000000000000023551175775750500207400ustar00rootroot00000000000000# Example of export OpenOpt MILP to MPS file # you should have lpsolve and its Python binding properly installed # (you may take a look at the instructions from openopt.org/LP) # You can solve problems defined in MPS files # with a variety of solvers at NEOS server for free # http://neos.mcs.anl.gov/ # BTW they have Python API along with web API and other from numpy import * from openopt import MILP f = [1, 2, 3, 4, 5, 4, 2, 1] # indexing starts from ZERO! # while in native lpsolve-python wrapper from 1 # so if you used [5,8] for native lp_solve python binding # you should use [4,7] instead intVars = [4, 7] lb = -1.5 * ones(8) ub = 15 * ones(8) A = zeros((5, 8)) b = zeros(5) for i in xrange(5): for j in xrange(8): A[i,j] = -8+sin(8*i) + cos(15*j) b[i] = -150 + 80*sin(80*i) p = MILP(f=f, lb=lb, ub=ub, A=A, b=b, intVars=intVars) # if file name not ends with '.MPS' or '.mps' # then '.mps' will be appended success = p.exportToMPS('/home/dmitrey/PyTest/milp_1') # or write into current dir: # success = p.exportToMPS('milp') # success is False if a error occurred (read-only file system, no write access, etc) # elseware success is True # f_opt is 25.801450769161505 # x_opt is [ 15. 10.15072538 -1.5 -1.5 -1. -1.5 -1.5 15.] openopt-0.38+svn1589/openopt/doc/oosolver.py000066400000000000000000000014071175775750500207610ustar00rootroot00000000000000""" The example illustrates oosolver usage You should pay special attention for "isInstalled" field oosolver work is untested for converters """ from openopt import oosolver, NLP ipopt = oosolver('ipopt', color='r') # oosolver can hanlde prob parameters ralg = oosolver('ralg', color='k', alp = 4.0) # as well as solver parameters asdf = oosolver('asdf') solvers = [ralg, asdf, ipopt] # or just # solvers = [oosolver('ipopt', color='r'), oosolver('asdf'), oosolver('ralg', color='k', alp = 4.0)] for solver in solvers: if not solver.isInstalled: print 'solver ' + solver.__name__ + ' is not installed' continue p = NLP(x0 = 15, f = lambda x: x**4, df = lambda x: 4 * x**3, iprint = 0) r = p.solve(solver, plot=1, show = solver == solvers[-1]) openopt-0.38+svn1589/openopt/doc/probAssign.py000066400000000000000000000030111175775750500212110ustar00rootroot00000000000000# Problem assignment in OpenOpt is performed in the following way: from openopt import NLP # or other constructor names: LP, MILP, QP etc, # for full list see http://openopt.org/Problems # p = NLP(*args, **kwargs) """ you should read help(NLP) for more details, also reading /examples/nlp_1.py and other files from the directory is highly recommended Each class has some expected arguments e.g. for NLP it's f and x0 - objective function and start point thus using NLP(myFunc, myStartPoint) will assign myFunc to f and myStartPoint to x0 prob fields alternatively, you could use it as kwargs, possibly along with some other kwargs: """ p = NLP(x0=15, f = lambda x: x**2-0.4, df = lambda x: 2*x, iprint = 0, plot = 1) # after the problem is assigned, you could turn the parameters, # along with some other that have been set as defaults: p.x0 = 0.15 p.plot = 0 def f(x): return x if x>0 else x**2 p.f = f # At last, you can modify any prob parameters in minimize/maximize/solve/manage functions: r = p.minimize('ralg', x0 = -1.5, iprint = -1, plot = 1, color = 'r') # or #r = p.manage('ralg', start = False, iprint = 0, x0 = -1.5) """ Note that *any* kwarg passed to constructor will be assigned e.g. p = NLP(f, x0, myName='JohnSmith') is equivalent to p.myName='JohnSmith' It can be very convenient for user-supplied callback functions (see /examples/userCallback.py) (instead of using "global" as you have to do in MATLAB) See also http://openopt.org/OOFrameworkDoc#Result_structure for result structure (r) fields """ openopt-0.38+svn1589/openopt/doc/restricted_dom.py000066400000000000000000000021001175775750500221070ustar00rootroot00000000000000 """ Some non-linear functions have much more restricted dom than R^nVars. For example F(x) = log(x); dom F = R+ = {x: x>0} For optimization solvers it is wont to expect user-povided F(x) = nan if x is out of dom. I can't inform how successfully OO-connected solvers will handle a prob instance with restricted dom because it seems to be too prob-specific Still I can inform that ralg handles the problems rather well provided in every point x from R^nVars at least one ineq constraint is active (i.e. value constr[i](x) belongs to R+) Note also that some solvers require x0 inside dom objFunc. For ralg it doesn't matter. """ from numpy import * from openopt import NLP n = 100 an = arange(n) # array [0, 1, 2, ..., n-1] x0 = n+15*(1+cos(an)) f = lambda x: (x**2).sum() + sqrt(x**3).sum() df = lambda x: 2*x + 1.5*x**0.5 lb = zeros(n) solvers = ['ralg'] #solvers = ['ipopt'] for solver in solvers: p = NLP(f, x0, df=df, lb=lb, xtol = 1e-6, iprint = 50, maxIter = 10000, maxFunEvals = 1e8) #p.checkdf() r = p.solve(solver) # expected r.xf = small values near zero openopt-0.38+svn1589/openopt/doc/solverParams.py000066400000000000000000000016371175775750500215740ustar00rootroot00000000000000""" Modifying of some solver default parameters is performed via either kwargs for p.solve() (they can be solver or prob attributes) or using oosolver (see examples/oosolver.py for more details). """ from numpy import * from openopt import * f = lambda x: (x[0]-1.5)**2 + sin(0.8 * x[1] ** 2 + 15)**4 + cos(0.8 * x[2] ** 2 + 15)**4 + (x[3]-7.5)**4 lb, ub = -ones(4), ones(4) # example 1 p = GLP(f, lb=lb, ub=ub, maxIter = 1e3, maxCPUTime = 3, maxFunEvals=1e5, fEnough = 80) # solve() kwargs can include some prob settings (like maxTime) as well r = p.solve('galileo', crossoverRate = 0.80, maxTime = 3, population = 15, mutationRate = 0.15) # example 2, via oosolver solvers = [oosolver('ralg', h0 = 0.80, alp = 2.15, show = False), oosolver('ralg', h0 = 0.15, alp = 2.80, color = 'k')] for i, solver in enumerate(solvers): p = NSP(f, [0]*4, lb=lb, ub=ub, legend='ralg'+str(i+1)) r = p.solve(solver, plot=True) openopt-0.38+svn1589/openopt/doc/textOutput.py000066400000000000000000000020311175775750500213100ustar00rootroot00000000000000""" You can manage text output in OpenOpt via the following prob parameters: Prob field name default value iprint 10 iterObjFunTextFormat '%0.3e' finalObjFunTextFormat '%0.8g' iprint: do text output each iprint-th iteration You can use iprint = 0 for final output only or iprint < 0 to omit whole output In future warnings are intended to be shown if iprint >= -1. However, some solvers like ALGENCAN have their own text output system, that's hard to suppress, it requires using different approach like, for example, http://permalink.gmane.org/gmane.comp.python.scientific.user/15465 iterObjFunTextFormat: how iter output objFun values are represented for example, '%0.3e' yields lines like iter objFunVal 0 1.947e+03 10 1.320e+03 ... finalObjFunTextFormat: how final output objFun value is represented for example finalObjFunTextFormat='%0.1f' yields ... objFunValue: 7.9 See Python language documentation for text format specification. """ openopt-0.38+svn1589/openopt/doc/userArgs.py000066400000000000000000000024651175775750500207110ustar00rootroot00000000000000""" Example of using additional parameters for user f, c, h functions Note! For oofun handling user parameters is performed in the same way: my_oofun.args = (...) they will be passed to derivative function as well (if you have supplied it) """ from openopt import NLP from numpy import asfarray f = lambda x, a: (x**2).sum() + a * x[0]**4 x0 = [8, 15, 80] p = NLP(f, x0) #using c(x)<=0 constraints p.c = lambda x, b, c: (x[0]-4)**2 - 1 + b*x[1]**4 + c*x[2]**4 #using h(x)=0 constraints p.h = lambda x, d: (x[2]-4)**2 + d*x[2]**4 - 15 p.args.f = 4 # i.e. here we use a=4 # so it's the same to "a = 4; p.args.f = a" or just "p.args.f = a = 4" p.args.c = (1,2) p.args.h = 15 # Note 1: using tuple p.args.h = (15,) is valid as well # Note 2: if all your funcs use same args, you can just use # p.args = (your args) # Note 3: you could use f = lambda x, a: (...); c = lambda x, a, b: (...); h = lambda x, a: (...) # Note 4: if you use df or d2f, they should handle same additional arguments; # same to c - dc - d2c, h - dh - d2h # Note 5: instead of myfun = lambda x, a, b: ... # you can use def myfun(x, a, b): ... r = p.solve('ralg') """ If you will encounter any problems with additional args implementation, you can use the simple python trick p.f = lambda x: other_f(x, ) same to c, h, df, etc """ openopt-0.38+svn1589/openopt/doc/userCallback.py000066400000000000000000000106451175775750500215100ustar00rootroot00000000000000""" usage: p = someOOclass(..., callback=MyIterFcn, ...) or p = ... p.callback = MyIterFcn or p.callback = (MyIterFcn1, MyIterFcn2, MyIterFcn3, ..., MyIterFcnN) or p.callback = [MyIterFcn1, MyIterFcn2, MyIterFcn3, ..., MyIterFcnN] each user-defined function MyIterFunc should return one of the following: 1. a flag value - 0, 1, True, False flag = True or 1 means user want to stop calculations (r.istop=80, r.msg = 'user-defined' ) 2. someRealValue like 15 or 80.15 or 1.5e4 (r.istop=someRealValue, r.msg = 'user-defined') 3. Python list (or tuple) - [istop, msg] (r.istop=istop, r.msg=msg) works for ralg and lincher, but may doesn't work for some other solvers (like scipy_cobyla, that has neither native callback nor call gradient) """ def MyIterFcn(p): # observing non-feasible ralg iter points if p.rk > p.contol: # p.rk is current iter max residual print '--= non-feasible ralg iter =--' print 'itn:', p.iter #however, I inted to change p.iter to p.iter in OpenOpt code soon print 'curr f:', p.fk # print 'curr x[:8]:', p.xk[:8] print 'max constraint value', p.rk """ BTW you can store data in any unique field of p for example if some_cond: p.JohnSmith = 15 else: p.JohnSmith = 0 However, special field "user" is intended for the purpose: p.user.mydata1 = (something) # or, for another example: if p.iter == 0: p.user.mylist = [] p.user.mylist.append(something) """ if p.fk < 1.5 and p.rk < p.contol: #NB! you could use p.fEnough = 15, p.contol=1e-5 in prob assignment instead return (15, 'value obtained is enough' ) # or # return 15 (hence r.istop=15, r.msg='user-defined') # or return True (hence r.istop=80, r.msg='user-defined') # or return 1 (hence r.istop = 80, r.msg='user-defined') else: return False # or # return 0 from openopt import NSP from numpy import cos, asfarray, arange, sign N = 75 f = lambda x: sum(1.2 ** arange(len(x)) * abs(x)) df = lambda x: 1.2 ** arange(len(x)) * sign(x) x0 = cos(1+asfarray(range(N))) #non-linear constraint c(x) <= 0: c = lambda x: abs(x[4]-0.8) + abs(x[5]-1.5) - 0.015 p = NSP(f, x0, df=df, c=c, callback=MyIterFcn, contol = 1e-5, maxIter = 1e4, iprint = 100, xtol = 1e-8, ftol = 1e-8) #optional: #p.plot = 1 r = p.solve('ralg') print r.xf[:8] """ ----------------------------------------------------- solver: ralg problem: unnamed goal: minimum iter objFunVal log10(maxResidual) 0 2.825e+06 0.02 --= non-feasible ralg iter =-- itn: 0 curr f: [ 2824966.83813157] max constraint value 1.04116752789 --= non-feasible ralg iter =-- itn: 1 curr f: [ 2824973.2896607] max constraint value 1.75725959686 --= non-feasible ralg iter =-- itn: 2 curr f: [ 2824966.83813157] max constraint value 1.04116752789 --= non-feasible ralg iter =-- itn: 3 curr f: [ 2824970.22518437] max constraint value 0.413756712605 --= non-feasible ralg iter =-- itn: 4 curr f: [ 2824969.02632034] max constraint value 0.0818395397163 --= non-feasible ralg iter =-- itn: 5 curr f: [ 2824969.37414607] max constraint value 0.0406513995891 --= non-feasible ralg iter =-- itn: 6 curr f: [ 2824969.20023321] max constraint value 0.00849187556755 --= non-feasible ralg iter =-- itn: 7 curr f: [ 2824969.20119103] max constraint value 0.00560799704173 --= non-feasible ralg iter =-- itn: 8 curr f: [ 2824969.2065267] max constraint value 0.00416641026253 --= non-feasible ralg iter =-- itn: 9 curr f: [ 2824969.22185181] max constraint value 0.0421905566026 --= non-feasible ralg iter =-- itn: 10 curr f: [ 2824969.2065267] max constraint value 0.00416641026253 --= non-feasible ralg iter =-- itn: 11 curr f: [ 2824969.20952515] max constraint value 0.00327175155207 100 2.665e+04 -100.00 200 4.845e+03 -100.00 300 1.947e+02 -100.00 400 9.298e+01 -100.00 500 5.160e+01 -100.00 600 2.600e+01 -100.00 700 1.070e+01 -100.00 800 6.994e+00 -100.00 900 5.375e+00 -100.00 1000 5.375e+00 -100.00 1094 5.375e+00 -100.00 istop: 4 (|| F[k] - F[k-1] || < ftol) Solver: Time Elapsed = 4.62 CPU Time Elapsed = 4.48 objFunValue: 5.3748608 (feasible, max constraint = 0) [ -1.06086135e-07 5.65437885e-08 -1.29682567e-07 6.12571176e-09 7.95256506e-01 1.49731951e+00 -1.42518171e-09 4.15961658e-08] """ openopt-0.38+svn1589/openopt/examples/000077500000000000000000000000001175775750500176065ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/examples/GUI_1.py000066400000000000000000000020431175775750500210230ustar00rootroot00000000000000""" OpenOpt GUI: function manage() usage example """ from openopt import NLP, manage from numpy import cos, arange, ones, asarray, abs, zeros N = 50 M = 5 p = NLP(lambda x: ((x-M)**2).sum(), cos(arange(N))) p.lb, p.ub = -6*ones(N), 6*ones(N) p.lb[3] = 5.5 p.ub[4] = 4.5 p.c = lambda x: [2* x[0] **4-32, x[1]**2+x[2]**2 - 8] p.h = (lambda x: 1e1*(x[-1]-1)**4, lambda x: (x[-2]-1.5)**4) """ minTime is used here for to provide enough time for user to play with GUI """ minTime = 1.5 # sec p.name = 'GUI_example' p.minTime = minTime """ hence maxIter, maxFunEvals etc will not trigger till minTime only same iter point x_k-1=x_k or some coords = nan can stop calculations other antistop criteria: minFunEvals, minIter, minCPUTime however, some solvers cannot handle them """ # start=True means don't wait for user to press "Run" r = manage(p,'ralg', plot=1, start=True) """ or calling manage() as filed of p: r = p.manage('algencan', plot=1) """ if r is not None: # r is None if user has pressed "Exit" button print 'objfunc val:', r.ff openopt-0.38+svn1589/openopt/examples/__init__.py000066400000000000000000000000011175775750500217060ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/examples/dfp_1.py000066400000000000000000000024661175775750500211610ustar00rootroot00000000000000""" In the DFP example we will search for z=(a, b, c, d) that minimizes Sum_i || F(z, X_i) - Y_i ||^2 for the function F(x0, x1) = a^3 + b * x0 + c * x1 + d * (x0^2+x1^2) Suppose we have the following measurements X_0 = [0, 1]; Y_0 = 15 X_1 = [1, 0]; Y_1 = 8 X_2 = [1, 1]; Y_2 = 80 X_3 = [3, 4]; Y_3 = 100 X_4 = [1, 15]; Y_4 = 150 subjected to a>=4, c<=30 (we could handle other constraints as well: Ax <= b, Aeq x = beq, c(x) <= 0, h(x) = 0) """ from openopt import DFP from numpy import inf f = lambda z, X: z[0]**3 + z[1]*X[0] + z[2]*X[1] + z[3]*(X[0]+X[1])**2 initEstimation = [0] * 4 # start point for solver: [0, 0, 0, 0] X = ([0, 1], [1, 0], [1, 1], [3, 4], [1, 15]) # list, tuple, numpy array or array-like are OK as well Y = [15, 8, 80, 100, 150] lb = [4, -inf, -inf, -inf] ub = [inf, inf, 30, inf] p = DFP(f, initEstimation, X, Y, lb=lb, ub=ub) # optional: derivative p.df = lambda z, X: [3*z[0]**2, X[0], X[1], (X[0]+X[1])**2] r = p.solve('nlp:ralg', plot=0, iprint = 10) print('solution: '+str(r.xf)+'\n||residuals||^2 = '+str(r.ff)+'\nresiduals: '+str([f(p.xf, X[i])-Y[i] for i in xrange(len(Y))])) #solution: [ 3.99999936 5.99708861 -12.25696614 1.04221073] #||residuals||^2 = 5992.63887806 #residuals: [37.785213926923028, 63.039268675751572, -18.091065285780857, -15.968303801844399, 2.9485118103557397] openopt-0.38+svn1589/openopt/examples/dfp_2.py000066400000000000000000000033021175775750500211500ustar00rootroot00000000000000""" In the DFP example we will search for z=(a, b, c, d) that minimizes Sum_i || F(z, X_i) - Y_i ||^2 for the function F: R^2 -> R^2 F(x0, x1) = [ a^3 + b * x0 + c * x1 + d * (x0^2+x1^2), 2*a + 3*b * x0 + 4*c * x1 + 5*d * (x0^2+x1^2) ] Suppose we have the following measurements X_0 = [0, 1]; Y_0 = [15, 1] X_1 = [1, 0]; Y_1 = [8, 16] X_2 = [1, 1]; Y_2 = [80, 800] X_3 = [3, 4]; Y_3 = [100, 120] X_4 = [1, 15]; Y_4 = [150, 1500] subjected to a>=4, c<=30 (we could handle other constraints as well: Ax <= b, Aeq x = beq, c(x) <= 0, h(x) = 0) """ from openopt import DFP from numpy import * f = lambda z, X: (z[0]**3 + z[1]*X[0] + z[2]*X[1] + z[3]*(X[0]+X[1])**2, 2*z[0] + 3*z[1]*X[0] + 4*z[2]*X[1] + 5*z[3]*(X[0]+X[1])**2) initEstimation = [0] * 4 # start point for solver: [0, 0, 0, 0] X = ([0, 1], [1, 0], [1, 1], [3, 4], [1, 15]) # list, tuple, numpy array or array-like are OK as well Y = [[15, 1], [8, 16], [80, 800], [100, 120], [150, 1500]] lb = [4, -inf, -inf, -inf] ub = [inf, inf, 30, inf] p = DFP(f, initEstimation, X, Y, lb=lb, ub=ub) # optional: derivatives #p.df = lambda z, X: ([3*z[0]**2, X[0], X[1], (X[0]+X[1])**2], [2, 3*X[0], 4*X[1], 5*(X[0]+X[1])**2]) r = p.solve('nlp:ralg', plot=1, iprint = 10) print('solution: '+str(r.xf)+'\n||residuals||^2 = '+str(r.ff)+'\nresiduals: ') rr = [array(f(p.xf, X[i]))-array(Y[i]) for i in xrange(len(Y))] print rr #solution: [ 3.99999936 -1.9497013 18.25467922 0.24926213] #||residuals||^2 = 653639.695247 #residuals: #[array([ 67.50391074, 81.26502627]), array([ 54.29953022, -12.60279452]), array([ 1.30199584, -719.84514565]), array([ 43.38342685, 223.59677693]), array([ 249.68156224, -83.51282276])] openopt-0.38+svn1589/openopt/examples/eig_1.py000066400000000000000000000020211175775750500211370ustar00rootroot00000000000000from openopt import EIG # create a 5 x 5 matrix import numpy.random as nr nr.seed(0) N = 5 A = nr.rand(N, N) #define prob p = EIG(A, goal = {'lm':3}) # search for 3 eigenvalues of largest magnitude # or goal={'largest magnitude':3}, with or without space inside, case-insensitive # for whole list of available goals see http://openopt.org/EIG #solve r = p.solve('arpack') # arpack is name of the involved solver print(r.eigenvalues) # [ 0.14607289-0.19602952j -0.65372843+0.j 2.89776724+0.j ] # for i-th eigenvalue r.eigenvectors[:,i] is corresponding vector, # as well as it is done for numpy/scipy functions print(r.eigenvectors) ''' [[-0.10391145-0.56334829j 0.19592536+0.j 0.43733688+0.j ] [-0.20999235+0.1812288j -0.03219327+0.j 0.49662623+0.j ] [-0.21334642+0.21648181j -0.55544796+0.j 0.42977207+0.j ] [ 0.34828527+0.36295959j 0.62338178+0.j 0.38727512+0.j ] [ 0.04820760-0.49714496j -0.51327338+0.j 0.47687818+0.j ]] ''' openopt-0.38+svn1589/openopt/examples/eig_2.py000066400000000000000000000022421175775750500211450ustar00rootroot00000000000000# An example of OpenOpt EIG, see http://openopt.org/EIG for more examples and details from openopt import EIG # create a 5 x 5 matrix import numpy.random as nr nr.seed(0) N = 5 A = nr.rand(N, N) #define prob p = EIG(A) #solve r = p.solve('numpy_eig') # solver numpy.linalg.eig will be used print(r.eigenvalues) # [ 2.89776724+0.j -0.65372843+0.j 0.14607289+0.19602952j 0.14607289-0.19602952j -0.08530815+0.j] # for i-th eigenvalue r.eigenvectors[:,i] is corresponding vector, # as well as it is done for numpy/scipy functions print(r.eigenvectors) ''' [[ 0.43733688+0.j -0.19592536+0.j 0.57285154+0.j 0.57285154+0.j 0.63764724+0.j ] [ 0.49662623+0.j 0.03219327+0.j -0.14013112+0.23938241j -0.14013112-0.23938241j -0.53642409+0.j ] [ 0.42977207+0.j 0.55544796+0.j -0.17419089+0.24907549j -0.17419089-0.24907549j 0.29171743+0.j ] [ 0.38727512+0.j -0.62338178+0.j -0.42011495-0.27666898j -0.42011495+0.27666898j -0.45403266+0.j ] [ 0.47687818+0.j 0.51327338+0.j 0.48015310-0.13758665j 0.48015310+0.13758665j 0.12004364+0.j ]] ''' openopt-0.38+svn1589/openopt/examples/glp_1.py000066400000000000000000000006211175775750500211610ustar00rootroot00000000000000from openopt import GLP from numpy import * f = lambda x: (x[0]-1.5)**2 + sin(0.8 * x[1] ** 2 + 15)**4 + cos(0.8 * x[2] ** 2 + 15)**4 + (x[3]-7.5)**4 p = GLP(f, lb = -ones(4), ub = ones(4), maxIter = 1e3, maxFunEvals = 1e5, maxTime = 3, maxCPUTime = 3) #optional: graphic output #p.plot = 1 or p.solve(..., plot=1) or p = GLP(..., plot=1) r = p.solve('de', plot=1) x_opt, f_opt = r.xf, r.ff openopt-0.38+svn1589/openopt/examples/glp_2.py000066400000000000000000000006141175775750500211640ustar00rootroot00000000000000from openopt import GLP from numpy import * f = lambda x: (x[0]-1.5)**2 + sin(0.8 * x[1] ** 2 + 15)**4 + cos(0.8 * x[2] ** 2 + 15)**4 + (x[3]-7.5)**4 p = GLP(f, lb = -ones(4), ub = ones(4), maxIter = 1e3, maxFunEvals = 1e5, maxTime = 3, maxCPUTime = 3) #optional: graphic output #p.plot = 1 r = p.solve('pswarm', x0=[0, 0, 0, 0], plot=0, debug=1, maxIter=200) x_opt, f_opt = r.xf, r.ff openopt-0.38+svn1589/openopt/examples/glp_3.py000066400000000000000000000005051175775750500211640ustar00rootroot00000000000000from openopt import GLP from numpy import * N = 100 aN = arange(N) f = lambda x: ((x-aN)**2).sum() p = GLP(f, lb = -ones(N), ub = N*ones(N), maxIter = 1e3, maxFunEvals = 1e5, maxTime = 10, maxCPUTime = 300) #optional: graphic output #p.plot = 1 r = p.solve('de', plot=1, debug=1, iprint=0) x_opt, f_opt = r.xf, r.ff openopt-0.38+svn1589/openopt/examples/glp_Ab_c.py000066400000000000000000000015711175775750500216520ustar00rootroot00000000000000from openopt import GLP from numpy import * # objective function # (x0 - 1.5)^2 + sin(0.8 * x1^2 + 15)^4 + cos(0.8 * x2^2 + 15)^4 + (x3 - 7.5)^4 -> min f = lambda x: (x[0]-1.5)**2 + sin(0.8 * x[1] ** 2 + 15)**4 + cos(0.8 * x[2] ** 2 + 15)**4 + (x[3]-7.5)**4 # box-bound constraints lb <= x <= ub lb, ub = -ones(4), ones(4) # linear inequality constraints # x0 + x3 <= 0.15 # x1 + x3 <= 1.5 # as Ax <= b A = mat('1 0 0 1; 0 1 0 1') # tuple, list, numpy array etc are OK as well b = [0.15, 1.5] # tuple, list, numpy array etc are OK as well # non-linear constraints # x0^2 + x2^2 <= 0.15 # 1.5 * x0^2 + x1^2 <= 1.5 c = lambda x: (x[0] ** 2 + x[2] ** 2 - 0.15, 1.5 * x[0] ** 2 + x[1] ** 2 - 1.5) p = GLP(f, lb=lb, ub=ub, A=A, b=b, c=c, maxIter = 250, maxFunEvals = 1e5, maxTime = 30, maxCPUTime = 30) r = p.solve('de', mutationRate = 0.15, plot=1) x_opt, f_opt = r.xf, r.ff openopt-0.38+svn1589/openopt/examples/lcp_1.py000066400000000000000000000030501175775750500211540ustar00rootroot00000000000000""" Example: Concider the LCP problem w = Mz + q M = array([ [0.42956806, -0.40076658, -0.02880148, -0.42956806, 0.40076658, 0.02880148], [-0.40076658, 0.47288367, -0.07211709, 0.40076658, -0.47288367, 0.07211709], [-0.02880148, -0.07211709, 0.10091857, 0.02880148, 0.07211709, -0.10091857], [-0.42956806, 0.40076658, 0.02880148, 0.42956806, -0.40076658, -0.02880148], [ 0.40076658, -0.47288367, 0.07211709, -0.40076658, 0.47288367, -0.07211709], [ 0.02880148, 0.07211709, -0.10091857, -0.02880148, -0.07211709, 0.10091857]]) q = array([1.09389333, -0.53851907, -0.05537426, -0.79389333, 0.83851907, 0.35537426]) """ from numpy import * from openopt import LCP M = array([ [0.42956806, -0.40076658, -0.02880148, -0.42956806, 0.40076658, 0.02880148], [-0.40076658, 0.47288367, -0.07211709, 0.40076658, -0.47288367, 0.07211709], [-0.02880148, -0.07211709, 0.10091857, 0.02880148, 0.07211709, -0.10091857], [-0.42956806, 0.40076658, 0.02880148, 0.42956806, -0.40076658, -0.02880148], [ 0.40076658, -0.47288367, 0.07211709, -0.40076658, 0.47288367, -0.07211709], [ 0.02880148, 0.07211709, -0.10091857, -0.02880148, -0.07211709, 0.10091857]]) q = array([1.09389333, -0.53851907, -0.05537426, -0.79389333, 0.83851907, 0.35537426]) p = LCP(M, q) r = p.solve('lcpsolve') f_opt, x_opt = r.ff, r.xf w, z = x_opt[x_opt.size/2:], x_opt[:x_opt.size/2] print('w: %s z: %s' % (w, z)) # w: [ 0. 0. 0.02167615 1.84666668 0. 0. ] z: [ 0.3 0.2 0. 0. 0.1 0.3] openopt-0.38+svn1589/openopt/examples/llavp_1.py000066400000000000000000000010151175775750500215130ustar00rootroot00000000000000from numpy import empty, sin, cos, arange, ones from openopt import LLAVP M, N = 150, 15 C = empty((M,N)) d = empty(M) for j in range(M): d[j] = 1.5*N+80*sin(j) C[j] = 8*sin(4.0+arange(N)) + 15*cos(j) lb = sin(arange(N)) ub = lb + 1 p = LLAVP(C, d, lb=lb, ub=ub, dump = 10, X = ones(N), maxIter = 1e4, maxFunEvals = 1e100) #optional: plot p.plot=1 r = p.solve('nsp:ralg', iprint = 100, maxIter = 1000) #r = p.solve('nsp:ipopt', iprint = 100, maxIter = 1000) print('f_opt: %f' % r.ff) #print 'x_opt:', r.xf openopt-0.38+svn1589/openopt/examples/llsp_1.py000066400000000000000000000012551175775750500213550ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import empty, sin, cos, arange from openopt import LLSP M, N = 1500, 1000 C = empty((M,N)) d = empty(M) for j in range(M): d[j] = 1.5*N+80*sin(j) C[j] = 8*sin(4.0+arange(N)) + 15*cos(j) """ alternatively, try the sparse problem - lsqr solver can take benefits of it. Also, if your C is too large for your RAM you can pass C of any scipy.sparse matrix format for j in xrange(M): d[j] = 1.5*N+80*sin(j) C[j, j%N] = 15*cos(j) #+ 8*sin(4.0+arange(N)) C[j, (1 + j)%N] = 15*cos(j) #+ 8*sin(4.0+arange(N)) """ p = LLSP(C, d) r = p.solve('lsqr') print('f_opt: %f' % r.ff) # 2398301.68347 #print 'x_opt:', r.xf openopt-0.38+svn1589/openopt/examples/llsp_2.py000066400000000000000000000015641175775750500213610ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import diag, ones, sin, cos, arange, sqrt, vstack, zeros, dot from openopt import LLSP, NLP N = 150 C1 = diag(sqrt(arange(N))) C2 = (1.5+arange(N)).reshape(1, -1) * (0.8+arange(N)).reshape(-1, 1) C = vstack((C1, C2)) d = arange(2*N) lb = -2.0+sin(arange(N)) ub = 5+cos(arange(N)) ############################LLSP################################ LLSPsolver = 'bvls' p = LLSP(C, d, lb=lb, ub=ub) r = p.solve(LLSPsolver) #############################NLP################################ NLPsolver = 'scipy_lbfgsb'# you could try scipy_tnc or ralg as well #NLPsolver = 'scipy_tnc' p2 = LLSP(C, d, lb=lb, ub=ub) r2=p2.solve('nlp:'+NLPsolver) ################################################################## print '###########Results:###########' print 'LLSP solver '+ LLSPsolver + ':', r.ff print 'NLP solver '+ NLPsolver + ':', r2.ff openopt-0.38+svn1589/openopt/examples/lp_1.py000066400000000000000000000023521175775750500210150ustar00rootroot00000000000000""" Example: Let's concider the problem 15x1 + 8x2 + 80x3 -> min (1) subjected to x1 + 2x2 + 3x3 <= 15 (2) 8x1 + 15x2 + 80x3 <= 80 (3) 8x1 + 80x2 + 15x3 <=150 (4) 100x1 + 10x2 + x3 >= 800 (5) 80x1 + 8x2 + 15x3 = 750 (6) x1 + 10x2 + 100x3 = 80 (7) x1 >= 4 (8) -8 >= x2 >= -80 (9) """ from numpy import * from openopt import LP f = array([15,8,80]) A = mat('1 2 3; 8 15 80; 8 80 15; -100 -10 -1') # numpy.ndarray is also allowed b = [15, 80, 150, -800] # numpy.ndarray, matrix etc are also allowed Aeq = mat('80 8 15; 1 10 100') # numpy.ndarray is also allowed beq = (750, 80) lb = [4, -80, -inf] ub = [inf, -8, inf] p = LP(f, A=A, Aeq=Aeq, b=b, beq=beq, lb=lb, ub=ub) #or p = LP(f=f, A=A, Aeq=Aeq, b=b, beq=beq, lb=lb, ub=ub) #r = p.minimize('glpk') # CVXOPT must be installed #r = p.minimize('lpSolve') # lpsolve must be installed r = p.minimize('pclp') #search for max: r = p.maximize('glpk') # CVXOPT & glpk must be installed #r = p.minimize('nlp:ralg', ftol=1e-7, xtol=1e-7, goal='min', plot=1) print('objFunValue: %f' % r.ff) # should print 204.48841578 print('x_opt: %s' % r.xf) # should print [ 9.89355041 -8. 1.5010645 ] openopt-0.38+svn1589/openopt/examples/lunp_1.py000066400000000000000000000005611175775750500213600ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import * from openopt import LUNP M, N = 1500, 150 C = empty((M,N)) d = empty(M) for j in xrange(M): d[j] = 1.5*N+80*sin(j) C[j] = 8*sin(4.0+arange(N)) + 15*cos(j) lb = sin(arange(N)) ub = lb + 1 p = LUNP(C, d, lb=lb, ub=ub) r = p.solve('lp:glpk', iprint = -1) print 'f_opt:', r.ff #print 'x_opt:', r.xf openopt-0.38+svn1589/openopt/examples/milp_1.py000066400000000000000000000013621175775750500213430ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import * from openopt import MILP f = [1, 2, 3, 4, 5, 4, 2, 1] # indexing starts from ZERO! # while in native lpsolve-python wrapper from 1 # so if you used [5,8] for native lp_solve python binding # you should use [4,7] instead intVars = [4, 7] lb = -1.5 * ones(8) ub = 15 * ones(8) A = zeros((5, 8)) b = zeros(5) for i in xrange(5): for j in xrange(8): A[i,j] = -8+sin(8*i) + cos(15*j) b[i] = -150 + 80*sin(80*i) p = MILP(f=f, lb=lb, ub=ub, A=A, b=b, intVars=intVars, goal='min') r = p.solve('lpSolve') #r = p.solve('glpk', iprint =-1) #r = p.solve('cplex') print('f_opt: %f' % r.ff) # 25.801450769161505 print('x_opt: %s' % r.xf) # [ 15. 10.15072538 -1.5 -1.5 -1. -1.5 -1.5 15.] openopt-0.38+svn1589/openopt/examples/minlp_1.py000066400000000000000000000026401175775750500215210ustar00rootroot00000000000000""" Example of MINLP It is recommended to read help(NLP) before and /examples/nlp_1.py """ from openopt import MINLP from numpy import * N = 150 K = 50 #objective function: f = lambda x: ((x-5.45)**2).sum() #optional: 1st derivatives df = lambda x: 2*(x-5.45) # start point x0 = 8*cos(arange(N)) # assign prob: # 1st arg - objective function # 2nd arg - start point # for more details see # http://openopt.org/Assignment p = MINLP(f, x0, df=df, maxIter = 1e3) # optional: set some box constraints lb <= x <= ub p.lb = [-6.5]*N p.ub = [6.5]*N # see help(NLP) for handling of other constraints: # Ax<=b, Aeq x = beq, c(x) <= 0, h(x) = 0 # see also /examples/nlp_1.py # required tolerance for smooth constraints, default 1e-6 p.contol = 1.1e-6 p.name = 'minlp_1' # required field: nlpSolver - should be capable of handling box-bounds at least #nlpSolver = 'ralg' nlpSolver = 'ipopt' # coords of discrete variables and sets of allowed values p.discreteVars = {7:range(3, 10), 8:range(3, 10), 9:[2, 3.1, 9]} # required tolerance for discrete variables, default 10^-5 p.discrtol = 1.1e-5 #optional: check derivatives, you could use p.checkdc(), p.checkdh() for constraints #p.checkdf() # optional: maxTime, maxCPUTime # p.maxTime = 15 # p.maxCPUTime = 15 r = p.solve('branb', nlpSolver=nlpSolver, plot = False) # optim point and value are r.xf and r.ff, # see http://openopt.org/OOFrameworkDoc#Result_structure for more details openopt-0.38+svn1589/openopt/examples/miqcqp_1.py000066400000000000000000000020511175775750500216700ustar00rootroot00000000000000""" Concider the MIQCQP problem 0.5 * (x1^2 + 2x2^2 + 3x3^2) + 15x1 + 8x2 + 80x3 -> min (1) subjected to x1 + 2x2 + 3x3 <= 150 (2) 8x1 + 15x2 + 80x3 <= 800 (3) x2 - x3 = 25.5 (4) x1 <= 15 (5) x1^2 + 2.5 x2^2 + 3 x3^2 + 0.1 x1 + 0.2 x2 + 0.3 x3 - 1000 <= 0 (6) 2 x1^2 + x2^2 + 3 x3^2 + 0.1 x1 + 0.5 x2 + 0.3 x3 <= 1000 (7) x1, x3 are integers """ from numpy import diag, matrix, inf from openopt import QP H = diag([1.0, 2.0,3.0]) f = [15,8,80] A = matrix('1 2 3; 8 15 80') b = [150, 800] # Qc should be list or tuple of triples (P, q, s): 0.5 x^T P x + q x + s <= 0 QC = ((diag([1.0, 2.5, 3.0]), [0.1, 0.2, 0.3], -1000), (diag([2.0, 1.0, 3.0]), [0.1, 0.5, 0.3], -1000)) p = QP(H, f, A = A, b = b, Aeq = [0, 1, -1], beq = 25.5, ub = [15,inf,inf], QC = QC, intVars = [0, 2]) # or p = QP(H=diag([1,2,3]), f=[15,8,80], ...) r = p.solve('cplex', iprint = 0, plot=1) f_opt, x_opt = r.ff, r.xf # x_opt = array([ -2.99999999, 9.5 , -16. ]) # f_opt = -770.24999989134858 openopt-0.38+svn1589/openopt/examples/miqp_1.py000066400000000000000000000012451175775750500213500ustar00rootroot00000000000000""" Example: Concider the problem 0.5 * (x1^2 + 2x2^2 + 3x3^2) + 15x1 + 8x2 + 80x3 -> min (1) subjected to x1 + 2x2 + 3x3 <= 150 (2) 8x1 + 15x2 + 80x3 <= 800 (3) x2 - x3 = 25.5 (4) x1 <= 15 (5) x1, x3 are integers """ from numpy import diag, matrix, inf from openopt import QP p = QP(diag([1, 2, 3]), [15, 8, 80], A = matrix('1 2 3; 8 15 80'), b = [150, 800], Aeq = [0, 1, -1], beq = 25.5, ub = [15,inf,inf]) # or p = QP(H=diag([1,2,3]), f=[15,8,80], A= ...) r = p.solve('cplex', intVars= [0, 2], iprint = 0) f_opt, x_opt = r.ff, r.xf # x_opt = array([-15. , -2.5, -28. ]) # f_opt = -1190.25 openopt-0.38+svn1589/openopt/examples/mmp_1.py000066400000000000000000000055021175775750500211730ustar00rootroot00000000000000""" Example of solving Mini-Max Problem via converter to NLP latter works via solving NLP t -> min subjected to t >= f0(x) t >= f1(x) ... t >= fk(x) Splitting f into separate funcs could benefit some solvers (ralg, algencan; see NLP docpage for more details) but is not implemented yet """ from numpy import * from openopt import * n = 15 f1 = lambda x: (x[0]-15)**2 + (x[1]-80)**2 + (x[2:]**2).sum() f2 = lambda x: (x[1]-15)**2 + (x[2]-8)**2 + (abs(x[3:]-100)**1.5).sum() f3 = lambda x: (x[2]-8)**2 + (x[0]-80)**2 + (abs(x[4:]+150)**1.2).sum() f = [f1, f2, f3] # you can define matrices as numpy array, matrix, Python lists or tuples #box-bound constraints lb <= x <= ub lb = [0]*n ub = [15, inf, 80] + (n-3) * [inf] # linear ineq constraints A*x <= b A = array([[4, 5, 6] + [0]*(n-3), [80, 8, 15] + [0]*(n-3)]) b = [100, 350] # non-linear eq constraints Aeq*x = beq Aeq = [15, 8, 80] + [0]*(n-3) beq = 90 # non-lin ineq constraints c(x) <= 0 c1 = lambda x: x[0] + (x[1]/8) ** 2 - 15 c2 = lambda x: x[0] + (x[2]/80) ** 2 - 15 c = [c1, c2] #or: c = lambda x: (x[0] + (x[1]/8) ** 2 - 15, x[0] + (x[2]/80) ** 2 - 15) # non-lin eq constraints h(x) = 0 h = lambda x: x[0]+x[2]**2 - x[1] x0 = [0, 1, 2] + [1.5]*(n-3) p = MMP(f, x0, lb = lb, ub = ub, A=A, b=b, Aeq = Aeq, beq = beq, c=c, h=h, xtol = 1e-6, ftol=1e-6) # optional, matplotlib is required: p.plot=1 r = p.solve('nlp:ipopt', iprint=50, maxIter=1e3) print 'MMP result:', r.ff ### let's check result via comparison with NSP solution F= lambda x: max([f1(x), f2(x), f3(x)]) p = NSP(F, x0, iprint=50, lb = lb, ub = ub, c=c, h=h, A=A, b=b, Aeq = Aeq, beq = beq, xtol = 1e-6, ftol=1e-6) r_nsp = p.solve('ipopt', maxIter = 1e3) print 'NSP result:', r_nsp.ff, 'difference:', r_nsp.ff - r.ff """ ----------------------------------------------------- solver: ipopt problem: unnamed goal: minimax iter objFunVal log10(maxResidual) 0 1.196e+04 1.89 50 1.054e+04 -8.00 100 1.054e+04 -8.00 150 1.054e+04 -8.00 161 1.054e+04 -6.10 istop: 1000 Solver: Time Elapsed = 0.93 CPU Time Elapsed = 0.88 objFunValue: 10536.481 (feasible, max constraint = 7.99998e-07) MMP result: 10536.4808622 ----------------------------------------------------- solver: ipopt problem: unnamed goal: minimum iter objFunVal log10(maxResidual) 0 1.196e+04 1.89 50 1.054e+04 -4.82 100 1.054e+04 -10.25 150 1.054e+04 -15.35 StdOut: Problem solved [PyIPOPT] Ipopt will use Hessian approximation. [PyIPOPT] nele_hess is 0 192 1.054e+04 -13.85 istop: 1000 Solver: Time Elapsed = 2.42 CPU Time Elapsed = 2.42 objFunValue: 10536.666 (feasible, max constraint = 1.42109e-14) NSP result: 10536.6656339 difference: 0.184771728482 """ openopt-0.38+svn1589/openopt/examples/mmp_2.py000066400000000000000000000064361175775750500212030ustar00rootroot00000000000000""" Example of solving Mini-Max Problem max { (x0-15)^2+(x1-80)^2, (x1-15)^2 + (x2-8)^2, (x2-8)^2 + (x0-80)^2 } -> min Currently nsmm is single OO solver available for MMP It defines function F(x) = max_i {f[i](x)} and solves NSP F(x) -> min using solver ralg. It's very far from specialized solvers (like MATLAB fminimax), but it's better than having nothing at all, and allows using of nonsmooth and noisy funcs. This solver is intended to be enhanced in future. """ from numpy import * from openopt import * f1 = lambda x: (x[0]-15)**2 + (x[1]-80)**2 f2 = lambda x: (x[1]-15)**2 + (x[2]-8)**2 f3 = lambda x: (x[2]-8)**2 + (x[0]-80)**2 f = [f1, f2, f3] # you can define matrices as numpy array, matrix, Python lists or tuples #box-bound constraints lb <= x <= ub lb = [0]*3# i.e. [0,0,0] ub = [15, inf, 80] # linear ineq constraints A*x <= b A = mat('4 5 6; 80 8 15') b = [100, 350] # non-linear eq constraints Aeq*x = beq Aeq = mat('15 8 80') beq = 90 # non-lin ineq constraints c(x) <= 0 c1 = lambda x: x[0] + (x[1]/8) ** 2 - 15 c2 = lambda x: x[0] + (x[2]/80) ** 2 - 15 c = [c1, c2] #or: c = lambda x: (x[0] + (x[1]/8) ** 2 - 15, x[0] + (x[2]/80) ** 2 - 15) # non-lin eq constraints h(x) = 0 h = lambda x: x[0]+x[2]**2 - x[1] x0 = [0, 1, 2] p = MMP(f, x0, lb = lb, ub = ub, A=A, b=b, Aeq = Aeq, beq = beq, c=c, h=h, xtol = 1e-6, ftol=1e-6) #p = MMP(f, x0, ftol=1e-8) # optional, matplotlib is required: #p.plot=1 r = p.solve('nsmm', iprint=1, NLPsolver = 'ralg', maxIter=1e3, minIter=1e2) print 'MMP result:', r.ff # ### let's check result via comparison with NSP solution F= lambda x: max([f1(x), f2(x), f3(x)]) p = NSP(F, x0, lb = lb, ub = ub, c=c, h=h, A=A, b=b, Aeq = Aeq, beq = beq, xtol = 1e-6, ftol=1e-6) #p = NSP(F, x0) r_nsp = p.solve('ralg') #print 'NSP result:', r_nsp.ff, 'difference:', r_nsp.ff - r.ff #""" #starting solver nsmm (license: BSD) with problem unnamed # iter ObjFun log10(maxResidual) # 0 6.4660e+03 +1.89 # 10 6.4860e+03 -0.68 # 20 6.4158e+03 -1.23 # 30 6.4119e+03 -3.08 # 40 6.3783e+03 -2.95 # 50 6.3950e+03 -4.05 # 60 6.3951e+03 -6.02 # 70 6.3938e+03 -6.02 # 78 6.3936e+03 -6.00 #nsmm has finished solving the problem unnamed #istop: 3 (|| X[k] - X[k-1] || < xtol) #Solver: Time Elapsed = 0.41 CPU Time Elapsed = 0.38 #objFunValue: 6393.6196095379446 (feasible, max constraint = 9.95421e-07) #MMP result: 6393.6196095379446 #starting solver ralg (license: BSD) with problem unnamed #itn 0 : Fk= 6466.0 MaxResidual= 78.0 #itn 10 Fk: 6485.9728487666425 MaxResidual: 2.07e-01 ls: 2 #itn 20 Fk: 6415.8358391383163 MaxResidual: 5.92e-02 ls: 1 #itn 30 Fk: 6411.9310394431113 MaxResidual: 8.22e-04 ls: 3 #itn 40 Fk: 6378.3471060481961 MaxResidual: 1.12e-03 ls: 2 #itn 50 Fk: 6394.9848936519056 MaxResidual: 8.94e-05 ls: 0 #itn 60 Fk: 6395.054402295913 MaxResidual: 9.57e-07 ls: 1 #itn 70 Fk: 6393.8314202292149 MaxResidual: 9.63e-07 ls: 1 #itn 78 Fk: 6393.6196095379446 MaxResidual: 9.95e-07 ls: 1 #ralg has finished solving the problem unnamed #istop: 3 (|| X[k] - X[k-1] || < xtol) #Solver: Time Elapsed = 0.44 CPU Time Elapsed = 0.32 #objFunValue: 6393.6196095379446 (feasible, max constraint = 9.95421e-07) #NSP result: 6393.6196095379446 difference: 0.0 #""" openopt-0.38+svn1589/openopt/examples/nllsp_1.py000066400000000000000000000032271175775750500215340ustar00rootroot00000000000000""" Let us solve the overdetermined nonlinear equations: a^2 + b^2 = 15 a^4 + b^4 = 100 a = 3.5 Let us concider the problem as x[0]**2 + x[1]**2 - 15 = 0 x[0]**4 + x[1]**4 - 100 = 0 x[0] - 3.5 = 0 Now we will solve the one using solver scipy_leastsq """ from openopt import NLLSP from numpy import * f = lambda x: ((x**2).sum() - 15, (x**4).sum() - 100, x[0]-3.5) # other possible f assignments: # f = lambda x: [(x**2).sum() - 15, (x**4).sum() - 100, x[0]-3.5] #f = [lambda x: (x**2).sum() - 15, lambda x: (x**4).sum() - 100, lambda x: x[0]-3.5] # f = (lambda x: (x**2).sum() - 15, lambda x: (x**4).sum() - 100, lambda x: x[0]-3.5) # f = lambda x: asfarray(((x**2).sum() - 15, (x**4).sum() - 100, x[0]-3.5)) #optional: gradient def df(x): r = zeros((3,2)) r[0,0] = 2*x[0] r[0,1] = 2*x[1] r[1,0] = 4*x[0]**3 r[1,1] = 4*x[1]**3 r[2,0] = 1 return r # init esimation of solution - sometimes rather pricise one is very important x0 = [1.5, 8] #p = NLLSP(f, x0, diffInt = 1.5e-8, xtol = 1.5e-8, ftol = 1.5e-8) # or # p = NLLSP(f, x0) # or p = NLLSP(f, x0, df = df, xtol = 1.5e-8, ftol = 1.5e-8) #optional: user-supplied gradient check: p.checkdf() #r = p.solve('scipy_leastsq', plot=1, iprint = -1) #or using converter lsp2nlp: r = p.solve('nlp:ralg', iprint = 1, plot=1) #r = p.solve('nlp:ipopt',plot=1), r = p.solve('nlp:algencan'), r = p.solve('nlp:ralg'), etc #(some NLP solvers require additional installation) print 'x_opt:', r.xf # 2.74930862, +/-2.5597651 print 'funcs Values:', p.f(r.xf) # [-0.888904734668, 0.0678251418575, -0.750691380965] print 'f_opt:', r.ff, '; sum of squares (should be same value):', (p.f(r.xf) ** 2).sum() # 1.35828942657 openopt-0.38+svn1589/openopt/examples/nlp_1.py000066400000000000000000000050351175775750500211740ustar00rootroot00000000000000""" Example: (x0-5)^2 + (x2-5)^2 + ... +(x149-5)^2 -> min subjected to # lb<= x <= ub: x4 <= 4 8 <= x5 <= 15 # Ax <= b x0+...+x149 >= 825 x9 + x19 <= 3 x10+x11 <= 9 # Aeq x = beq x100+x101 = 11 # c(x) <= 0 2*x0^4-32 <= 0 x1^2+x2^2-8 <= 0 # h(x) = 0 (x[149]-1)**6 = 0 (x[148]-1.5)**6 = 0 """ from openopt import NLP from numpy import cos, arange, ones, asarray, zeros, mat, array N = 150 # objective function: f = lambda x: ((x-5)**2).sum() # objective function gradient (optional): df = lambda x: 2*(x-5) # start point (initial estimation) x0 = 8*cos(arange(N)) # c(x) <= 0 constraints c = [lambda x: 2* x[0] **4-32, lambda x: x[1]**2+x[2]**2 - 8] # dc(x)/dx: non-lin ineq constraints gradients (optional): dc0 = lambda x: [8 * x[0]**3] + [0]*(N-1) dc1 = lambda x: [0, 2 * x[1], 2 * x[2]] + [0]*(N-3) dc = [dc0, dc1] # h(x) = 0 constraints def h(x): return (x[N-1]-1)**6, (x[N-2]-1.5)**6 # other possible return types: numpy array, matrix, Python list, tuple # or just h = lambda x: [(x[149]-1)**6, (x[148]-1.5)**6] # dh(x)/dx: non-lin eq constraints gradients (optional): def dh(x): r = zeros((2, N)) r[0, -1] = 6*(x[N-1]-1)**5 r[1, -2] = 6*(x[N-2]-1.5)**5 return r # lower and upper bounds on variables lb = -6*ones(N) ub = 6*ones(N) ub[4] = 4 lb[5], ub[5] = 8, 15 # general linear inequality constraints A = zeros((3, N)) A[0, 9] = 1 A[0, 19] = 1 A[1, 10:12] = 1 A[2] = -ones(N) b = [7, 9, -825] # general linear equality constraints Aeq = zeros(N) Aeq[100:102] = 1 beq = 11 # required constraints tolerance, default for NLP is 1e-6 contol = 1e-7 # If you use solver algencan, NB! - it ignores xtol and ftol; using maxTime, maxCPUTime, maxIter, maxFunEvals, fEnough is recommended. # Note that in algencan gtol means norm of projected gradient of the Augmented Lagrangian # so it should be something like 1e-3...1e-5 gtol = 1e-7 # (default gtol = 1e-6) # Assign problem: # 1st arg - objective function # 2nd arg - start point p = NLP(f, x0, df=df, c=c, dc=dc, h=h, dh=dh, A=A, b=b, Aeq=Aeq, beq=beq, lb=lb, ub=ub, gtol=gtol, contol=contol, iprint = 50, maxIter = 10000, maxFunEvals = 1e7, name = 'NLP_1') #optional: graphic output, requires pylab (matplotlib) p.plot = True #optional: user-supplied 1st derivatives check p.checkdf() p.checkdc() p.checkdh() solver = 'ralg' #solver = 'algencan' #solver = 'ipopt' #solver = 'scipy_slsqp' # solve the problem r = p.solve(solver, plot=0) # string argument is solver name # r.xf and r.ff are optim point and optim objFun value # r.ff should be something like 132.05 openopt-0.38+svn1589/openopt/examples/nlp_11.py000066400000000000000000000064611175775750500212610ustar00rootroot00000000000000""" Example: (x0-5)^2 + (x2-5)^2 + ... +(x149-5)^2 -> min subjected to # lb<= x <= ub: x4 <= 4 8 <= x5 <= 15 # Ax <= b x0+...+x149 >= 825 x9 + x19 <= 3 x10+x11 <= 9 # Aeq x = beq x100+x101 = 11 # c(x) <= 0 2*x0^4-32 <= 0 x1^2+x2^2-8 <= 0 # h(x) = 0 (x[149]-1)**6 = 0 (x[148]-1.5)**6 = 0 """ from openopt import NLP from numpy import cos, arange, ones, asarray, zeros, mat, array N = 150 # objective function: f = lambda x: ((x-5)**2).sum() # objective function gradient (optional): df = lambda x: 2*(x-5) # start point (initial estimation) x0 = 8*cos(arange(N)) # c(x) <= 0 constraints c = [lambda x: 2* x[0] **4-32, lambda x: x[1]**2+x[2]**2 - 8] # dc(x)/dx: non-lin ineq constraints gradients (optional): dc0 = lambda x: [8 * x[0]**3] + [0]*(N-1) dc1 = lambda x: [0, 2 * x[1], 2 * x[2]] + [0]*(N-3) dc = [dc0, dc1] # h(x) = 0 constraints def h(x): #return (x[-1]-1)**2 return (x[-1]-1)**6, (x[-2]-1.5)**6 # other possible return types: numpy array, matrix, Python list, tuple # dh(x)/dx: non-lin eq constraints gradients (optional): def dh(x): r = zeros((2, N)) r[0, -1] = 6*(x[-1]-1)**5 r[1, -2] = 6*(x[-2]-1.5)**5 return r #def dh(x): # r = zeros((1, N)) # r[0, -1] = 2*(x[-1]-1)**1 # #r[1, -2] = 6*(x[148]-1.5)**5 # return r # lower and upper bounds on variables lb = -6*ones(N) ub = 6*ones(N) ub[4] = 4 lb[5], ub[5] = 8, 15 #lb[110:120]=5.67 #ub[110:120]=5.67 # general linear inequality constraints A = zeros((3, N)) A[0, 9] = 1 A[0, 19] = 1 A[1, 10:12] = 1 A[2] = -ones(N) b = [7, 9, -825] # general linear equality constraints Aeq = zeros((1, N)) Aeq[0, 100:102] = 1 beq = 11 #Aeq[1, 105] = 1 #Aeq[1, 106] = 1.00001 #beq = [11, 11.00005] # required constraints tolerance, default for NLP is 1e-6 contol = 1e-6 # If you use solver algencan, NB! - it ignores xtol and ftol; using maxTime, maxCPUTime, maxIter, maxFunEvals, fEnough is recommended. # Note that in algencan gtol means norm of projected gradient of the Augmented Lagrangian # so it should be something like 1e-3...1e-5 gtol = 1e-7 # (default gtol = 1e-6) # Assign problem: # 1st arg - objective function # 2nd arg - start point p = NLP(f, x0, df=df, c=c, dc=dc, h=h, dh=dh, A=A, b=b, Aeq=Aeq, beq=beq, lb=lb, ub=ub, gtol=gtol, contol=contol, iprint = 50, maxIter = 10000, maxFunEvals = 1e7, name = 'NLP_1') #p = NLP(f, x0, df=df, Aeq=Aeq, beq=beq, # gtol=gtol, contol=contol, iprint = 50, maxIter = 10000, maxFunEvals = 1e7, name = 'NLP_1') #p = NLP(f, x0, df=df, lb=lb, ub=ub, gtol=gtol, contol=contol, iprint = 50, maxIter = 10000, maxFunEvals = 1e7, name = 'NLP_1') #optional: graphic output, requires pylab (matplotlib) p.plot = 1 #optional: user-supplied 1st derivatives check p.checkdf() p.checkdc() p.checkdh() def MyIterFcn(p): return 0 # print 'Iteration',p.iter # if p.iter == 50: # p.user.mylist.append(p.xk.copy()) # return 0 p.user.mylist = [] # solve the problem #p.debug=1 solver = 'algencan' solver = 'ralg' #solver = 'scipy_cobyla' #solver = 'ipopt' #solver = 'scipy_slsqp' p.debug=1 r = p.solve(solver, showRej=1, iprint=1, maxTime = 15000, newLinEq=1, callback = MyIterFcn) # string argument is solver name #r = p.solve('r2', iprint = 1, plot=0, showLS=1, maxIter=480) # r.xf and r.ff are optim point and optim objFun value # r.ff should be something like 132.0522 openopt-0.38+svn1589/openopt/examples/nlp_2.py000066400000000000000000000016151175775750500211750ustar00rootroot00000000000000from openopt import NLP from numpy import cos, arange, ones, asarray, abs, zeros N = 30 M = 5 ff = lambda x: ((x-M)**2).sum() p = NLP(ff, cos(arange(N))) p.df = lambda x: 2*(x-M) p.c = lambda x: [2* x[0] **4-32, x[1]**2+x[2]**2 - 8] def dc(x): r = zeros((2, p.n)) r[0,0] = 2 * 4 * x[0]**3 r[1,1] = 2 * x[1] r[1,2] = 2 * x[2] return r p.dc = dc h1 = lambda x: 1e1*(x[-1]-1)**4 h2 = lambda x: (x[-2]-1.5)**4 p.h = lambda x: (h1(x), h2(x)) def dh(x): r = zeros((2, p.n)) r[0,-1] = 1e1*4*(x[-1]-1)**3 r[1,-2] = 4*(x[-2]-1.5)**3 return r p.dh = dh p.lb = -6*ones(N) p.ub = 6*ones(N) p.lb[3] = 5.5 p.ub[4] = 4.5 #r = p.solve('ipopt', showLS=0, xtol=1e-7, maxIter = 1504) #solver = 'ipopt' solver = 'ralg' #solver = 'scipy_slsqp' #solver = 'algencan' r = p.solve(solver, maxIter = 1504, plot=1) #!! fmin_cobyla can't use user-supplied gradient #r = p.solve('scipy_cobyla') openopt-0.38+svn1589/openopt/examples/nlp_3.py000066400000000000000000000051631175775750500212000ustar00rootroot00000000000000from openopt import NLP from numpy import cos, arange, ones, asarray, abs, zeros, sqrt, asscalar from pylab import legend, show, plot, subplot, xlabel, subplots_adjust from string import rjust, ljust, expandtabs N = 15 M = 5 f = lambda x: -(abs(x-M) ** 1.5).sum() x0 = cos(arange(N)) #c = lambda x: [2* x[0] **4-32, x[1]**2+x[2]**2 - 8] global cc1, cc2, cc3 def c1(x): global cc1 cc1 += 1 return 2* x[0] **4-32 def c2(x): global cc2 cc2 += 1 return x[1]**2+x[2]**2 - 8 def c3(x): global cc3 cc3 += 1 return x[1]**2+x[2]**2 + x[3]**2 - 35 c = [c1, c2, c3] h1 = lambda x: 1e1*(x[-1]-1)**4 h2 = lambda x: (x[-2]-1.5)**4 h = (h1, h2) lb = -6*ones(N) ub = 6*ones(N) lb[3] = 5.5 ub[4] = 4.5 colors = ['b', 'k', 'y', 'r', 'g'] ############# #solvers = ['ralg','scipy_cobyla', 'lincher'] solvers = ['ralg', 'scipy_cobyla', 'lincher','ipopt','algencan' ] solvers = ['ralg', 'ralg3', 'ralg5'] solvers = ['ralg', 'scipy_cobyla'] #solvers = ['ipopt'] solvers = ['ralg', 'ipopt'] solvers = ['ralg'] solvers = ['scipy_slsqp'] solvers = ['ralg'] ############# colors = colors[:len(solvers)] lines, results = [], {} for j in range(len(solvers)): cc1, cc2, cc3 = 0, 0, 0 solver = solvers[j] color = colors[j] p = NLP(f, x0, c=c, h=h, lb = lb, ub = ub, ftol = 1e-6, maxFunEvals = 1e7, maxIter = 1220, plot = 1, color = color, iprint = 0, legend = [solvers[j]], show= False, xlabel='time', goal='maximum', name='nlp3') if solver == 'algencan': p.gtol = 1e-1 elif solver == 'ralg': p.debug = 1 r = p.solve(solver, debug=1) print 'c1 evals:', cc1, 'c2 evals:', cc2, 'c3 evals:', cc3 results[solver] = (r.ff, p.getMaxResidual(r.xf), r.elapsed['solver_time'], r.elapsed['solver_cputime'], r.evals['f'], r.evals['c'], r.evals['h']) subplot(2,1,1) F0 = asscalar(p.f(p.x0)) lines.append(plot([0, 1e-15], [F0, F0], color= colors[j])) for i in range(2): subplot(2,1,i+1) legend(lines, solvers) subplots_adjust(bottom=0.2, hspace=0.3) xl = ['Solver f_opt MaxConstr Time CPUTime fEvals cEvals hEvals'] for i in range(len(results)): xl.append((expandtabs(ljust(solvers[i], 16)+' \t', 15)+'%0.2f'% (results[solvers[i]][0]) + ' %0.1e' % (results[solvers[i]][1]) + (' %0.2f'% (results[solvers[i]][2])) + ' %0.2f '% (results[solvers[i]][3]) + str(results[solvers[i]][4]) + ' ' + rjust(str(results[solvers[i]][5]), 5) + expandtabs('\t' +str(results[solvers[i]][6]),8))) xl = '\n'.join(xl) subplot(2,1,1) xlabel('Time elapsed (without graphic output), sec') from pylab import * subplot(2,1,2) xlabel(xl) show() openopt-0.38+svn1589/openopt/examples/nlp_4.py000066400000000000000000000017331175775750500212000ustar00rootroot00000000000000from openopt import NLP from numpy import cos, arange, ones, asarray, zeros, mat, array, sin, cos, sign, abs, inf N = 1500 K = 50 # 1st arg - objective function # 2nd arg - x0 p = NLP(lambda x: (abs(x-5)).sum(), 8*cos(arange(N)), iprint = 50, maxIter = 1e3) # f(x) gradient (optional): p.df = lambda x: sign(x-5) p.lb = 5*ones(N) + sin(arange(N)) - 0.1 p.ub = 5*ones(N) + sin(arange(N)) + 0.1 p.lb[:N/4] = -inf p.ub[3*N/4:] = inf #p.ub[4] = 4 #p.lb[5], p.ub[5] = 8, 15 #A = zeros((K, N)) #b = zeros(K) #for i in xrange(K): # A[i] = 1+cos(i+arange(N)) # b[i] = sin(i) #p.A = A #p.b = b #p.Aeq = zeros(p.n) #p.Aeq[100:102] = 1 #p.beq = 11 p.contol = 1e-6 p.plot = 1 p.maxFunEvals = 1e7 p.name = 'nlp_4' p.debug=1 solver = 'ralg' solver = 'gsubg' #solver = 'scipy_cobyla' solver = 'algencan' #solver = 'ipopt' r = p.solve(solver, xlabel = 'time', fTol = 10, debug=0, maxIter = 5500, plot=0, maxTime=1000, ftol = 1e-8, xtol = 1e-6, iprint=1, showLS=0, showFeas=0, show_hs=0) openopt-0.38+svn1589/openopt/examples/nlp_5.py000066400000000000000000000052171175775750500212020ustar00rootroot00000000000000from openopt import NLP from numpy import cos, arange, ones, asarray, abs, zeros, sqrt, asscalar, inf from string import rjust, ljust, expandtabs, center, lower N = 100 M = 5 Power = 1.13 ff = lambda x: (abs(x-M) ** Power).sum() x0 = cos(arange(N)) c = [lambda x: 2* x[0] **4-32, lambda x: x[1]**2+x[2]**2 - 8] #c = lambda x: [2* x[0] **4-32, x[1]**2+x[2]**2 - 8000] h1 = lambda x: 1e1*(x[-1]-1)**4 h2 = lambda x: (x[-2]-1.5)**4 h = (h1, h2) lb = -6*ones(N) ub = 6*ones(N) lb[3] = 5.5 ub[4] = 4.5 gtol=1e-6 ftol = 1e-6 diffInt = 1e-8 contol = 1e-6 maxFunEvals = 1e6 maxTime = 10 Xlabel = 'time' PLOT = 0 colors = ['b', 'k', 'y', 'g', 'r', 'm', 'c'] ############################################################### solvers = ['ralg', 'scipy_cobyla', 'lincher', 'scipy_slsqp', 'ipopt','algencan'] #solvers = ['ralg', 'ipopt'] #solvers = ['ralg', 'scipy_cobyla', 'lincher', 'scipy_slsqp', 'ipopt'] #solvers = ['ralg', 'ralg3'] solvers = ['ralg'] ############################################################### lines, results = [], {} for j, solver in enumerate(solvers): p = NLP(ff, x0, xlabel = Xlabel, c=c, h=h, lb = lb, ub = ub, gtol=gtol, diffInt = diffInt, ftol = ftol, maxIter = 1390, plot = PLOT, color = colors[j], iprint = 10, df_iter = 4, legend = solver, show=False, contol = contol, maxTime = maxTime, maxFunEvals = maxFunEvals, name='NLP_5') if solver =='algencan': p.gtol = 1e-2 elif solver == 'ralg': pass #p.debug = 1 p.debug = 1 r = p.solve(solver) for fn in ('h','c'): if not r.evals.has_key(fn): r.evals[fn]=0 # if no c or h are used in problem results[solver] = (r.ff, p.getMaxResidual(r.xf), r.elapsed['solver_time'], r.elapsed['solver_cputime'], r.evals['f'], r.evals['c'], r.evals['h']) if PLOT: subplot(2,1,1) F0 = asscalar(p.f(p.x0)) lines.append(plot([0, 1e-15], [F0, F0], color= colors[j])) if PLOT: for i in range(2): subplot(2,1,i+1) legend(lines, solvers) subplots_adjust(bottom=0.2, hspace=0.3) xl = ['Solver f_opt MaxConstr Time CPUTime fEvals cEvals hEvals'] for i in range(len(results)): s=(ljust(lower(solvers[i]), 40-len(solvers[i]))+'%0.3f'% (results[solvers[i]][0]) + ' %0.1e' % (results[solvers[i]][1]) + (' %0.2f'% (results[solvers[i]][2])) + ' %0.2f '% (results[solvers[i]][3]) + str(results[solvers[i]][4]) + ' ' + rjust(str(results[solvers[i]][5]), 5) + ' '*8 +str(results[solvers[i]][6])) xl.append(s) xl = '\n'.join(xl) subplot(2,1,1) xlabel(Xlabel) from pylab import * subplot(2,1,2) xlabel(xl) show() openopt-0.38+svn1589/openopt/examples/nlp_ALGENCAN.py000066400000000000000000000077521175775750500222140ustar00rootroot00000000000000from openopt import NLP from numpy import cos, arange, ones, asarray, zeros, mat, array N = 50 # objfunc: # (x0-1)^4 + (x2-1)^4 + ... +(x49-1)^4 -> min (N=nVars=50) f = lambda x : ((x-1)**4).sum() x0 = cos(arange(N)) p = NLP(f, x0, maxIter = 1e3, maxFunEvals = 1e5) # f(x) gradient (optional): p.df = lambda x: 4*(x-1)**3 # lb<= x <= ub: # x4 <= -2.5 # 3.5 <= x5 <= 4.5 # all other: lb = -5, ub = +15 p.lb = -5*ones(N) p.ub = 15*ones(N) p.ub[4] = -2.5 p.lb[5], p.ub[5] = 3.5, 4.5 # Ax <= b # x0+...+xN>= 1.1*N # x9 + x19 <= 1.5 # x10+x11 >= 1.6 p.A = zeros((3, N)) p.A[0, 9] = 1 p.A[0, 19] = 1 p.A[1, 10:12] = -1 p.A[2] = -ones(N) p.b = [1.5, -1.6, -1.1*N] # you can use any types of A, Aeq, b, beq: # Python list, numpy.array, numpy.matrix, even Python touple # so p.b = array([1.5, -1.6, -825]) or p.b = (1.5, -1.6, -825) are valid as well # Aeq x = beq # x20+x21 = 2.5 p.Aeq = zeros(N) p.Aeq[20:22] = 1 p.beq = 2.5 # non-linear inequality constraints c(x) <= 0 # 2*x0^4 <= 1/32 # x1^2+x2^2 <= 1/8 # x25^2 +x25*x35 + x35^2<= 2.5 p.c = lambda x: [2* x[0] **4-1./32, x[1]**2+x[2]**2 - 1./8, x[25]**2 + x[35]**2 + x[25]*x[35] -2.5] # other valid c: # p.c = [lambda x: c1(x), lambda x : c2(x), lambda x : c3(x)] # p.c = (lambda x: c1(x), lambda x : c2(x), lambda x : c3(x)) # p.c = lambda x: numpy.array(c1(x), c2(x), c3(x)) # def c(x): # return c1(x), c2(x), c3(x) # p.c = c # dc(x)/dx: non-lin ineq constraints gradients (optional): def DC(x): r = zeros((3, N)) r[0,0] = 2 * 4 * x[0]**3 r[1,1] = 2 * x[1] r[1,2] = 2 * x[2] r[2,25] = 2*x[25] + x[35] r[2,35] = 2*x[35] + x[25] return r p.dc = DC # non-linear equality constraints h(x) = 0 # 1e6*(x[last]-1)**4 = 0 # (x[last-1]-1.5)**4 = 0 p.h = lambda x: (1e4*(x[-1]-1)**4, (x[-2]-1.5)**4) # dh(x)/dx: non-lin eq constraints gradients (optional): def DH(x): r = zeros((2, p.n)) r[0, -1] = 1e4*4 * (x[-1]-1)**3 r[1, -2] = 4 * (x[-2]-1.5)**3 return r p.dh = DH p.contol = 1e-3 # required constraints tolerance, default for NLP is 1e-6 # for ALGENCAN solver gtol is the only one stop criterium connected to openopt # (except maxfun, maxiter) # Note that in ALGENCAN gtol means norm of projected gradient of the Augmented Lagrangian # so it should be something like 1e-3...1e-5 p.gtol = 1e-5 # gradient stop criterium (default for NLP is 1e-6) # see also: help(NLP) -> maxTime, maxCPUTime, ftol and xtol # that are connected to / used in lincher and some other solvers # optional: check of user-supplied derivatives p.checkdf() p.checkdc() p.checkdh() # last but not least: # please don't forget, # Python indexing starts from ZERO!! p.plot = 0 p.iprint = 0 p.df_iter = 4 p.maxTime = 4000 p.debug=1 #r = p.solve('algencan') r = p.solve('ralg') #r = p.solve('lincher') """ typical output: OpenOpt checks user-supplied gradient df (size: (50,)) according to: prob.diffInt = 1e-07 prob.check.maxViolation = 1e-05 max(abs(df_user - df_numerical)) = 2.50111104094e-06 (is registered in df number 41) sum(abs(df_user - df_numerical)) = 4.45203815948e-05 ======================== OpenOpt checks user-supplied gradient dc (size: (50, 3)) according to: prob.diffInt = 1e-07 prob.check.maxViolation = 1e-05 max(abs(dc_user - dc_numerical)) = 1.20371180401e-06 (is registered in dc number 0) sum(abs(dc_user - dc_numerical)) = 1.60141862837e-06 ======================== OpenOpt checks user-supplied gradient dh (size: (50, 2)) according to: prob.diffInt = 1e-07 prob.check.maxViolation = 1e-05 dh num i,j:dh[i]/dx[j] user-supplied numerical difference 98 49 / 0 -1.369e+04 -1.369e+04 -2.941e-03 max(abs(dh_user - dh_numerical)) = 0.00294061290697 (is registered in dh number 98) sum(abs(dh_user - dh_numerical)) = 0.00294343472179 ======================== starting solver ALGENCAN (GPL license) with problem unnamed solver ALGENCAN has finished solving the problem unnamed istop: 1000 Solver: Time elapsed = 0.34 CPU Time Elapsed = 0.34 objFunValue: 190.041570332 (feasible, max constraint = 0.000677961) """ openopt-0.38+svn1589/openopt/examples/nlp_bench_1.py000066400000000000000000000064751175775750500223440ustar00rootroot00000000000000from openopt import * from numpy import cos, arange, ones, asarray, abs, zeros, sqrt, asscalar, inf from pylab import legend, show, plot, subplot, xlabel, subplots_adjust from string import rjust, ljust, expandtabs, center, lower N = 10 M = 5 Power = 1.13 ff = lambda x: (abs(x-M) ** Power).sum() x0 = cos(arange(N)) c = [lambda x: 2* x[0] **4-32, lambda x: x[1]**2+x[2]**2 - 8] #c = lambda x: [2* x[0] **4-32, x[1]**2+x[2]**2 - 8000] h1 = lambda x: 1e1*(x[-1]-1)**4 h2 = lambda x: (x[-2]-1.5)**4 h = (h1, h2) lb = -6*ones(N) ub = 6*ones(N) lb[3] = 5.5 ub[4] = 4.5 gtol=1e-6 ftol = 1e-6 diffInt = 1e-8 contol = 1e-6 xtol = 1e-9 maxFunEvals = 1e6 maxTime = 1000 Xlabel = 'time' PLOT = 1 colors = ['k', 'r', 'b', 'g', 'r', 'm', 'c'] ############################################################### solvers = ['ralg', 'scipy_cobyla', 'lincher', 'scipy_slsqp', 'ipopt','algencan'] #solvers = ['ralg', 'ipopt'] solvers = ['ralg', 'scipy_cobyla', 'lincher', 'scipy_slsqp', 'ipopt'] #solvers = ['ralg', 'scipy_slsqp', 'scipy_cobyla', 'algencan'] #solvers = ['ipopt','ralg', 'algencan'] #solvers = ['ralg', 'scipy_cobyla'] #solvers = ['ralg'] solvers = ['gsubg', 'ralg', 'scipy_cobyla'] solvers = ['gsubg', 'ipopt'] #solvers = ['gsubg', 'ipopt', 'scipy_cg'] #solvers = ['ipopt']*3 #solvers = ['ipopt'] solvers = [oosolver('gsubg', dilation = False)] #lb = [-1]*N ############################################################### lines, results = [], {} legends = solvers h = None for j, solver in enumerate(solvers): p = NLP(ff, x0, xlabel = Xlabel, c=c, h=h, lb = lb, ub = ub, gtol=gtol, xtol = xtol, diffInt = diffInt, ftol = ftol, fTol = 1e-1, maxIter = 1390, plot = PLOT, color = colors[j], iprint = 1, df_iter = 4, legend = solver, show=False, contol = contol, maxTime = maxTime, maxFunEvals = maxFunEvals, name='NLP_bench_1') p.legend = legends[j] if solver =='algencan': p.gtol = 1e-2 elif solver == 'ralg': pass #p.debug = 1 r = p.solve(solver) from numpy import * xx = array([ 1.99999982, 2.11725165, 1.87543228, 5.00000823, 4.50000036, 5.00000278, 5.00001633, 5.00000858, 1.5299053 , 1.01681614]) for fn in ('h','c'): if not r.evals.has_key(fn): r.evals[fn]=0 # if no c or h are used in problem results[solver] = (r.ff, p.getMaxResidual(r.xf), r.elapsed['solver_time'], r.elapsed['solver_cputime'], r.evals['f'], r.evals['c'], r.evals['h']) if PLOT: subplot(2,1,1) F0 = asscalar(p.f(p.x0)) lines.append(plot([0, 1e-15], [F0, F0], color= colors[j])) if PLOT: for i in range(2): subplot(2,1,i+1) legend(lines, legends) subplots_adjust(bottom=0.2, hspace=0.3) xl = ['Solver f_opt MaxConstr Time CPUTime fEvals cEvals hEvals'] for i in range(len(results)): s=(ljust(lower(solvers[i]), 40-len(solvers[i]))+'%0.3f'% (results[solvers[i]][0]) + ' %0.1e' % (results[solvers[i]][1]) + (' %0.2f'% (results[solvers[i]][2])) + ' %0.2f '% (results[solvers[i]][3]) + str(results[solvers[i]][4]) + ' ' + rjust(str(results[solvers[i]][5]), 5) + ' '*8 +str(results[solvers[i]][6])) xl.append(s) xl = '\n'.join(xl) subplot(2,1,1) xlabel(Xlabel) from pylab import * subplot(2,1,2) xlabel(xl) show() openopt-0.38+svn1589/openopt/examples/nlp_bench_2.py000066400000000000000000000066421175775750500223410ustar00rootroot00000000000000from openopt import NLP from numpy import cos, arange, ones, asarray, abs, zeros, sqrt, sign, asscalar from pylab import legend, show, plot, subplot, xlabel, subplots_adjust from string import rjust, ljust, expandtabs, center, lower from scipy import rand N = 10 M = 5 s = 1.3 f = lambda x: (abs(x-M) ** s).sum() df = lambda x: s * sign(x-M) * abs(x-M) ** (s-1) x0 = cos(arange(N)) #+ rand(N) c = lambda x: [2* x[0] **4-32, x[1]**2+x[2]**2 - 8] def dc(x): r = zeros((len(c(x0)), p.n)) r[0,0] = 2 * 4 * x[0]**3 r[1,1] = 2 * x[1] r[1,2] = 2 * x[2] return r K = 1e2 h1 = lambda x: K*(x[-1]-1)**4 h2 = lambda x: (x[-2]-1.5)**4 h3 = lambda x: (x[-5]+x[-6]-2*M+1.5)**6 h = lambda x: (h1(x), h2(x), h3(x)) def dh(x): r = zeros((3, N)) r[0, -1] = 4 * K * (x[-1]-1)**3 r[1, -2] = 4 * (x[-2]-1.5)**3 r[2, -5] = 6 * (x[-5]+x[-6]-2*M+1.5)**5 r[2, -6] = 6 * (x[-5]+x[-6]-2*M+1.5)**5 return r lb = -6*ones(N) ub = 6*ones(N) lb[3] = 5.5 ub[4] = 4.5 gtol=1e-1 ftol = 1e-6 xtol = 1e-6 diffInt = 1e-8 contol = 1e-6 maxTime = 10 maxIter = 13700 colors = ['b', 'k', 'y', 'g', 'r'] ######################################## solvers = ['ralg', 'scipy_cobyla', 'lincher', 'scipy_slsqp'] #solvers = ['scipy_cobyla', 'ralg'] #solvers = ['lincher', 'scipy_cobyla'] solvers = [ 'ralg','scipy_cobyla'] #solvers = [ 'algencan','algencan2'] #solvers = [ 'ralg', 'ralg3'] ######################################## colors = colors[:len(solvers)] lines, results = [], {} for j in range(len(solvers)): solver = solvers[j] color = colors[j] p = NLP(f, x0, name = 'bench2', df = df, c=c, dc = dc, h=h, dh = dh, lb = lb, ub = ub, gtol=gtol, ftol = ftol, maxFunEvals = 1e7, maxIter = maxIter, maxTime = maxTime, plot = 1, color = color, iprint = 10, legend = [solvers[j]], show=False, contol = contol) # p = NLP(f, x0, name = 'bench2', df = df, c=c, dc = dc, lb = lb, ub = ub, gtol=gtol, ftol = ftol, maxFunEvals = 1e7, maxIter = 1e4, maxTime = maxTime, plot = 1, color = color, iprint = 0, legend = [solvers[j]], show=False, contol = contol) if solver[:4] == ['ralg']: pass # p.gtol = 1e-8 # p.ftol = 1e-7 # p.xtol = 1e-7 elif solver == 'lincher': #p.iprint = 1 p.maxTime = 1e15 p.maxIter = 100 ## p.check.df = 1 ## p.check.dc = 1 ## p.check.dh = 1 r = p.solve(solver) for fn in ('h','c'): if not r.evals.has_key(fn): r.evals[fn]=0 # if no c or h are used in problem results[solver] = (r.ff, p.getMaxResidual(r.xf), r.elapsed['solver_time'], r.elapsed['solver_cputime'], r.evals['f'], r.evals['c'], r.evals['h']) subplot(2,1,1) F0 = asscalar(p.f(p.x0)) lines.append(plot([0, 1e-15], [F0, F0], color= colors[j])) for i in range(2): subplot(2,1,i+1) legend(lines, solvers) subplots_adjust(bottom=0.2, hspace=0.3) xl = ['Solver f_opt MaxConstr Time CPUTime fEvals cEvals hEvals'] for i in range(len(results)): s=(ljust(lower(solvers[i]), 40-len(solvers[i]))+'%0.3f'% (results[solvers[i]][0]) + ' %0.1e' % (results[solvers[i]][1]) + (' %0.2f'% (results[solvers[i]][2])) + ' %0.2f '% (results[solvers[i]][3]) + str(results[solvers[i]][4]) + ' ' + rjust(str(results[solvers[i]][5]), 5) + ' '*5 +str(results[solvers[i]][6])) xl.append(s) xl = '\n'.join(xl) subplot(2,1,1) xlabel('Time elapsed (without graphic output), sec') from pylab import * subplot(2,1,2) xlabel(xl) show() openopt-0.38+svn1589/openopt/examples/nlp_d2f.py000066400000000000000000000014661175775750500215130ustar00rootroot00000000000000""" this is an example of using d2f - Hesse matrix (2nd derivatives) d2c, d2h, d2l are intended to be implemented soon and to be connected to ALGENCAN and/or CVXOPT and/or other NLP solvers //Dmitrey """ from openopt import NLP from numpy import cos, arange, ones, asarray, abs, zeros, diag N = 300 M = 5 ff = lambda x: ((x-M)**4).sum() p = NLP(ff, cos(arange(N))) p.df = lambda x: 4*(x-M)**3 p.d2f = lambda x: diag(12*(x-M)**2) # other valid assignment: # p = NLP(lambda x: ((x-M)**4).sum(), cos(arange(N)), df = lambda x: 4*(x-M)**3, d2f = lambda x: diag(12*(x-M)**2)) # or # p = NLP(x0 = cos(arange(N)), f = lambda x: ((x-M)**4).sum(), df = lambda x: 4*(x-M)**3, d2f = lambda x: diag(12*(x-M)**2)) r = p.solve('scipy_ncg') print('objfunc val: %e' % r.ff) # it should be a small positive like 5.23656378549e-08 openopt-0.38+svn1589/openopt/examples/nlsp_1.py000066400000000000000000000023411175775750500213540ustar00rootroot00000000000000""" Solving system of equations: x[0]**3+x[1]**3-9 = 0 x[0]-0.5*x[1] = 0 cos(x[2])+x[0]-1.5 = 0 """ from openopt import SNLE from numpy import asfarray, zeros, cos, sin #f = lambda x: (x[0]**3+x[1]**3-9, x[0]-0.5*x[1], cos(x[2])+x[0]-1.5) # or: f = (lambda x: x[0]**3+x[1]**3-9, lambda x: x[0]-0.5*x[1], lambda x: cos(x[2])+x[0]-1.5) # Python list, numpy.array are allowed as well: #f = lambda x: [x[0]**3+x[1]**3-9, x[0]-0.5*x[1], cos(x[2])+x[0]-1.5] #or f = lambda x: asfarray((x[0]**3+x[1]**3-9, x[0]-0.5*x[1], cos(x[2])+x[0]-1.5)) # start point x0 = [8,15, 80] #optional: gradient df = (lambda x: [3*x[0]**2, 3*x[1]**2, 0], lambda x: [1, -0.5, 0], lambda x:[1, 0, -sin(x[2])]) #w/o gradient: #p = SNLE(f, x0) p = SNLE(f, x0, df = df) #optional: user-supplied gradient check: #p.checkdf() #optional: graphical output, requires matplotlib installed p.plot = 1 #r = p.solve('scipy_fsolve') r = p.solve('nssolve') #or using converter to nlp, try to minimize sum(f_i(x)^2): #r = p.solve('nlp:ralg') print('solution: %s' % r.xf) print('max residual: %e' % r.ff) ############################### #should print: #solution: [ 1. 2. 55.50147021] (3rd coord may differ due to cos is periodic) #max residual: 2.72366951215e-09 openopt-0.38+svn1589/openopt/examples/nlsp_constrained.py000066400000000000000000000036731175775750500235360ustar00rootroot00000000000000""" Solving system of equations: x[0]**3+x[1]**3-9 = 0 x[0]-0.5*x[1] = 0 cos(x[2])+x[0]-1.5 = 0 with some constraints: 150 <= x[2] <= 158 and possible non-linear constraint: (x[2] - 150.8)**2 <= 1.5 Note: 1. Using Ax <= b constraints is also allowed 2. You can try using equality constraints (h(x)=0, Aeq x = beq) as well. 3. Required function tolerance is p.ftol, constraints tolerance is p.contol, and hence using h(x)=0 constraints is not 100% same to some additional f coords """ from openopt import SNLE from numpy import * # you can define f in several ways: f = lambda x: (x[0]**3+x[1]**3-9, x[0]-0.5*x[1], cos(x[2])+x[0]-1.5) #f = (lambda x: x[0]**3+x[1]**3-9, lambda x: x[0]-0.5*x[1], lambda x: cos(x[2])+x[0]-1.5) # Python list, numpy.array are allowed as well: #f = lambda x: [x[0]**3+x[1]**3-9, x[0]-0.5*x[1], cos(x[2])+x[0]-1.5] #or f = lambda x: asfarray((x[0]**3+x[1]**3-9, x[0]-0.5*x[1], cos(x[2])+x[0]-1.5)) #optional: gradient def df(x): df = zeros((3,3)) df[0,0] = 3*x[0]**2 df[0,1] = 3*x[1]**2 df[1,0] = 1 df[1,1] = -0.5 df[2,0] = 1 df[2,2] = -sin(x[2]) return df x0 = [8,15, 80] #w/o gradient: #p = SNLE(f, x0) p = SNLE(f, x0, df = df, maxFunEvals = 1e5, iprint = 10, plot=1, ftol = 1e-8, contol=1e-15) #optional: user-supplied gradient check: #p.checkdf() #optional: graphical output, requires matplotlib installed #p.plot = 1 #set some constraints p.lb, p.ub = [-inf]*3, [inf]*3 p.lb[2], p.ub[2] = 145, 150 # you could try also comment/uncomment nonlinear constraints: p.c = lambda x: (x[2] - 146)**2-1.5 # optional: gradient p.dc = lambda x: asfarray((0, 0, 2*(x[2]-146))) # also you could set it via p=SNLE(f, x0, ..., c = c, dc = dc) #optional: user-supplied dc check: #p.checkdc() #r = p.solve('nssolve', debug=0, maxIter=1e9) # using converter to nlp, try to minimize sum(f_i(x)^2): r = p.solve('nlp:ralg', xlabel='iter', iprint=10, plot=1) print('solution: %s' % r.xf) print('max residual: %e' % r.ff) openopt-0.38+svn1589/openopt/examples/nsp_1.py000066400000000000000000000016251175775750500212040ustar00rootroot00000000000000""" Example: Solving nonsmooth problem |x1| + 1.2|x2| + 1.44|x3| + ... + 1.2^N |xN| -> min N=75 x0 = [cos(1), cos(2), ..., cos(N)] x_opt = all-zeros f_opt = 0 """ from numpy import * from openopt import NSP N = 75 objFun = lambda x: sum(1.2 ** arange(len(x)) * abs(x)) x0 = cos(1+asfarray(range(N))) p = NSP(objFun, x0, maxFunEvals = 1e7, xtol = 1e-8) #These assignments are also correct: #p = NLP(objFun, x0=x0) #p = NLP(f=objFun, x0=x0) #p = NLP(ftol = 1e-5, contol = 1e-5, f=objFun, x0=x0) p.maxIter = 5000 #optional (requires matplotlib installed) #p.plot = 1 #p.graphics.xlabel = 'cputime'#default: time, case-unsensetive; also here maybe 'cputime', 'niter' #OPTIONAL: user-supplied gradient/subgradient p.df = lambda x: 1.2 ** arange(len(x)) * sign(x) r = p.solve('ralg') # ralg is name of a solver print('x_opt: %s' % r.xf) print('f_opt: %f' % r.ff) # should print small positive number like 0.00056 openopt-0.38+svn1589/openopt/examples/nssolveVSfsolve_1.py000066400000000000000000000113221175775750500235600ustar00rootroot00000000000000""" Solving system of equations: x[0]**3 + x[1]**3 - 9 = 0 x[0] - 0.5*x[1] - 0.15*x[2]= 0 sinh(x[2]) + x[0] - 15 = 0 !! with numerical noise 1e-8 !! Note that both fsolve and nssolve get same gradient - if no user-supplied one is available, then same OO finite-difference one is used (according to p.diffInt value) If you have matplotlib installed, you'll get a figure. Typical fsolve fails number (for scipy 0.6.0) is ~ 10-15% This test runs ~ a minute on my AMD 3800+ """ noise = 1e-8 from openopt import SNLE from numpy import asfarray, zeros, cos, sin, arange, cosh, sinh, log10, ceil, floor, arange, inf, nanmin, nanmax from time import time from scipy import rand x0 = [8, 15, 0.80] global count1, count2, count3 count1 = count2 = count3 = 0 def Count1(): global count1; count1 +=1; return 0 def Count2(): global count2; count2 +=1; return 0 def Count3(): global count3; count3 +=1; return 0 # ATTENTION! # when no user-supplied gradient is available # nssolve can take benefites from splitting funcs # so using f=[fun1, fun2, fun3, ...](or f=(fun1, fun2, fun3, ...)) # (where each fun is separate equation) # is more appriciated than # f = lambda x: (...) # or def f(x): (...) f_without_noise = \ [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] def fvn(x): r = -inf for f in f_without_noise: r = max(r, abs(f(x))) return r 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(), \ lambda x: sinh(x[2])+x[0]-15 + noise*rand(1)+Count3()]# + (2007 * x[3:]**2).tolist() #optional: gradient ##def DF(x): ## df = zeros((3,3)) ## df[0,0] = 3*x[0]**2 ## df[0,1] = 3*x[1]**2 ## df[1,0] = 1 ## df[1,1] = -0.5 ## df[1,2] = -0.15 ## df[2,0] = 1 ## df[2,2] = cosh(x[2]) ## return df N = 100 desired_ftol = 1e-6 assert desired_ftol - noise*len(x0) > 1e-7 #w/o gradient: scipy_fsolve_failed, fs = 0, [] print '----------------------------------' print 'desired ftol:', desired_ftol, 'objFunc noise:', noise ############################################################################ print '---------- fsolve fails ----------' t = time() print 'N log10(MaxResidual) MaxResidual' for i in xrange(N): p = SNLE(f, x0, ftol = desired_ftol - noise*len(x0), iprint = -1, maxFunEvals = int(1e7)) r = p.solve('scipy_fsolve') v = fvn(r.xf) fs.append(log10(v)) if v > desired_ftol: scipy_fsolve_failed += 1 print i+1, ' %0.2f ' % log10(v), v else: print i+1, 'OK' print 'fsolve time elapsed', time()-t #print 'fsolve_failed number:', scipy_fsolve_failed , '(from', N, '),', 100.0*scipy_fsolve_failed / N, '%' print 'counters:', count1, count2, count3 ############################################################################ count1 = count2 = count3 = 0 t = time() print '---------- nssolve fails ---------' nssolve_failed, ns = 0, [] print 'N log10(MaxResidual) MaxResidual' for i in xrange(N): p = SNLE(f, x0, ftol = desired_ftol - noise*len(x0), iprint = -1, maxFunEvals = int(1e7)) r = p.solve('nssolve') #r = p.solve('nlp:amsg2p') #r = p.solve('nlp:ralg') v = fvn(r.xf) ns.append(log10(v)) if v > desired_ftol: nssolve_failed += 1 print i+1, ' %0.2f ' % log10(v), v else: print i+1, 'OK' print 'nssolve time elapsed', time()-t print 'nssolve_failed number:', nssolve_failed , '(from', N, '),', 100.0 * nssolve_failed / N, '%' print 'counters:', count1, count2, count3 ############################################################################ print '------------ SUMMARY -------------' print 'fsolve_failed number:', scipy_fsolve_failed , '(from', N, '),', 100.0*scipy_fsolve_failed / N, '%' print 'nssolve_failed number:', nssolve_failed , '(from', N, '),', 100.0 * nssolve_failed / N, '%' #try: from pylab import * subplot(2,1,1) grid(1) title('scipy.optimize fsolve fails to achive desired ftol: %0.1f%%' %(100.0*scipy_fsolve_failed / N)) xmin1, xmax1 = floor(nanmin(fs)), ceil(nanmax(fs))+1 hist(fs, arange(xmin1, xmax1)) #xlabel('log10(maxResidual)') axvline(log10(desired_ftol), color='green', linewidth=3, ls='--') [ymin1, ymax1] = ylim() ################ subplot(2,1,2) grid(1) title('openopt nssolve fails to achive desired ftol: %0.1f%%' % (100.0*nssolve_failed / N)) xmin2, xmax2 = floor(nanmin(ns)), ceil(nanmax(ns))+1 #hist(ns, 5) hist(ns, arange(xmin2, xmax2)) xlabel('log10(maxResidual)') axvline(log10(desired_ftol), color='green', linewidth=3, ls='--') [ymin2, ymax2] = ylim() ################ xmin, xmax = min(xmin1, xmin2) - 0.1, max(xmax1, xmax2) + 0.1 ymin, ymax = 0, max(ymax1, ymax2) * 1.05 subplot(2,1,1) xlim(xmin, xmax) ylim(0, ymax) subplot(2,1,2) xlim(xmin, xmax) show() #except: # pass openopt-0.38+svn1589/openopt/examples/qcqp_1.py000066400000000000000000000020661175775750500213500ustar00rootroot00000000000000""" Concider the MIQCQP problem 0.5 * (x1^2 + 2x2^2 + 3x3^2) + 15x1 + 8x2 + 80x3 -> min (1) subjected to x1 + 2x2 + 3x3 <= 150 (2) 8x1 + 15x2 + 80x3 <= 800 (3) x2 - x3 = 25.5 (4) x1 <= 15 (5) x1^2 + 2.5 x2^2 + 3 x3^2 + 0.1 x1 + 0.2 x2 + 0.3 x3 - 1000 <= 0 (6) 2 x1^2 + x2^2 + 3 x3^2 + 0.1 x1 + 0.5 x2 + 0.3 x3 <= 1000 (7) x1, x3 are integers """ from numpy import diag, matrix, inf from openopt import QP H = diag([1.0, 2.0,3.0]) f = [15,8,80] A = matrix('1 2 3; 8 15 80') b = [150, 800] # QC should be list or tuple of triples (P, q, s): 0.5 x^T P x + q x + s <= 0 QC = ((diag([1.0, 2.5, 3.0]), [0.1, 0.2, 0.3], -1000), (diag([2.0, 1.0, 3.0]), [0.1, 0.5, 0.3], -1000)) p = QP(H, f, A = A, b = b, Aeq = [0, 1, -1], beq = 25.5, ub = [15,inf,inf], QC = QC, name='OpenOpt QCQP example 1') # or p = QP(H=diag([1,2,3]), f=[15,8,80], ...) r = p.solve('cplex', iprint = 0, plot=1) f_opt, x_opt = r.ff, r.xf # x_opt = array([ -2.99999999, 9.5 , -16. ]) # f_opt = -770.24999989134858 openopt-0.38+svn1589/openopt/examples/qp_1.py000066400000000000000000000012041175775750500210150ustar00rootroot00000000000000""" Example: Concider the problem 0.5 * (x1^2 + 2x2^2 + 3x3^2) + 15x1 + 8x2 + 80x3 -> min (1) subjected to x1 + 2x2 + 3x3 <= 150 (2) 8x1 + 15x2 + 80x3 <= 800 (3) x2 - x3 = 25.5 (4) x1 <= 15 (5) """ from numpy import diag, matrix, inf from openopt import QP p = QP(diag([1, 2, 3]), [15, 8, 80], A = matrix('1 2 3; 8 15 80'), b = [150, 800], Aeq = [0, 1, -1], beq = 25.5, ub = [15,inf,inf]) # or p = QP(H=diag([1,2,3]), f=[15,8,80], A= ...) r = p._solve('cvxopt_qp', iprint = 0) f_opt, x_opt = r.ff, r.xf # x_opt = array([-15. , -2.5, -28. ]) # f_opt = -1190.25 openopt-0.38+svn1589/openopt/examples/sdp_1.py000066400000000000000000000016431175775750500211720ustar00rootroot00000000000000""" This is OpenOpt SDP example, for the problem http://openopt.org/images/1/12/SDP.png """ from numpy import mat from openopt import SDP S, d = {}, {} S[0, 0] = mat('-7 -11; -11 3') # numpy array, array-like, CVXOPT matrix are allowed as well S[0, 1] = mat('7 -18; -18 8') S[0, 2] = mat('-2 -8; -8 1') d[0] = mat('33, -9; -9, 26') S[1, 0] = mat('-21 -11 0; -11 10 8; 0 8 5') S[1, 1] = mat('0 10 16; 10 -10 -10; 16 -10 3') S[1, 2] = mat('-5 2 -17; 2 -6 8; -17 -7 6') d[1] = mat('14, 9, 40; 9, 91, 10; 40, 10, 15') p = SDP([1, -1, 1], S = S, d = d) # Also you can use A, b, Aeq, beq for linear matrix (in)equality constraints # and lb, ub for box-bound constraints lb <= x <= ub # see /examples/lp_1.py #r = p.solve('cvxopt_sdp', iprint = 0) r = p.solve('dsdp', iprint = -1) f_opt, x_opt = r.ff, r.xf print('x_opt: %s' % x_opt) print('f_opt: %s' % f_opt) #x_opt: [-0.36766609 1.89832827 -0.88755043] #f_opt: -3.15354478797 openopt-0.38+svn1589/openopt/examples/sle_1.py000066400000000000000000000005321175775750500211630ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import * from openopt import SLE N = 1000 C = empty((N,N)) d = 1.5+80*sin(arange(N)) for j in xrange(N): C[j] = 8*sin(4.0+arange(j, N+j)**2) + 15*cos(j) p = SLE(C, d) #r = p.solve('defaultSLEsolver'), or just r = p.solve() print('max residual: %e' % r.ff) #print('solution: %s' % r.xf) openopt-0.38+svn1589/openopt/examples/snle_1.py000077500000000000000000000024161175775750500213470ustar00rootroot00000000000000""" Solving system of equations: x[0]**3+x[1]**3-9 = 0 x[0]-0.5*x[1] = 0 cos(x[2])+x[0]-1.5 = 0 """ from openopt import SNLE from numpy import asfarray, zeros, cos, sin #f = lambda x: (x[0]**3+x[1]**3-9, x[0]-0.5*x[1], cos(x[2])+x[0]-1.5) # or: f = (lambda x: x[0]**3+x[1]**3-9, lambda x: x[0]-0.5*x[1], lambda x: cos(x[2])+x[0]-1.5) # Python list, numpy.array are allowed as well: #f = lambda x: [x[0]**3+x[1]**3-9, x[0]-0.5*x[1], cos(x[2])+x[0]-1.5] #or f = lambda x: asfarray((x[0]**3+x[1]**3-9, x[0]-0.5*x[1], cos(x[2])+x[0]-1.5)) # start point x0 = [8,15, 80] #optional: gradient df = (lambda x: [3*x[0]**2, 3*x[1]**2, 0], lambda x: [1, -0.5, 0], lambda x:[1, 0, -sin(x[2])]) #w/o gradient: #p = NLSP(f, x0) p = SNLE(f, x0, df = df) #optional: user-supplied gradient check: #p.checkdf() #optional: graphical output, requires matplotlib installed p.plot = 1 p.maxFunEvals = 1e5 p.iprint = 10 #r = p.solve('scipy_fsolve') #r = p.solve('nssolve') #or using converter nlsp2nlp, try to minimize sum(f_i(x)^2): r = p.solve('nlp:ralg', plot=1) print('solution: %s' % r.xf) print('max residual: %e' % r.ff) ############################### #should print: #solution: [ 1. 2. 55.50147021] (3rd coord may differ due to cos is periodic) #max residual: 2.72366951215e-09 openopt-0.38+svn1589/openopt/examples/socp_1.py000066400000000000000000000012571175775750500213510ustar00rootroot00000000000000""" OpenOpt SOCP example for the problem http://openopt.org/images/2/28/SOCP.png """ from numpy import * from openopt import SOCP f = array([-2, 1, 5]) C0 = mat('-13 3 5; -12 12 -6') d0 = [-3, -2] q0 = array([-12, -6, 5]) s0 = -12 C1 = mat('-3 6 2; 1 9 2; -1 -19 3') d1 = [0, 3, -42] q1 = array([-3, 6, -10]) s1 = 27 p = SOCP(f, C=[C0, C1], d=[d0, d1], q=[q0, q1], s=[s0, s1]) # you could add lb <= x <= ub, Ax <= b, Aeq x = beq constraints # via p = SOCP(f, ..., A=A, b=b, Aeq=Aeq, beq=beq,lb=lb, ub=ub) r = p.solve('cvxopt_socp') x_opt, f_opt = r.xf, r.ff print(' f_opt: %f x_opt: %s' % (f_opt, x_opt)) # f_opt: -38.346368 x_opt: [-5.01428121 -5.76680444 -8.52162517] openopt-0.38+svn1589/openopt/kernel/000077500000000000000000000000001175775750500172505ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/kernel/DFP.py000066400000000000000000000060071175775750500202360ustar00rootroot00000000000000from baseProblem import NonLinProblem from ooMisc import assignScript from numpy import sum, dot, asfarray, atleast_2d, array, zeros import NLP class DFP(NonLinProblem): _optionalData = ['lb', 'ub', 'A', 'Aeq', 'b', 'beq', 'c', 'h'] probType = 'DFP' expectedArgs = ['f', 'x0', 'X', 'Y'] allowedGoals = ['minimum', 'min'] goal = 'minimum' showGoal = False isObjFunValueASingleNumber = False def _Prepare(self): self.X = atleast_2d(self.X) self.Y = array(self.Y, float) if self.X.shape[0] != self.Y.shape[0]: if self.X.shape[1] != self.Y.shape[0]: self.err('incorrect shape of input data') else: self.X = self.X.T NonLinProblem._Prepare(self) #if self.Y.ndim if self.userProvided.df: assert len(self.user.df) == 1 self.dfff = self.user.df[0] def dff(x): r = zeros(self.n) for i in range(self.Y.shape[0]): #print asfarray(self.fff(x, self.X[i])-self.Y[i]), asfarray(self.dfff(x, self.X[i])) r += dot(2.0 * asfarray(self.fff(x, self.X[i])-self.Y[i]), asfarray(self.dfff(x, self.X[i]))) return r self.df = self.user.df = dff def __finalize__(self): NonLinProblem.__finalize__(self) if self.userProvided.df: self.df = self.dfff self.f = self.fff def __init__(self, *args, **kwargs): NonLinProblem.__init__(self, *args, **kwargs) assignScript(self, kwargs) self.fff = self.f def ff(x): r = [] for i in range(self.Y.shape[0]): r.append(asfarray(self.fff(x, self.X[i])-self.Y[i])**2) return r self.f = ff def objFuncMultiple2Single(self, fv): assert all(fv.flatten()>=0) return fv.sum() # they are squared in other place def dfp2nlp(self, solver, **solver_params): ff = lambda x: (asfarray(self.f(x))).sum() if self.userProvided.df: #dff = lambda x: dot(2*asfarray(ff(x)), asfarray(self.df(x))) p = NLP.NLP(ff, self.x0, df=self.df) else: p = NLP.NLP(ff, self.x0) #p = NLP.NLP(lambda x: self.f(x), self.x0) #if self.userProvided.df: p.df = dff self.inspire(p, sameConstraints=True) p.f = ff # to prefent overwriting def dfp_iterfcn(*args, **kwargs): self.iterfcn(*args, **kwargs) if self.istop != 0: p.istop, p.msg = self.istop, self.msg tmp_iterfcn(*args, **kwargs) if p.istop != 0: self.istop, self.msg = p.istop, p.msg p.iterfcn, tmp_iterfcn = dfp_iterfcn, p.iterfcn #p.iprint = -1 self.iprint = -1 if self.plot: self.plot, p.plot = 0, 1 p.show = self.show #p.show = False p.checkdf() r = p.solve(solver, **solver_params) #r.ff = ff(r.xf) return r openopt-0.38+svn1589/openopt/kernel/EIG.py000066400000000000000000000071741175775750500202370ustar00rootroot00000000000000from baseProblem import MatrixProblem #from numpy.linalg import norm from numpy import vstack, isscalar class EIG(MatrixProblem): probType = 'EIG' goal = 'all' allowedGoals = None showGoal = True expectedArgs = ['C'] M = None _optionalData = ['M'] xtol = 0.0 FuncDesignerSign = 'C' N = 0 #ftol = None def __init__(self, *args, **kwargs): MatrixProblem.__init__(self, *args, **kwargs) if self.goal == 'all': Name, name = 'all eigenvectors and eigenvalues', 'all' if not isinstance(self.C[0], dict): self.N = self.C.shape[0] else: assert type(self.goal) in (dict, tuple, list) and len(self.goal) == 1, \ 'EIG goal argument should be "all" or Python dict {goal_name: number_of_required_eigenvalues}' if type(self.goal) == dict: goal_name, N = list(self.goal.items())[0] else: goal_name, N = self.goal self.N = N name = ''.join(goal_name.lower().split()) if name in ('lm', 'largestmagnitude'): Name, name = 'largest magnitude', 'le' elif name in ('sm', 'smallestmagnitude'): Name, name = 'smallest magnitude', 'sm' elif name in ('lr', 'largestrealpart'): Name, name = 'largest real part', 'lr' elif name in ('sr', 'smallestrealpart'): Name, name = 'smallest real part', 'sr' elif name in ('li', 'largestimaginarypart'): Name, name = 'largest imaginary part', 'li' elif name in ('si', 'smallestimaginarypart'): Name, name = 'smallest imaginary part', 'si' elif name in ('la', 'largestamplitude'): Name, name = 'largestamplitude', 'la' elif name in ('sa', 'smallestamplitude'): Name, name = 'smallest amplitude', 'sa' elif name in ('be', 'bothendsofthespectrum'): Name, name = 'both ends of the spectrum', 'be' self.goal = Name self._goal = name #if not isinstance(self.C[0], dict): def solve(self, *args, **kw): C = self.C if type(C) in (tuple, list) and isinstance(C[0], dict): from FuncDesigner import ootranslator K = set() N = 0 varSizes = {} for d in C: K.update(d.keys()) for key in d.keys(): if key in varSizes: if varSizes[key] != d[key].shape[1]: s = 'incorrect shape 2nd coordinate %d for variable %s, defined in other array as %d' %(d[key].shape[1], key.name, varSizes[key]) self.err(s) else: varSizes[key] = d[key].shape[1] if not isscalar(d[key]) else 1 tmp = list(d.values()) N += tmp[0].shape[0] if not isscalar(tmp[0]) else 1 P = dict([(key, [0]*val) for key, val in varSizes.items()]) T = ootranslator(P) C2 = vstack([T.pointDerivative2array(d) for d in C]) self.C = C2 if C2.shape != (N, N): self.err('square matrix of shape (%d,%d) expected, shape %s obtained instead' % (N, N, C2.shape)) r = MatrixProblem.solve(self, *args, **kw) if type(C) in (tuple, list) and isinstance(C[0], dict): r.eigenvectors = [T.vector2point(v) for v in self.eigenvectors.T] return r def objFunc(self, x): return 0 #raise 'unimplemented yet' openopt-0.38+svn1589/openopt/kernel/GLP.py000066400000000000000000000036771175775750500202610ustar00rootroot00000000000000from ooMisc import assignScript from baseProblem import NonLinProblem from numpy import asarray, ones, inf, array from setDefaultIterFuncs import MAX_NON_SUCCESS class GLP(NonLinProblem): probType = 'GLP' _optionalData = ['lb', 'ub', 'c', 'A', 'b'] expectedArgs = ['f', 'x0'] allowedGoals = ['minimum', 'min', 'maximum', 'max'] goal = 'minimum' showGoal = False isObjFunValueASingleNumber = True plotOnlyCurrentMinimum= True _currentBestPoint = None _nonSuccessCounter = 0 maxNonSuccess = 15 def __init__(self, *args, **kwargs): #if len(args) > 1: self.err('incorrect args number for GLP constructor, must be 0..1 + (optionaly) some kwargs') NonLinProblem.__init__(self, *args, **kwargs) def maxNonSuccess(p): newPoint = p.point(p.xk) if self._currentBestPoint is None: self._currentBestPoint = newPoint return False elif newPoint.betterThan(self._currentBestPoint): self._currentBestPoint = newPoint self._nonSuccessCounter = 0 return False self._nonSuccessCounter += 1 if self._nonSuccessCounter > self.maxNonSuccess: return (True, 'Non-Success Number > maxNonSuccess = ' + str(self.maxNonSuccess)) else: return False self.kernelIterFuncs[MAX_NON_SUCCESS] = maxNonSuccess if 'lb' in kwargs.keys(): self.n = len(kwargs['lb']) elif 'ub' in kwargs.keys(): self.n = len(kwargs['ub']) elif 'b' in kwargs.keys(): self.n = asarray(b).size if hasattr(self, 'n'): if not hasattr(self, 'lb'): self.lb = -inf * ones(self.n) if not hasattr(self, 'ub'): self.ub = inf * ones(self.n) if 'x0' not in kwargs.keys(): self.x0 = (asarray(self.lb) + asarray(self.ub)) / 2.0 openopt-0.38+svn1589/openopt/kernel/GUI.py000066400000000000000000000125011175775750500202450ustar00rootroot00000000000000# sometimes Tkinter is not installed TkinterIsInstalled = True import platform if platform.python_version()[0] == '2': # Python2 try: from Tkinter import Tk, Toplevel, Button, Entry, Menubutton, Label, Frame, StringVar, DISABLED, ACTIVE except: TkinterIsInstalled = False else: # Python3 try: from tkinter import Tk, Toplevel, Button, Entry, Menubutton, Label, Frame, StringVar, DISABLED, ACTIVE except: TkinterIsInstalled = False from threading import Thread from openopt import __version__ as ooversion from setDefaultIterFuncs import BUTTON_ENOUGH_HAS_BEEN_PRESSED, USER_DEMAND_EXIT from ooMisc import killThread from runProbSolver import finalShow def manage(p, *args, **kwargs): p.isManagerUsed = True if not TkinterIsInstalled: p.err('Tkinter is not installed. If you have Linux you could try using "apt-get install python-tk"') # expected args are (solver, start) or (start, solver) or one of them p._args = args p._kwargs = kwargs for arg in args: if type(arg) == str or hasattr(arg, '__name__'): p.solver = arg elif arg in (0, 1, True, False): start = arg else: p.err('Incorrect argument for manage()') start = kwargs.pop('start', True) if 'solver' in kwargs.keys(): p.solver = kwargs['solver'] # root root = Tk() p.GUI_root = root # Title #root.wm_title('OpenOpt ' + ooversion) p.GUI_buttons = {} """ Buttons """ # OpenOpt label Frame(root).pack(ipady=4) Label(root, text=' OpenOpt ' + ooversion + ' ').pack() Label(root, text=' Solver: ' + (p.solver if isinstance(p.solver, str) else p.solver.__name__) + ' ').pack() Label(root, text=' Problem: ' + p.name + ' ').pack() #TODO: use Menubutton #Statistics # stat = StringVar() # stat.set('') # Statistics = Button(root, textvariable = stat, command = lambda: invokeStatistics(p)) # cw = Entry(root) # # # b = Button(root, text = 'Evaluate!', command = lambda: invokeCommand(cw)) # cw.pack(fill='x', side='left') # b.pack(side='right') # Run t = StringVar() t.set(" Run ") RunPause = Button(root, textvariable = t, command = lambda: invokeRunPause(p)) Frame(root).pack(ipady=8) RunPause.pack(ipady=15) p.GUI_buttons['RunPause'] = RunPause p.statusTextVariable = t # Enough def invokeEnough(): p.userStop = True p.istop = BUTTON_ENOUGH_HAS_BEEN_PRESSED if hasattr(p, 'stopdict'): p.stopdict[BUTTON_ENOUGH_HAS_BEEN_PRESSED] = True p.msg = 'button Enough has been pressed' if p.state == 'paused': invokeRunPause(p, isEnough=True) else: RunPause.config(state=DISABLED) Enough.config(state=DISABLED) Frame(root).pack(ipady=8) Enough = Button(root, text = ' Enough! ', command = invokeEnough) Enough.config(state=DISABLED) Enough.pack() p.GUI_buttons['Enough'] = Enough # Exit def invokeExit(): p.userStop = True p.istop = USER_DEMAND_EXIT if hasattr(p, 'stopdict'): p.stopdict[USER_DEMAND_EXIT] = True # however, the message is currently unused # since openopt return r = None p.msg = 'user pressed Exit button' root.destroy() Frame(root).pack(ipady=8) Button(root, text=" Exit ", command = invokeExit).pack(ipady=15) """ Start main loop """ state = 'paused' if start: Thread(target=invokeRunPause, args=(p, )).start() root.mainloop() #finalShow(p) """ Handle result """ if hasattr(p, 'tmp_result'): r = p.tmp_result delattr(p, 'tmp_result') else: r = None """ Return """ return r def invokeRunPause(p, isEnough=False): try: import pylab except: if p.plot: p.warn('to use graphics you should have matplotlib installed') p.plot = False if isEnough: p.GUI_buttons['RunPause'].config(state=DISABLED) if p.state == 'init': p.probThread = Thread(target=doCalculations, args=(p, )) p.state = 'running' p.statusTextVariable.set(' Pause ') p.GUI_buttons['Enough'].config(state=ACTIVE) p.GUI_root.update_idletasks() p.probThread.start() elif p.state == 'running': p.state = 'paused' if p.plot: pylab.ioff() p.statusTextVariable.set(' Run ') p.GUI_root.update_idletasks() elif p.state == 'paused': p.state = 'running' if p.plot: pylab.ion() p.statusTextVariable.set(' Pause ') p.GUI_root.update_idletasks() def doCalculations(p): try: p.tmp_result = p.solve(*p._args, **p._kwargs) except killThread: if p.plot: if hasattr(p, 'figure'): #p.figure.canvas.draw_drawable = lambda: None pylab.ioff() pylab.close('all') #def invokeStatistics(p): def invokeCommand(cw): exec(cw.get()) openopt-0.38+svn1589/openopt/kernel/IP.py000066400000000000000000000015321175775750500201330ustar00rootroot00000000000000from baseProblem import NonLinProblem #from numpy.linalg import norm from numpy import inf class IP(NonLinProblem): probType = 'IP' goal = 'solution' allowedGoals = ['solution'] showGoal = False _optionalData = [] expectedArgs = ['f', 'domain'] ftol = None def __init__(self, *args, **kwargs): NonLinProblem.__init__(self, *args, **kwargs) domain = args[1] self.x0 = dict([(v, 0.5*(val[0]+val[1])) for v, val in domain.items()]) self.constraints = [v>bounds[0] for v, bounds in domain.items()] + [v 2: self.err('incorrect args number for LLAVP constructor, must be 0..2 + (optionaly) some kwargs') if len(args) > 0: kwargs['C'] = args[0] if len(args) > 1: kwargs['d'] = args[1] MatrixProblem.__init__(self) llavp_init(self, kwargs) def objFunc(self, x): r = norm(dot(self.C, x) - self.d, 1) if not self.damp is None: r += self.damp * norm(x-self.X, 1) #if any(isfinite(self.f)): r += dot(self.f, x) return r def llavp2nsp(self, solver, **solver_params): if hasattr(self,'x0'): p = NSP.NSP(ff, self.x0, df=dff) else: p = NSP.NSP(ff, zeros(self.n), df=dff) p.args.f = self # DO NOT USE p.args = self IN PROB ASSIGNMENT! self.inspire(p) self.iprint = -1 # for LLAVP plot is via NLP p.show = self.show p.plot, self.plot = self.plot, 0 #p.checkdf() #p.solver.__optionalDataThatCanBeHandled__ += ['damp', 'X', 'c'] r = p.solve(solver, **solver_params) self.xf, self.ff, self.rf = r.xf, r.ff, r.rf return r def _Prepare(self): MatrixProblem._Prepare(self) if not self.damp is None and not any(isfinite(self.X)): self.X = zeros(self.n) def llavp_init(prob, kwargs): prob.probType = 'LLAVP' prob.goal = 'minimum' prob.allowedGoals = ['minimum', 'min'] prob.showGoal = False kwargs['C'] = asfarray(kwargs['C']) prob.n = kwargs['C'].shape[1] prob.lb = -inf * ones(prob.n) prob.ub = inf * ones(prob.n) if 'damp' not in kwargs.keys(): kwargs['damp'] = None if 'X' not in kwargs.keys(): kwargs['X'] = nan*ones(prob.n) if prob.x0 is None: prob.x0 = zeros(prob.n) return assignScript(prob, kwargs) ff = lambda x, LLAVprob: LLAVprob.objFunc(x) def dff(x, LLAVprob): r = dot(sign(dot(LLAVprob.C, x) - LLAVprob.d), LLAVprob.C) #r = (LLAVprob.C * sign(dot(LLAVprob.C, x) - LLAVprob.d)).sum(0) if not LLAVprob.damp is None: r += LLAVprob.damp * (sign(x - LLAVprob.X)).sum(0) return r openopt-0.38+svn1589/openopt/kernel/LLSP.py000066400000000000000000000066311175775750500204020ustar00rootroot00000000000000from ooMisc import assignScript from baseProblem import MatrixProblem from numpy import asfarray, ones, inf, dot, nan, zeros, any, all, isfinite, eye, vstack from ooMisc import norm import NLP class LLSP(MatrixProblem): _optionalData = ['damp', 'X', 'c'] expectedArgs = ['C', 'd']# for FD it should be Cd and x0 probType = 'LLSP' goal = 'minimum' allowedGoals = ['minimum', 'min'] showGoal = False FuncDesignerSign = 'C' def __init__(self, *args, **kwargs): MatrixProblem.__init__(self, *args, **kwargs) if 'damp' not in kwargs.keys(): self.damp = None if 'f' not in kwargs.keys(): self.f = None if not self._isFDmodel(): if len(args)>0: self.n = args[0].shape[1] else: self.n = kwargs['C'].shape[1] #self.lb = -inf * ones(self.n) #self.ub = inf * ones(self.n) if not hasattr(self, 'lb'): self.lb = -inf * ones(self.n) if not hasattr(self, 'ub'): self.ub = inf * ones(self.n) if self.x0 is None: self.x0 = zeros(self.n) else: # is FD model if type(self.C) not in (set, tuple, list): if 'is_oovar' not in dir(self.C): s = ''' Icorrect data type for LLSP constructor, first argument should be numpy ndarray, scipy sparse matrix, FuncDesigner oofun or list of oofuns''' p.err(s) self.C = [self.C] def objFunc(self, x): r = norm(self.matMultVec(self.C, x) - self.d) ** 2 / 2.0 if self.damp is not None: r += self.damp * norm(x-self.X)**2 / 2.0 if self.f is not None: r += dot(self.f, x) return r def llsp2nlp(self, solver, **solver_params): if hasattr(self,'x0'): p = NLP.NLP(ff, self.x0, df=dff, d2f=d2ff) else: p = NLP.NLP(ff, zeros(self.n), df=dff, d2f=d2ff) p.args.f = self # DO NOT USE p.args = self IN PROB ASSIGNMENT! self.inspire(p) self.iprint = -1 # for LLSP plot is via NLP p.show = self.show p.plot, self.plot = self.plot, 0 #p.checkdf() r = p.solve(solver, **solver_params) self.xf, self.ff, self.rf = r.xf, r.ff, r.rf return r def _Prepare(self): if isinstance(self.d, dict): # FuncDesigner startPoint self.x0 = self.d MatrixProblem._Prepare(self) if self.isFDmodel: self.C, self.d = self._linearOOFunsToMatrices(self.C) if not self.damp is None and (not hasattr(self, 'X') or not any(isfinite(self.X))): self.X = zeros(self.n) #def llsp_init(prob, kwargs): # if 'damp' not in kwargs.keys(): kwargs['damp'] = None # if 'X' not in kwargs.keys(): kwargs['X'] = nan*ones(prob.n) # if 'f' not in kwargs.keys(): kwargs['f'] = nan*ones(prob.n) # # if prob.x0 is nan: prob.x0 = zeros(prob.n) #def ff(x, LLSPprob): # r = dot(LLSPprob.C, x) - LLSPprob.d # return dot(r, r) ff = lambda x, LLSPprob: LLSPprob.objFunc(x) def dff(x, p): r = p.matMultVec(p.C.T, p.matMultVec(p.C,x) - p.d) if p.damp is not None and p.damp != 0: r += p.damp*(x - LLSPprob.X) if p.f is not None and all(isfinite(p.f)) : r += p.f return r def d2ff(x, p): # TODO: handle sparse! r = dot(p.C.T, p.C) if not p.damp is None: r += p.damp*eye(x.size) return r openopt-0.38+svn1589/openopt/kernel/LP.py000066400000000000000000000170441175775750500201430ustar00rootroot00000000000000from baseProblem import MatrixProblem from numpy import asarray, ones, inf, dot, nan, zeros, isnan, any, vstack, array, asfarray, atleast_1d import NLP class LP(MatrixProblem): _optionalData = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub'] expectedArgs = ['f', 'x0'] probType = 'LP' allowedGoals = ['minimum', 'min', 'max', 'maximum'] showGoal = True _lp_prepared = False def __init__(self, *args, **kwargs): self.goal = 'minimum' MatrixProblem.__init__(self, *args, **kwargs) if len(args) > 1 and not hasattr(args[0], 'is_oovar'): self.err('No more than 1 argument is allowed for classic style LP constructor') def _Prepare(self): if self._lp_prepared: return self._lp_prepared = True MatrixProblem._Prepare(self) if self.x0 is None: self.x0 = zeros(self.n) if hasattr(self.f, 'is_oovar'): # hence is oofun or oovar # freeVars and fixedVars are already rendered to both not-None here (if it's the case) # but current .D() implementation doesn't allow to use both arguments # BTW translator ignores fixed vars in derivatives, so passing fixedVars here can be omitted # but is performed for more safety wrt future changes _f = self._point2vector(self.f.D(self._x0, fixedVars = self.fixedVars)) self.f, self._f = _f, self.f self._init_f_vector = _f # we don't take p.goal into account here _c = self._f(self._x0) - dot(self.f, self.x0) self._c = _c else: self._init_f_vector = self.f # we don't take p.goal into account here self._c = 0 self.f = atleast_1d(self.f) if not hasattr(self, 'n'): self.n = len(self.f) #print 'lb:', self.lb, 'ub:', self.ub if not hasattr(self, 'lb'): self.lb = -inf * ones(self.n) if not hasattr(self, 'ub'): self.ub = inf * ones(self.n) # if any(isnan(self.lb)): # if self.lb.size != 1: self.err('NaN in lower bound for a variable from the problem') # self.lb = -inf * ones(self.n) # if any(isnan(self.ub)): # if self.ub.size != 1: self.err('NaN in upper bound for a variable from the problem') # self.ub = inf * ones(self.n) if self.goal in ['max', 'maximum']: self.f = -asfarray(self.f) # TODO: handle this and SDP finalize in single func finalize_for_max def __finalize__(self): MatrixProblem.__finalize__(self) if self.goal in ['max', 'maximum']: self.f = -self.f for fn in ['fk', ]:#not ff - it's handled in other place in RunProbSolver.py if hasattr(self, fn): setattr(self, fn, -getattr(self, fn)) if hasattr(self, '_f'): self.f = self._f def objFunc(self, x): return dot(self.f, x) + self._c def lp2nlp(self, solver, **solver_params): if self.isConverterInvolved and self.goal in ['max', 'maximum']: self.err('maximization problems are not implemented lp2nlp converter') ff = lambda x: dot(x, self.f)+self._c dff = lambda x: self.f if hasattr(self,'x0'): p = NLP.NLP(ff, self.x0, df=dff) else: p = NLP.NLP(ff, zeros(self.n), df=dff) self.inspire(p) self.iprint = -1 # for LP plot is via NLP p.show = self.show p.plot, self.plot = self.plot, 0 if self.isFDmodel: p._x0 = self._x0 # may be used in interalg r = p.solve(solver, **solver_params) self.xf, self.ff, self.rf = r.xf, r.ff, r.rf return r def exportToMPS(self, filename, format='fixed', startIndex=0): try: from lp_solve import lpsolve except ImportError: self.err('To export LP/MILP in files you should have lpsolve and its Python binding properly installed') maxNameLength = 8 if format != 'free' else 255 handler = self.get_lpsolve_handler(maxNameLength, startIndex) # TODO: uncomment it ext = 'mps' if not filename.endswith('MPS') and not filename.endswith('mps') else '' if ext != '': filename += '.' + ext if format=='fixed': r = bool(lpsolve('write_mps', handler, filename) ) elif format=='free': r = bool(lpsolve('write_freemps', handler, filename) ) else: self.err('incorrect MPS format, should be "fixed" or "free"') if r != True: self.warn('Failed to write MPS file, maybe read-only filesystem, incorrect path or write access is absent') lpsolve('delete_lp', handler) return r def get_lpsolve_handler(self, maxNameLength=255, startIndex=0): try: from lp_maker import lp_maker, lpsolve except ImportError: self.err('To export LP/MILP in files you should have lpsolve and its Python binding properly installed') self._Prepare() from ooMisc import LinConst2WholeRepr LinConst2WholeRepr(self) # set goal to min/max minim = 0 if self.goal in ['max', 'maximum'] else 1 # objective f = self._init_f_vector lp_handle = lp_maker(List(asarray(f).flatten()), List(self.Awhole), List(asarray(self.bwhole).flatten()), List(asarray(self.dwhole).flatten()), \ List(self.lb), List(self.ub), (1+asarray(self._intVars_vector)).tolist(), 0,minim) #lp_handle = lpsolve('make_lp', len(self.beq)+len(self.b), self.n) L = lambda action, *args: lpsolve(action, lp_handle, *args) # set name L('set_lp_name', self.name) # set boolean values if present #if len(self.boolVars)>0: #assert self.boolVars[0] in [True, False] #L('set_binary', self.boolVars) # set variables names if self.isFDmodel: assert not isinstance(self.freeVars, set), 'error in openopt kernel, inform developers' #assert len(self.freeVars) == self.n, 'not implemented yet for oovars of size > 1' #names = [oov.name for oov in self.freeVars] x0 = self._x0 names = [] #assert not isinstance(self.freeVars, set), 'error in openopt kernel, inform developers' for oov in self.freeVars: if oov.name.startswith('unnamed'): L('delete_lp') self.err('For exporting FuncDesigner models into MPS files you cannot have variables with names starting with "unnamed"') if ' ' in oov.name: L('delete_lp') self.err('For exporting FuncDesigner models into MPS files you cannot have variables with spaces in names') Size = asarray(x0[oov]).size if Size == 1: Name = oov.name names.append(Name) else: tmp = [(oov.name + ('_%d' % (startIndex+j))) for j in range(Size)] names += tmp Name = tmp[-1] if maxNameLength < len(Name): L('delete_lp') self.err('incorrect name "%s" - for exporting FuncDesigner models into MPS files you cannot have variables with names of length > maxNameLength=%d'% maxNameLength) # TODO: check are names unique L('set_col_name', names) return lp_handle def List(x): if isinstance(x, list): return x elif x == None or x.size == 0: return None else: return x.tolist() openopt-0.38+svn1589/openopt/kernel/LUNP.py000066400000000000000000000055001175775750500204000ustar00rootroot00000000000000from ooMisc import assignScript from baseProblem import MatrixProblem from numpy import asfarray, ones, inf, dot, nan, zeros, any, all, isfinite, eye, hstack, vstack, asarray, atleast_2d from ooMisc import norm import LP class LUNP(MatrixProblem): probType = 'LUNP' goal = 'minimum' allowedGoals = ['minimum', 'min'] showGoal = False _optionalData = [] expectedArgs = ['C', 'd'] def __init__(self, *args, **kwargs): MatrixProblem.__init__(self, *args, **kwargs) self.n = self.C.shape[1] # if 'damp' not in kwargs.keys(): kwargs['damp'] = None # if 'X' not in kwargs.keys(): kwargs['X'] = nan*ones(self.n) if self.x0 is None: self.x0 = zeros(self.n) #lunp_init(self, kwargs) def objFunc(self, x): r = norm(dot(self.C, x) - self.d, inf) # if not self.damp is None: # r += self.damp * norm(x-self.X)**2 / 2.0 # if any(isfinite(self.f)): r += dot(self.f, x) return r def lunp2lp(self, solver, **solver_params): shapeC = atleast_2d(self.C).shape nVars = shapeC[1] + 1 nObj = shapeC[0] f = hstack((zeros(nVars))) f[-1] = 1 p = LP.LP(f) # TODO: check - is it performed in self.inspire(p)? if hasattr(self,'x0'): p.x0 = self.x0 #p.args.f = self # DO NOT USE p.args = self IN PROB ASSIGNMENT! self.inspire(p) p.x0 = hstack((p.x0, [0])) p.A = vstack((hstack((self.A, zeros((atleast_2d(self.A).shape[0], 1)))), \ hstack((self.C, -ones((nObj, 1)))), \ hstack((-self.C, -ones((nObj, 1)))))) p.b = hstack((p.b, self.d, -self.d)) p.lb = hstack((p.lb, -inf)) p.ub = hstack((p.ub, inf)) p.Aeq = hstack((self.Aeq, zeros((atleast_2d(self.Aeq).shape[0], 1)))) #p.iprint = -1 self.iprint = -1 # for LLSP plot is via NLP #p.show = self.show #p.plot, self.plot = self.plot, 0 #p.checkdf() r = p.solve(solver, **solver_params) self.xf, self.ff, self.rf = r.xf[:-1], r.ff, r.rf self.istop, self.msg = p.istop, p.msg return r # def _Prepare(self): # MatrixProblem._Prepare(self) # if not self.damp is None and not any(isfinite(self.X)): # self.X = zeros(self.n) #def ff(x, LLSPprob): # r = dot(LLSPprob.C, x) - LLSPprob.d # return dot(r, r) #ff = lambda x, LLSPprob: LLSPprob.objFunc(x) #def dff(x, LLSPprob): # r = dot(LLSPprob.C.T, dot(LLSPprob.C,x) - LLSPprob.d) # if not LLSPprob.damp is None: r += LLSPprob.damp*(x - LLSPprob.X) # if all(isfinite(LLSPprob.f)) : r += LLSPprob.f # return r # #def d2ff(x, LLSPprob): # r = dot(LLSPprob.C.T, LLSPprob.C) # if not LLSPprob.damp is None: r += LLSPprob.damp*eye(x.size) # return r openopt-0.38+svn1589/openopt/kernel/MILP.py000066400000000000000000000076741175775750500204010ustar00rootroot00000000000000from baseProblem import MatrixProblem from numpy import asarray, ones, inf, dot, nan, zeros, ceil, floor, argmax, ndarray, copy from setDefaultIterFuncs import SMALL_DELTA_X, SMALL_DELTA_F from LP import LP class MILP(LP): _optionalData = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'intVars', 'boolVars'] storeIterPoints = False probType = 'MILP' expectedArgs = ['f', 'x0'] allowedGoals = ['minimum', 'min', 'max', 'maximum'] showGoal = True _milp_prepared = False def _Prepare(self): if self._milp_prepared: return self._milp_prepared = True LP._Prepare(self) r = [] if type(self.intVars) not in [list, tuple, set] and not isinstance(self.intVars, ndarray): self.intVars = [self.intVars] if self.isFDmodel: ########### obsolete, to be removed in future versions if self.intVars != []: s = ''' For FuncDesigner models prob parameter intVars is deprecated and will be removed in future versions, use oovar(..., domain = int) instead''' self.pWarn(s) for iv in self.intVars: if self.fixedVars is not None and iv in self.fixedVars or\ self.freeVars is not None and iv not in self.freeVars: continue r1, r2 = self._oovarsIndDict[iv] r += range(r1, r2) ########### obsolete, to be removed in future versions for v in self._freeVarsList: if isinstance(v.domain, (tuple, list, ndarray, set)): self.err('for FuncDesigner MILP models only variables with domains int, bool or None (real) are implemented for now') if v.domain in (int, 'int', bool, 'bool'): r1, r2 = self._oovarsIndDict[v] r += range(r1, r2) self.intVars, self._intVars = r, self.intVars self._intVars_vector = self.intVars if SMALL_DELTA_X in self.kernelIterFuncs: self.kernelIterFuncs.pop(SMALL_DELTA_X) if SMALL_DELTA_F in self.kernelIterFuncs: self.kernelIterFuncs.pop(SMALL_DELTA_F) def getMaxResidualWithIntegerConstraints(x, retAll = False): r, fname, ind = self.getMaxResidual2(x, True) if len(self.intVars) != 0: intV = x[self.intVars] intDifference = abs(intV-intV.round()) intConstraintNumber = argmax(intDifference) intConstraint = intDifference[intConstraintNumber] #print 'intConstraint:', intConstraint if intConstraint > r: intConstraintNumber = self.intVars[intConstraintNumber] r, fname, ind = intConstraint, 'int', intConstraintNumber if retAll: return r, fname, ind else: return r self.getMaxResidual, self.getMaxResidual2 = getMaxResidualWithIntegerConstraints, self.getMaxResidual # TODO: # 1) ADD BOOL VARS self.lb, self.ub = copy(self.lb), copy(self.ub) self.lb[self.intVars] = ceil(self.lb[self.intVars]) self.ub[self.intVars] = floor(self.ub[self.intVars]) # if self.goal in ['max', 'maximum']: # self.f = -self.f def __finalize__(self): LP.__finalize__(self) if self.isFDmodel: self.intVars = self._intVars # def __finalize__(self): # MatrixProblem.__finalize__(self) # if self.goal in ['max', 'maximum']: # self.f = -self.f # for fn in ['fk', ]:#not ff - it's handled in other place in RunProbSolver.py # if hasattr(self, fn): # setattr(self, fn, -getattr(self, fn)) # def __init__(self, *args, **kwargs): # LP.__init__(self, *args, **kwargs) def objFunc(self, x): return dot(self.f, x) + self._c #return dot(self.f, x) openopt-0.38+svn1589/openopt/kernel/MINLP.py000066400000000000000000000040161175775750500205020ustar00rootroot00000000000000from ooMisc import assignScript from baseProblem import NonLinProblem from numpy import asarray, ones, inf, array, sort, ndarray class MINLP(NonLinProblem): _optionalData = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h', 'discreteVars'] probType = 'MINLP' allowedGoals = ['minimum', 'min', 'maximum', 'max'] showGoal = True plotOnlyCurrentMinimum = True discrtol = 1e-5 # tolerance required for discrete constraints expectedArgs = ['f', 'x0'] def __init__(self, *args, **kwargs): self.goal = 'minimum' self.discreteVars = {} NonLinProblem.__init__(self, *args, **kwargs) self.iprint=1 def _Prepare(self): if hasattr(self, 'prepared') and self.prepared == True: return NonLinProblem._Prepare(self) if self.isFDmodel: r = {} for iv in self.freeVars: if iv.domain is None: continue ind1, ind2 = self._oovarsIndDict[iv] assert ind2-ind1 == 1 r[ind1] = iv.domain self.discreteVars = r # TODO: use something else instead of dict.keys() for key in self.discreteVars.keys(): fv = self.discreteVars[key] if type(fv) not in [list, tuple, ndarray] and fv not in ('bool', bool): self.err('each element from discreteVars dictionary should be list or tuple of allowed values') if fv is not bool and fv is not 'bool': fv = sort(fv) lowest = 0 if fv is bool or fv is 'bool' else fv[0] biggest = 1 if fv is bool or fv is 'bool' else fv[-1] if lowest > self.ub[key]: self.err('variable '+ str(key)+ ': smallest allowed discrete value ' + str(fv[0]) + ' exeeds imposed upper bound '+ str(self.ub[key])) if biggest < self.lb[key]: self.err('variable '+ str(key)+ ': biggest allowed discrete value ' + str(fv[-1]) + ' is less than imposed lower bound '+ str(self.lb[key])) self.discreteVars[key] = fv openopt-0.38+svn1589/openopt/kernel/MMP.py000066400000000000000000000047711175775750500202640ustar00rootroot00000000000000from baseProblem import NonLinProblem from NLP import NLP from numpy import max, array, hstack, vstack, zeros, ones, inf, asfarray, atleast_2d class MMP(NonLinProblem): """ Mini-Max Problem """ _optionalData = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] expectedArgs = ['f', 'x0'] allowedGoals = ['minimax'] probType = 'MMP' isObjFunValueASingleNumber = False showGoal = True goal = 'minimax' def __init__(self, *args, **kwargs): NonLinProblem.__init__(self, *args, **kwargs) def objFuncMultiple2Single(self, fv): return max(fv) def mmp2nlp(self, solver, **solver_params): f = lambda x: x[-1] DF = array([0]*self.n + [1]) df = lambda x: DF.copy() def iterfcn(*args, **kwargs): p2.primalIterFcn(*args, **kwargs) self.xk = p2.xk[:-1].copy() self.fk = p2.fk self.rk = p2.rk self.istop = p2.istop if self.istop and p2.rk <= p2.contol: self.msg = p2.msg self.iterfcn() p2 = NLP(f, hstack((self.x0, max(self.f(self.x0)))), df=df, xtol = self.xtol, ftol = self.ftol, gtol = self.gtol,\ A=hstack((self.A, zeros((len(self.b), 1)))), b=self.b, Aeq=hstack((self.Aeq, zeros((len(self.beq), 1)))), beq=self.beq, lb=hstack((self.lb, -inf)), ub=hstack((self.ub, inf)), \ maxFunEvals = self.maxFunEvals, fEnough = self.fEnough, maxIter=self.maxIter, iprint = -1, \ maxtime = self.maxTime, maxCPUTime = self.maxCPUTime, noise = self.noise) if self.userProvided.c: arr_dc = array([0]*self.nc + [-1]*self.nf).reshape(-1, 1) p2.c = lambda x: hstack((self.c(x[:-1]), self.f(x[:-1])-x[-1])) p2.dc = lambda x: hstack((vstack((self.dc(x[:-1]), self.df(x[:-1]))), arr_dc)) else: p2.c = lambda x: self.f(x[:-1])-x[-1] arr_dc = -ones((self.nf, 1)) p2.dc = lambda x: hstack((atleast_2d(self.df(x[:-1]), arr_dc))) if self.userProvided.h: arr_dh = array([0]*self.nh).reshape(-1, 1) p2.h = lambda x: self.h(x[:-1]) p2.dh = lambda x: hstack((atleast_2d(self.dh(x[:-1])), arr_dh)) p2.primalIterFcn, p2.iterfcn = p2.iterfcn, iterfcn #p2.checkdc() r2 = p2.solve(solver) #xf = fsolve(self.f, self.x0, fprime=self.df, xtol = self.xtol, maxfev = self.maxFunEvals) xf = r2.xf[:-1] self.xk = self.xf = xf self.fk = self.ff = max(self.f(xf)) openopt-0.38+svn1589/openopt/kernel/MOP.py000066400000000000000000000203221175775750500202540ustar00rootroot00000000000000from baseProblem import NonLinProblem from numpy import inf from openopt.kernel.setDefaultIterFuncs import SMALL_DELTA_X, SMALL_DELTA_F class MOP(NonLinProblem): _optionalData = ['lb', 'ub', 'A', 'Aeq', 'b', 'beq', 'c', 'h'] showGoal = True goal = 'weak Pareto front' probType = 'MOP' allowedGoals = ['weak Pareto front', 'strong Pareto front', 'wpf', 'spf'] isObjFunValueASingleNumber = False expectedArgs = ['f', 'x0'] _frontLength = 0 _nIncome = 0 _nOutcome = 0 iprint = 1 def __init__(self, *args, **kwargs): NonLinProblem.__init__(self, *args, **kwargs) self.nSolutions = 'all' self.kernelIterFuncs.pop(SMALL_DELTA_X, None) self.kernelIterFuncs.pop(SMALL_DELTA_F, None) self.data4TextOutput = ['front length', 'income', 'outcome', 'log10(maxResidual)'] f = self.f i = 0 targets = [] while True: if len(f[i:]) == 0: break func = f[i] if type(func) in (list, tuple): F, tol, val = func i += 1 else: F, tol, val = f[i], f[i+1], f[i+2] i += 3 t = target() t.func, t.tol = F, tol t.val = val if type(val) != str \ else inf if val in ('max', 'maximum') \ else -inf if val in ('min', 'minimum') \ else self.err('incorrect MOP func target') targets.append(t) self.targets = targets self.f = [t.func for t in targets] self.user.f = self.f def objFuncMultiple2Single(self, fv): return 0#(fv ** 2).sum() def solve(self, *args, **kw): # if self.plot or kw.get('plot', False): # self.warn('\ninteractive graphic output for MOP is unimplemented yet and will be turned off') # kw['plot'] = False self.graphics.drawFuncs = [mop_iterdraw] r = NonLinProblem.solve(self, *args, **kw) r.plot = lambda *args, **kw: self._plot(**kw) r.__call__ = lambda *args, **kw: self.err('evaluation of MOP result on arguments is unimplemented yet, use r.solutions') r.export = lambda *args, **Kw: _export_to_xls(self, r, *args, **kw) T0 = self.targets[0] if T0.val == -inf: keyfunc = lambda elem: elem[T0.func] elif T0.val == inf: keyfunc = lambda elem: -elem[T0.func] else: keyfunc = lambda elem: abs(T0.val - elem[T0.func]) r.solutions.sort(key=keyfunc) for v in self._categoricalVars: for elem in r.solutions: elem.useAsMutable = True elem[v] = v.aux_domain[elem[v]] elem.useAsMutable = False return r def _plot(self, **kw): from numpy import asarray, atleast_1d, array_equal S = self.solutions if type(S)==list and len(S) == 0: return tmp = asarray(self.solutions.F if 'F' in dir(self.solutions) else self.solutions.values) from copy import deepcopy kw2 = deepcopy(kw) useShow = kw2.pop('show', True) if not useShow and hasattr(self, '_prev_mop_solutions') and array_equal(self._prev_mop_solutions, tmp): return self._prev_mop_solutions = tmp.copy() if tmp.size == 0: if self.isFinished: self.disp('no solutions, nothing to plot') return try: import pylab except: self.err('you should have matplotlib installed') pylab.ion() if self.nf != 2: self.err('MOP plotting is implemented for problems with only 2 goals, while you have %d' % self.nf) X, Y = atleast_1d(tmp[:, 0]), atleast_1d(tmp[:, 1]) useGrid = kw2.pop('grid', 'on') if 'marker' not in kw2: kw2['marker'] = (5, 1, 0) if 's' not in kw2: kw2['s']=[150] if 'edgecolor' not in kw2: kw2['edgecolor'] = 'b' if 'facecolor' not in kw2: kw2['facecolor'] = '#FFFF00'#'y' pylab.scatter(X, Y, **kw2) pylab.grid(useGrid) t0_goal = 'min' if self.targets[0].val == -inf else 'max' if self.targets[0].val == inf else str(self.targets[0].val) t1_goal = 'min' if self.targets[1].val == -inf else 'max' if self.targets[1].val == inf else str(self.targets[1].val) pylab.xlabel(self.user.f[0].name + ' (goal: %s tolerance: %s)' %(t0_goal, self.targets[0].tol)) pylab.ylabel(self.user.f[1].name + ' (goal: %s tolerance: %s)' %(t1_goal, self.targets[1].tol)) pylab.title('problem: %s goal: %s' %(self.name, self.goal)) figure = pylab.gcf() from openopt import __version__ as ooversion figure.canvas.set_window_title('OpenOpt ' + ooversion) pylab.hold(0) pylab.draw() if useShow: pylab.ioff() pylab.show() def mop_iterdraw(p): p._plot(show=False) TkinterIsInstalled = True import platform if platform.python_version()[0] == '2': # Python2 try: from Tkinter import Tk from tkFileDialog import asksaveasfilename except: TkinterIsInstalled = False else: # Python3 try: from tkinter import Tk from tkinter.filedialog import asksaveasfilename except: TkinterIsInstalled = False def _export_to_xls(p, r, *args, **kw): try: import xlwt except: s = ''' To export OpenOpt MOP result into xls file you should have Python module "xlwt" installed, (http://www.python-excel.org), available via easy_install xlwt or Linux apt-get python-xlwt ''' p.err(s) if len(args) != 0: xls_file = args[0] elif TkinterIsInstalled: root = Tk() root.withdraw() import os hd = os.getenv("HOME") xls_file = asksaveasfilename(defaultextension='.xls', initialdir = hd, filetypes = [('xls files', '.xls')]) root.destroy() if xls_file in (None, ''): return else: p.err(''' you should either provide xls file name for data output or have tkinter installed to set it via GUI window''') # xls_file = asksaveasfilename(defaultextension='.xls', initialdir = self.hd, filetypes = [('xls files', '.xls')]) # if xls_file in (None, ''): # return nf = p.nf target_funcs = [t.func for t in p.targets] vars4export = set(p._freeVarsList).difference(target_funcs) vars4export = list(vars4export) vars4export.sort(key = lambda v: v._id) nv = len(vars4export) R = [[] for i in range(nv + nf)] Names = [t.name for t in target_funcs] + [v.name for v in vars4export] Keys = target_funcs + vars4export for elem in r.solutions: for i, key in enumerate(Keys): R[i].append(elem[key]) from numpy import asarray R = asarray(R) L = len(r.solutions) wb = xlwt.Workbook() ws = wb.add_sheet('OpenOpt MOP result') from openopt import __version__ as ver i = 0 ws.write(i, 0, 'OpenOpt ver') ws.write(i, 1, ver) i += 1 ws.write(i, 0, 'Solver') ws.write(i, 1, p.solver.__name__) i += 1 ws.write(i, 0, 'Prob name') ws.write(i, 1, p.name) i += 1 ws.write(i, 0, 'Prob type') ws.write(i, 1, p.probType) i += 1 ws.write(i, 0, 'Time, s') ws.write(i, 1, str(int(r.elapsed['solver_time']))) i += 1 ws.write(i, 0, 'CPU Time, s') ws.write(i, 1, str(int(r.elapsed['solver_cputime']))) i += 1 ws.write(i, 0, 'N solutions') ws.write(i, 1, str(L)) style1 = xlwt.easyxf(""" font: name Times New Roman, colour_index black; pattern: back_colour yellow, pattern thick_forward_diag, fore-colour yellow """) for i in range(nf): ws.write(0, 3+i, Names[i], style1) for j in range(L): ws.write(1+j, 3+i, R[i, j], style1) for i in range(nf, nf + nv): ws.write(0, 3+i, Names[i]) for j in range(L): ws.write(1+j, 3+i, R[i, j]) wb.save(xls_file) p.disp('export MOP %s result to xls file finished' % p.name) class target: pass openopt-0.38+svn1589/openopt/kernel/NLLSP.py000066400000000000000000000026361175775750500205210ustar00rootroot00000000000000from baseProblem import NonLinProblem from numpy import sum, dot, asfarray import NLP class NLLSP(NonLinProblem): _optionalData = ['lb', 'ub', 'A', 'Aeq', 'b', 'beq', 'c', 'h'] showGoal = False goal = 'minimum' probType = 'NLLSP' allowedGoals = ['minimum', 'min'] isObjFunValueASingleNumber = False expectedArgs = ['f', 'x0'] def __init__(self, *args, **kwargs): NonLinProblem.__init__(self, *args, **kwargs) def objFuncMultiple2Single(self, fv): return (fv ** 2).sum() def nllsp2nlp(self, solver, **solver_params): ff = lambda x: sum(asfarray(self.f(x))**2) p = NLP.NLP(ff, self.x0) #p = NLP.NLP(FF, self.x0) self.inspire(p, sameConstraints=True) if self.userProvided.df: p.df = lambda x: dot(2*asfarray(self.f(x)), asfarray(self.df(x,useSparse=False))) p.f = ff def nllsp_iterfcn(*args, **kwargs): p.primalIterFcn(*args, **kwargs) p.xk = self.xk p.fk = p.f(p.xk) p.rk = self.rk # TODO: add nNaNs if self.istop != 0: p.istop = self.istop elif p.istop != 0: self.istop = p.istop p.primalIterFcn, p.iterfcn = self.iterfcn, nllsp_iterfcn self.iprint = -1 p.show = False r = p.solve(solver, **solver_params) #r.ff = ff(r.xf) return r openopt-0.38+svn1589/openopt/kernel/NLP.py000066400000000000000000000007161175775750500202570ustar00rootroot00000000000000from ooMisc import assignScript from baseProblem import NonLinProblem from numpy import asarray, ones, inf, array class NLP(NonLinProblem): _optionalData = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] expectedArgs = ['f', 'x0'] probType = 'NLP' allowedGoals = ['minimum', 'min', 'maximum', 'max'] showGoal = True def __init__(self, *args, **kwargs): self.goal = 'minimum' NonLinProblem.__init__(self, *args, **kwargs) openopt-0.38+svn1589/openopt/kernel/NLSP.py000066400000000000000000000066151175775750500204060ustar00rootroot00000000000000from baseProblem import NonLinProblem from ooMisc import norm from numpy import inf, asfarray, atleast_1d, dot, abs, ndarray from setDefaultIterFuncs import FVAL_IS_ENOUGH, SMALL_DELTA_F from nonOptMisc import getSolverFromStringName import NLP try: import scipy solver = 'scipy_fsolve' except ImportError: solver = 'nssolve' class NLSP(NonLinProblem): _optionalData = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] probType = 'NLSP' goal = 'solution' allowedGoals = ['solution'] isObjFunValueASingleNumber = False showGoal = False expectedArgs = ['f', 'x0'] solver = solver def __init__(self, *args, **kwargs): NonLinProblem.__init__(self, *args, **kwargs) if 'is_oovar' in dir(self.f): self.f = [self.f] def objFuncMultiple2Single(self, fv): return norm(atleast_1d(asfarray(fv)), inf) def nlsp2nlp(self, solver, **solver_params): ff = lambda x: sum(asfarray(self.f(x))**2) p = NLP.NLP(ff, self.x0) self.inspire(p, sameConstraints=True) if self.userProvided.df: p.df = lambda x: dot(2*asfarray(self.f(x)), asfarray(self.df(x))) p.f = ff def nlsp_iterfcn(*args, **kwargs): if len(args) != 0 and type(args[0]) != ndarray: # hence Point p.primalIterFcn(args[0].x, max(abs(self.f(args[0].x))), args[0].mr(), **kwargs) # TODO: add nNaNs elif len(args) > 1: p.primalIterFcn(args[0], max(abs(self.f(args[0]))), *args[2:], **kwargs) elif 'fk' in kwargs.keys(): kwargs['fk'] = max(abs(self.f(args[0]))) p.primalIterFcn(*args, **kwargs) else: p.primalIterFcn(*args, **kwargs) p.xk = self.xk p.fk = p.f(p.xk) p.rk = self.rk # TODO: add nNaNs p.istop = self.istop return p.istop ftol_init = self.ftol contol_init = self.contol msg_contol = '' if self.isUC else 'and contol ' def nlsp_callback(nlsp): # nlsp = self if all(abs(asfarray(self.f(nlsp.xk))) < ftol_init) and (self.isUC or self.getMaxResidual(nlsp.xk) < contol_init): self.msg = 'solution with required ftol ' + msg_contol+ 'has been reached' return (15, self.msg) else: return False self.callback = [nlsp_callback] if SMALL_DELTA_F in self.kernelIterFuncs.keys():self.kernelIterFuncs.pop(SMALL_DELTA_F) p.primalIterFcn, p.iterfcn = self.iterfcn, nlsp_iterfcn p.goal = 'min' #self.fEnough = self.ftol p.iprint = -1 Multiplier = 1e16 #self.ftol /= Multiplier self.xtol /= Multiplier self.gtol /= Multiplier p.show = False p.fOpt = 0.0 p.fTol = p.ftol**2 r = p.solve(solver, **solver_params) #self.ftol *= Multiplier self.xtol *= Multiplier self.gtol *= Multiplier if self.istop == FVAL_IS_ENOUGH: self.msg = 'solution with required ftol ' + msg_contol+ 'has been reached' self.istop = 15 #self.iterfcn(xk = r.xk, fk = r.fk, rk = r.rk) #self.show = show # TODO: fix it! #r.iterValues.f = self.iterValues.f #r.ff = max(abs(asfarray(self.f(r.xf)))) return r openopt-0.38+svn1589/openopt/kernel/NSP.py000066400000000000000000000010761175775750500202660ustar00rootroot00000000000000from ooMisc import assignScript from baseProblem import NonLinProblem from numpy import asarray, ones, inf class NSP(NonLinProblem): _optionalData = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] expectedArgs = ['f', 'x0'] probType = 'NSP' JacobianApproximationStencil = 3 allowedGoals = ['minimum', 'min', 'maximum', 'max'] showGoal = True def __init__(self, *args, **kwargs): self.goal = 'minimum' NonLinProblem.__init__(self, *args, **kwargs) #TODO: set here default tolx, tolcon, diffInt etc for NS Problem openopt-0.38+svn1589/openopt/kernel/ODE.py000066400000000000000000000017211175775750500202320ustar00rootroot00000000000000from baseProblem import NonLinProblem from numpy import any, diff #from numpy.linalg import norm class ODE(NonLinProblem): probType = 'ODE' goal = 'solution' allowedGoals = ['solution'] showGoal = False _optionalData = [] FuncDesignerSign = 'timeVariable' expectedArgs = ['equations', 'startPoint', 'timeVariable', 'times'] ftol = None def __init__(self, *args, **kwargs): NonLinProblem.__init__(self, *args, **kwargs) domain, timeVariable, times = args[1:4] self.x0 = domain # if any(diff(times) < 0): self.err(''' # currently required ODE times should be sorted # in ascending order, other cases are unimplemented yet # ''') #self.constraints = [timeVariable > times[0], timeVariable < times[-1]] def objFunc(self, x): return 0 #raise 'unimplemented yet' #r = norm(dot(self.C, x) - self.d) ** 2 / 2.0 #return r openopt-0.38+svn1589/openopt/kernel/Point.py000066400000000000000000000660661175775750500207310ustar00rootroot00000000000000# created by Dmitrey from numpy import copy, isnan, array, argmax, abs, vstack, zeros, any, isfinite, all, where, asscalar, \ sign, dot, sqrt, array_equal, nanmax, inf, hstack, isscalar, logical_or, matrix, asfarray, prod, arange, ndarray, asarray, sum from ooMisc import norm from nonOptMisc import Copy, isPyPy from pointProjection import pointProjection empty_arr = array(()) try: from scipy.sparse import isspmatrix, csr_matrix scipyInstalled = True except ImportError: scipyInstalled = False isspmatrix = lambda *args, **kwargs: False class Point: """ the class is used to prevent calling non-linear constraints more than once f, c, h are funcs for obtaining objFunc, non-lin ineq and eq constraints. df, dc, dh are funcs for obtaining 1st derivatives. """ __expectedArgs__ = ['x', 'f', 'mr'] def __init__(self, p, x, *args, **kwargs): self.p = p self.x = copy(x) for i, arg in enumerate(args): setattr(self, '_' + self.__expectedArgs__[i], args[i]) for name, val in kwargs.items(): setattr(self, '_' + name, val) #assert self.x is not None def f(self): if not hasattr(self, '_f'): # TODO: rework this: self.p.probType!='IP' if self.p._baseClassName == 'NonLin' and self.p.probType!='IP': self._f = self.p.f(self.x) if self.p.isObjFunValueASingleNumber else self.p.F(self.x) else: self._f = self.p.objFunc(self.x) return copy(self._f) def df(self): if not hasattr(self, '_df'): self._df = self.p.df(self.x) return Copy(self._df) def c(self, ind=None): if not self.p.userProvided.c: return empty_arr.copy() if ind is None: if not hasattr(self, '_c'): self._c = self.p.c(self.x) return copy(self._c) else: if hasattr(self, '_c'): return copy(self._c[ind]) else: return copy(self.p.c(self.x, ind)) def dc(self, ind=None): if not self.p.userProvided.c: return empty_arr.copy().reshape(0, self.p.n) if ind is None: if not hasattr(self, '_dc'): self._dc = self.p.dc(self.x) return Copy(self._dc) else: if hasattr(self, '_dc'): return Copy(self._dc[ind]) else: return Copy(self.p.dc(self.x, ind)) def h(self, ind=None): if not self.p.userProvided.h: return empty_arr.copy() if ind is None: if not hasattr(self, '_h'): self._h = self.p.h(self.x) return copy(self._h) else: if hasattr(self, '_h'): return copy(self._h[ind]) else: return copy(self.p.h(self.x, ind)) def dh(self, ind=None): if not self.p.userProvided.h: return empty_arr.copy().reshape(0, self.p.n) #raise 0 if ind is None: if not hasattr(self, '_dh'): self._dh = self.p.dh(self.x) return Copy(self._dh) else: if hasattr(self, '_dh'): return Copy(self._dh[ind]) else: return Copy(self.p.dh(self.x, ind)) def d2f(self): if not hasattr(self, '_d2f'): self._d2f = self.p.d2f(self.x) return copy(self._d2f) # def intConstraints(self): # if self.p.intVars == {} or self.p.intVars == []: return 0 # if not hasattr(self, '_intConstraint'): # r = [norm(self.x[k]-self.p.intVars[k], -inf) for k in self.p.intVars.keys()] # self._intConstraints = max(r) # # return copy(self._intConstraints) def lin_ineq(self): if not hasattr(self, '_lin_ineq'): self._lin_ineq = self.p._get_AX_Less_B_residuals(self.x) return copy(self._lin_ineq) def lin_eq(self): if not hasattr(self, '_lin_eq'): self._lin_eq = self.p._get_AeqX_eq_Beq_residuals(self.x) return copy(self._lin_eq) def lb(self): if not hasattr(self, '_lb'): self._lb = self.p.lb - self.x return copy(self._lb) def ub(self): if not hasattr(self, '_ub'): self._ub = self.x - self.p.ub return copy(self._ub) def mr(self, retAll = False): # returns max residual if not hasattr(self, '_mr'): r, fname, ind = 0, None, 0 ineqs = ['lin_ineq', 'lb', 'ub'] eqs = ['lin_eq'] if self.p._baseClassName == 'NonLin': ineqs.append('c') eqs.append('h') elif self.p.probType in ['MILP', 'MINLP']: pass #ineqs.append('intConstraints') for field in ineqs: fv = array(getattr(self, field)()).flatten() if fv.size > 0: #ind_max = argmax(fv) #val_max = fv[ind_max val_max = nanmax(fv) if not isnan(val_max): ind_max = where(fv==val_max)[0][0] if r < val_max: r, ind, fname = val_max, ind_max, field for field in eqs: fv = array(getattr(self, field)()).flatten() if fv.size > 0: fv = abs(fv) ind_max = argmax(fv) val_max = fv[ind_max] if r < val_max: r, ind, fname = val_max, ind_max, field self._mr, self._mrName, self._mrInd= r, fname, ind if retAll: return asscalar(copy(self._mr)), self._mrName, asscalar(copy(self._mrInd)) else: return asscalar(copy(self._mr)) def sum_of_all_active_constraints(self): if not hasattr(self, '_sum_of_all_active_constraints'): p = self.p if p.solver.__name__ == 'ralg': tol = p.contol / 2.0 else: tol = 0.0 # elif p.solver.__name__ == 'gsubg': # tol = 0.0 # else: # p.err('unimplemented case in Point.py') c, h= self.c(), self.h() all_lin = self.all_lin() self._sum_of_all_active_constraints = (c[c>0] - 0).sum() + (h[h>tol] - tol).sum() - (h[h<-tol] + tol).sum() + all_lin return Copy(self._sum_of_all_active_constraints) def mr_alt(self, retAll = False, bestFeasiblePoint=None): # TODO: add fix wrt bestFeasiblePoint handling ################################################### # DEBUG! # IT SAVES DIFFERENT VALUES WRT WITH OR WITHOUT bestFeasiblePoint # IT HAS BEEN CALLED 1ST TIME if hasattr(self, '_mr_alt'): delattr(self, '_mr_alt') ################################################### if not hasattr(self, '_mr_alt'): p = self.p if not hasattr(p.solver, 'approach') or p.solver.approach == 'all active': val = self.sum_of_all_active_constraints() if bestFeasiblePoint is not None: # not "+="!!!!! Else some problems with array shapes can occur #print self.f()-bestFeasiblePoint.f() # val = val + max((0, self.f()-bestFeasiblePoint.f())) * p.contol / p.fTol pass self._mr_alt, self._mrName_alt, self._mrInd_alt = val, 'all active', 0 else: p.err('bug in openopt kernel, inform developers') # r = 0.0 # if c.size != 0: # ind_max = argmax(c) # val_max = c[ind_max] # if val_max > r: # r = val_max # Type = 'c' # ind = ind_max # if h.size != 0: # h = abs(h) # ind_max = argmax(h) # val_max = h[ind_max] # #hm = abs(h).max() # if val_max > r: # r = val_max # Type = 'h' # ind = ind_max # lin_eq = self.lin_eq() # if lin_eq.size != 0: # l_eq = abs(lin_eq) # ind_max = argmax(l_eq) # val_max = l_eq[ind_max] # if val_max > r: # r = val_max # Type = 'lin_eq' # ind = ind_max # lin_ineq = self.lin_ineq() # # TODO: implement it # val = r # self._mr_alt, self._mrName_alt, self._mrInd_alt = val, Type, 0 if retAll: return asscalar(copy(self._mr_alt)), self._mrName_alt, asscalar(copy(self._mrInd_alt)) else: return asscalar(copy(self._mr_alt)) def dmr(self, retAll = False): # returns direction for max residual decrease #( gradient for equality < 0 residuals ! ) if not hasattr(self, '_dmr') or (retAll and not hasattr(self, '_dmrInd')): g = zeros(self.p.n) maxResidual, resType, ind = self.mr(retAll=True) if resType == 'lb': g[ind] -= 1 # N * (-1), -1 = dConstr/dx = d(lb-x)/dx elif resType == 'ub': g[ind] += 1 # N * (+1), +1 = dConstr/dx = d(x-ub)/dx elif resType == 'lin_ineq': g += self.p.A[ind] elif resType == 'lin_eq': rr = self.p.matmult(self.p.Aeq[ind], self.x)-self.p.beq[ind] if rr < 0: g -= self.p.Aeq[ind] else: g += self.p.Aeq[ind] elif resType == 'c': dc = self.dc(ind=ind).flatten() g += dc elif resType == 'h': dh = self.dh(ind=ind).flatten() if self.p.h(self.x, ind) < 0: g -= dh#CHECKME!! else: g += dh#CHECKME!! else: # TODO: error or debug warning pass #self.p.err('incorrect resType') self._dmr, self._dmrName, self._dmrInd = g, resType, ind if retAll: return copy(self._dmr), self._dmrName, copy(self._dmrInd) else: return copy(self._dmr) def betterThan(self, point2compare, altLinInEq = False, bestFeasiblePoint = None): """ usage: result = involvedPoint.better(pointToCompare) returns True if the involvedPoint is better than pointToCompare and False otherwise (if NOT better, mb same fval and same residuals or residuals less than desired contol) """ if self.p.isUC: return self.f() < point2compare.f() contol = self.p.contol if altLinInEq: mr, point2compareResidual = self.mr_alt(bestFeasiblePoint=bestFeasiblePoint), point2compare.mr_alt(bestFeasiblePoint=bestFeasiblePoint) else: mr, point2compareResidual = self.mr(), point2compare.mr() # if altLinInEq and bestFeasiblePoint is not None and isfinite(self.f()) and isfinite(point2compare.f()): # fTol = self.p.fTol # mr += (self.f() - bestFeasiblePoint.f() + fTol) *contol / fTol # point2compareResidual += (point2compare.f() - bestFeasiblePoint.f()+fTol) *contol / fTol # mr += max((0, self.f() - bestFeasiblePoint.f())) *contol/ fTol # point2compareResidual += max((0, point2compare.f() - bestFeasiblePoint.f())) *contol/ fTol # assert self.f() >= bestFeasiblePoint.f() # assert point2compare.f() >= bestFeasiblePoint.f() # mr += (self.f() - bestFeasiblePoint.f()) / fTol # point2compareResidual += (point2compare.f() - bestFeasiblePoint.f()) / fTol criticalResidualValue = max((contol, point2compareResidual)) self_nNaNs, point2compare_nNaNs = self.nNaNs(), point2compare.nNaNs() if point2compare_nNaNs > self_nNaNs: return True elif point2compare_nNaNs < self_nNaNs: return False # TODO: check me if self_nNaNs == 0: if mr > self.p.contol and mr > point2compareResidual: return False elif point2compareResidual > self.p.contol and point2compareResidual > mr: return True else: # got here means self_nNaNs = point2compare_nNaNs but not equal to 0 if mr == 0 and point2compareResidual == 0: if not self.p.solver.__name__.startswith('interalg'): self.p.err('you should provide at least one active constraint in each point from R^n where some constraints are undefined') return mr < point2compareResidual point2compareF_is_NaN = isnan(point2compare.f()) selfF_is_NaN = isnan(self.f()) if isPyPy: if type(point2compareF_is_NaN) == ndarray: point2compareF_is_NaN = asscalar(point2compareF_is_NaN) if type(selfF_is_NaN) == ndarray: selfF_is_NaN = asscalar(selfF_is_NaN) if not point2compareF_is_NaN: # f(point2compare) is not NaN if not selfF_is_NaN: # f(newPoint) is not NaN return self.f() < point2compare.f() else: # f(newPoint) is NaN return False else: # f(point2compare) is NaN if selfF_is_NaN: # f(newPoint) is NaN return mr < point2compareResidual else: # f(newPoint) is not NaN return True def isFeas(self, altLinInEq): if not all(isfinite(self.f())): return False if self.p.isUC: return True if self.nNaNs() != 0: return False contol = self.p.contol if altLinInEq: if self.mr_alt() > contol: return False else: if hasattr(self, '_mr'): if self._mr > contol: return False else: #TODO: simplify it! #for fn in residuals: (...) if any(self.lb() > contol): return False if any(self.ub() > contol): return False if any(abs(self.lin_eq()) > contol): return False if any(self.lin_ineq() > contol): return False if any(abs(self.h()) > contol): return False if any(self.c() > contol): return False return True def nNaNs(self): # returns number of nans in constraints if self.p._baseClassName != 'NonLin': return 0 r = 0 c, h = self.c(), self.h() r += len(where(isnan(c))[0]) r += len(where(isnan(h))[0]) return r def linePoint(self, alp, point2, ls=None): # returns alp * point1 + (1-alp) * point2 # where point1 is self, alp is real number assert isscalar(alp) p = self.p r = p.point(self.x * (1-alp) + point2.x * alp) #lin_eqs = self.lin_eq()*alp + point2.lin_eq() * (1-alp) #print '!>>, ', p.norm(lin_eqs), p.norm(lin_eqs - r.lin_eq()) # TODO: optimize it, take ls into account! #if ls is not None and if not (p.iter % 16): lin_ineq_predict = self.lin_ineq()*(1-alp) + point2.lin_ineq() * alp #if 1 or p.debug: print('!>>', p.norm(lin_ineq_predict-r.lin_ineq())) r._lin_ineq = lin_ineq_predict r._lin_eq = self.lin_eq()*(1-alp) + point2.lin_eq() * alp # don't calculate c for inside points if 0 0, isnan(c1)) ind2 = logical_or(c2 > 0, isnan(c2)) # prev # ind = where(ind1 | ind2)[0] # # _c = zeros(p.nc) # if ind.size != 0: # _c[ind] = p.c(r.x, ind) # new, temporary walkaround for PyPy ind = logical_or(ind1, ind2) _c = zeros(p.nc) if any(ind): _c[ind] = p.c(r.x, where(ind)[0]) r._c = _c # TODO: mb same for h? return r def all_lin(self): # TODO: rename it wrt lin_eq that are present here if not hasattr(self, '_all_lin'): lb, ub, lin_ineq = self.lb(), self.ub(), self.lin_ineq() r = 0.0 # TODO: CHECK IT - when 0 (if some nans), when contol # if all(isfinite(self.f())): threshold = self.p.contol # else: 0.0 = 0 lin_eq = self.lin_eq() ind_lb, ind_ub = lb>0.0, ub>0.0 ind_lin_ineq = lin_ineq>0.0 ind_lin_eq = abs(lin_eq)>0.0 USE_SQUARES = 1 if USE_SQUARES: if any(ind_lb): r += sum(lb[ind_lb] ** 2) if any(ind_ub): r += sum(ub[ind_ub] ** 2) # if ind_lb.size != 0: # r += sum(lb[ind_lb]) # if ind_ub.size != 0: # r += sum(ub[ind_ub]) if any(ind_lin_ineq): r += sum(lin_ineq[ind_lin_ineq] ** 2) if any(ind_lin_eq): r += sum(lin_eq[ind_lin_eq] ** 2) self._all_lin = r / self.p.contol # self._all_lin = r else: if any(ind_lb): r += sum(lb[ind_lb]) if any(ind_ub): r += sum(ub[ind_ub]) if any(ind_lin_ineq): r += sum(lin_ineq[ind_lin_ineq]) if any(ind_lin_eq): r += sum(abs(lin_eq[ind_lin_eq])) self._all_lin = r return copy(self._all_lin) def all_lin_gradient(self): if not hasattr(self, '_all_lin_gradient'): p = self.p n = p.n d = zeros(n) lb, ub = self.lb(), self.ub() lin_ineq = self.lin_ineq() lin_eq = self.lin_eq() ind_lb, ind_ub = lb > 0.0, ub > 0.0 ind_lin_ineq = lin_ineq > 0.0 ind_lin_eq = abs(lin_eq) != 0.0 USE_SQUARES = 1 if USE_SQUARES: if any(ind_lb): d[ind_lb] -= lb[ind_lb]# d/dx((x-lb)^2) for violated constraints if any(ind_ub): d[ind_ub] += ub[ind_ub]# d/dx((x-ub)^2) for violated constraints if any(ind_lin_ineq): # d/dx((Ax-b)^2) b = p.b[ind_lin_ineq] if hasattr(p, '_A'): a = p._A[ind_lin_ineq] tmp = a._mul_sparse_matrix(csr_matrix((self.x, (arange(n), zeros(n))), shape=(n, 1))).toarray().flatten() - b #tmp = a._mul_sparse_matrix(csr_matrix((self.x, reshape(p.n, 1))).toarray().flatten() - b d += a.T._mul_sparse_matrix(tmp.reshape(tmp.size, 1)).A.flatten() #d += dot(a.T, dot(a, self.x) - b) else: if isPyPy: a = array([p.A[j] for j in where(ind_lin_ineq)[0]]) else: a = p.A[ind_lin_ineq] d += dot(a.T, dot(a, self.x) - b) # d/dx((Ax-b)^2) if any(ind_lin_eq): if isspmatrix(p.Aeq): p.err('this solver is not ajusted to handle sparse Aeq matrices yet') #self.p.err('nonzero threshold is not ajusted with lin eq yet') aeq = p.Aeq#[ind_lin_eq] beq = p.beq#[ind_lin_eq] d += dot(aeq.T, dot(aeq, self.x) - beq) # d/dx((Aeq x - beq)^2) # self._all_lin_gradient = 2.0 * d self._all_lin_gradient = 2.0 * d / p.contol else: if any(ind_lb): d[ind_lb] -= 1# d/dx(lb-x) for violated constraints if any(ind_ub): d[ind_ub] += 1# d/dx(x-ub) for violated constraints if any(ind_lin_ineq): # d/dx(Ax-b) b = p.b[ind_lin_ineq] if hasattr(p, '_A'): d += (p._A[ind_lin_ineq]).sum(0).A.flatten() else: d += (p.A[ind_lin_ineq]).sum(0).flatten() if any(ind_lin_eq): # currently for ralg it should be handled in dilation matrix p.err('not implemented yet, if you see it inform OpenOpt developers') # beq = p.beq[ind_lin_eq] # if hasattr(p, '_Aeq'): # tmp = p._Aeq[ind_lin_eq] # ind_change = where() # tmp # d += ().sum(0).A.flatten() # else: # #d += (p.Aeq[ind_lin_eq]).sum(0).flatten() # aeq = p.Aeq[ind_lin_eq] # beq = p.beq[ind_lin_eq] # d += dot(aeq.T, dot(aeq, self.x) - beq) # 0.5*d/dx((Aeq x - beq)^2) self._all_lin_gradient = d return copy(self._all_lin_gradient) def sum_of_all_active_constraints_gradient(self): if not hasattr(self, '_sum_of_all_active_constraints_gradient'): p = self.p contol = p.contol x = self.x direction = self.all_lin_gradient() if p.solver.__name__ == 'ralg': new = 1 elif p.solver.__name__ == 'gsubg': new = 0 else: p.err('unhandled case in Point._getDirection') if p.userProvided.c: th = 0.0 #th = contol / 2.0 C = p.c(x) Ind = C>th ind = where(Ind)[0] activeC = asarray(C[Ind])# asarray and Ind for PyPy compatibility if len(ind) > 0: tmp = p.dc(x, ind) if new: if tmp.ndim == 1 or min(tmp.shape) == 1: if hasattr(tmp, 'toarray'): tmp = tmp.toarray()#.flatten() if activeC.size == prod(tmp.shape): activeC = activeC.reshape(tmp.shape) tmp *= (activeC-th*(1.0-1e-15))/norm(tmp) else: if hasattr(tmp, 'toarray'): tmp = tmp.toarray() tmp *= ((activeC - th*(1.0-1e-15))/sqrt((tmp**2).sum(1))).reshape(-1, 1) if tmp.ndim > 1: tmp = tmp.sum(0) direction += (tmp.A if type(tmp) != ndarray else tmp).flatten() if p.userProvided.h: #th = 0.0 th = contol / 2.0 H = p.h(x) Ind1 = H>th ind1 = where(Ind1)[0] H1 = asarray(H[Ind1])# asarray and Ind1 for PyPy compatibility if len(ind1) > 0: tmp = p.dh(x, ind1) if new: if tmp.ndim == 1 or min(tmp.shape) == 1: if hasattr(tmp, 'toarray'): tmp = tmp.toarray()#.flatten() if H1.size == prod(tmp.shape): H1 = H1.reshape(tmp.shape) tmp *= (H1-th*(1.0-1e-15))/norm(tmp) else: if hasattr(tmp, 'toarray'): tmp = tmp.toarray() tmp *= ((H1 - th*(1.0-1e-15))/sqrt((tmp**2).sum(1))).reshape(-1, 1) if tmp.ndim > 1: tmp = tmp.sum(0) direction += (tmp.A if isspmatrix(tmp) or hasattr(tmp, 'toarray') else tmp).flatten() ind2 = where(H<-th)[0] H2 = H[ind2] if len(ind2) > 0: tmp = p.dh(x, ind2) if new: if tmp.ndim == 1 or min(tmp.shape) == 1: if hasattr(tmp, 'toarray'): tmp = tmp.toarray()#.flatten() if H2.size == prod(tmp.shape): H2 = H2.reshape(tmp.shape) tmp *= (-H2-th*(1.0-1e-15))/norm(tmp) else: if hasattr(tmp, 'toarray'): tmp = tmp.toarray() tmp *= ((-H2 - th*(1.0-1e-15))/sqrt((tmp**2).sum(1))).reshape(-1, 1) if tmp.ndim > 1: tmp = tmp.sum(0) direction -= (tmp.A if isspmatrix(tmp) or isinstance(tmp, matrix) else tmp).flatten() self._sum_of_all_active_constraints_gradient = direction return Copy(self._sum_of_all_active_constraints_gradient) def _getDirection(self, approach, currBestFeasPoint = None): if self.isFeas(altLinInEq=True): self.direction, self.dType = self.df(),'f' if type(self.direction) != ndarray: self.direction = self.direction.A.flatten() return self.direction.copy() else: if approach == 'all active': self.dType = 'all active' self.direction = self.sum_of_all_active_constraints_gradient() else: maxRes, fname, ind = self.mr_alt(1, bestFeasiblePoint = currBestFeasPoint) if fname == 'all_lin': d = self.all_lin_gradient() self.dType = 'all_lin' elif fname == 'lin_eq': self.p.err("kernel error, inform openopt developers") #d = self.dmr() #self.dType = 'lin_eq' elif fname == 'c': d = self.dmr() #if p.debug: assert array_equal(self.dc(ind).flatten(), self.dmr()) self.dType = 'c' elif fname == 'h': d = self.dmr()#sign(self.h(ind))*self.dh(ind) #if p.debug: assert array_equal(self.dh(ind).flatten(), self.dmr()) self.dType = 'h' else: p.err('error in getRalgDirection (unknown residual type ' + fname + ' ), you should report the bug') self.direction = d.flatten() if type(self.direction) != ndarray: self.direction = self.direction.A.flatten() # print 'currBestFeasPoint is not None:', (currBestFeasPoint is not None), 'self.f() > currBestFeasPoint.f():', self.f() > currBestFeasPoint.f() contol, fTol = self.p.contol, self.p.fTol # print self.f(), currBestFeasPoint.f(), self.f() - fTol == currBestFeasPoint.f() if currBestFeasPoint is not None and self.f() + 0.25*fTol > currBestFeasPoint.f(): #self.direction += ((self.f()-currBestFeasPoint.f()) * p.contol / nDF / fTol) * DF # self.direction += self.df() * (contol/fTol) pass return self.direction.copy() # it may be modified in ralg when some constraints coords are NaN openopt-0.38+svn1589/openopt/kernel/QP.py000066400000000000000000000041111175775750500201370ustar00rootroot00000000000000import NLP from ooMisc import assignScript, isspmatrix from baseProblem import MatrixProblem from numpy import asfarray, ones, inf, dot, asfarray, nan, zeros, isfinite, all, ravel class QP(MatrixProblem): probType = 'QP' goal = 'minimum' allowedGoals = ['minimum', 'min'] showGoal = False _optionalData = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'QC', 'intVars'] expectedArgs = ['H', 'f'] def _Prepare(self): # TODO: handle cvxopt sparse matrix case here self.n = self.H.shape[0] if not hasattr(self, 'x0') or self.x0 is None or self.x0[0] == nan: self.x0 = zeros(self.n) MatrixProblem._Prepare(self) def __init__(self, *args, **kwargs): MatrixProblem.__init__(self, *args, **kwargs) if len(args) > 1 or 'f' in kwargs.keys(): self.f = ravel(self.f) self.n = self.f.size if len(args) > 0 or 'H' in kwargs.keys(): # TODO: handle sparse cvxopt matrix H unchanges # if not ('cvxopt' in str(type(H)) and 'cvxopt' in p.solver): if not isspmatrix(self.H): self.H = asfarray(self.H, float) # TODO: handle the case in runProbSolver() def objFunc(self, x): return asfarray(0.5*dot(x, self.matMultVec(self.H, x)) + dot(self.f, x).sum()).flatten() def qp2nlp(self, solver, **solver_params): if hasattr(self,'x0'): p = NLP.NLP(ff, self.x0, df=dff, d2f=d2ff) else: p = NLP.NLP(ff, zeros(self.n), df=dff, d2f=d2ff) p.args.f = self # DO NOT USE p.args = self IN PROB ASSIGNMENT! p.iprint = self.iprint self.inspire(p) self.iprint = -1 # for QP plot is via NLP p.show = self.show p.plot, self.plot = self.plot, 0 #p.checkdf() r = p.solve(solver, **solver_params) self.xf, self.ff, self.rf = r.xf, r.ff, r.rf return r ff = lambda x, QProb: QProb.objFunc(x) def dff(x, QProb): r = dot(QProb.H, x) if all(isfinite(QProb.f)) : r += QProb.f return r def d2ff(x, QProb): r = QProb.H return r openopt-0.38+svn1589/openopt/kernel/SDP.py000066400000000000000000000037031175775750500202530ustar00rootroot00000000000000from baseProblem import MatrixProblem from numpy import asfarray, ones, inf, dot, asfarray, nan, zeros, isfinite, all class SDP(MatrixProblem): _optionalData = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'S', 'd'] expectedArgs = ['f'] goal = 'minimum' #TODO: impolement goal = max, maximum for SDP #allowedGoals = ['minimum', 'min', 'maximum', 'max'] allowedGoals = ['minimum', 'min'] showGoal = True def __init__(self, *args, **kwargs): self.probType = 'SDP' self.S = {} self.d = {} MatrixProblem.__init__(self, *args, **kwargs) self.f = asfarray(self.f) self.n = self.f.size if self.x0 is None: self.x0 = zeros(self.n) def _Prepare(self): MatrixProblem._Prepare(self) if self.solver.__name__ in ['cvxopt_sdp', 'dsdp']: try: from cvxopt.base import matrix matrixConverter = lambda x: matrix(x, tc='d') except: self.err('cvxopt must be installed') else: matrixConverter = asfarray for i in self.S.keys(): self.S[i] = matrixConverter(self.S[i]) for i in self.d.keys(): self.d[i] = matrixConverter(self.d[i]) # if len(S) != len(d): self.err('semidefinite constraints S and d should have same length, got '+len(S) + ' vs '+len(d)+' instead') # for i in range(len(S)): # d[i] = matrixConverter(d[i]) # for j in range(len(S[i])): # S[i][j] = matrixConverter(S[i][j]) def __finalize__(self): MatrixProblem.__finalize__(self) if self.goal in ['max', 'maximum']: self.f = -self.f for fn in ['fk', ]:#not ff - it's handled in other place in RunProbSolver.py if hasattr(self, fn): setattr(self, fn, -getattr(self, fn)) def objFunc(self, x): return asfarray(dot(self.f, x).sum()).flatten() openopt-0.38+svn1589/openopt/kernel/SLE.py000066400000000000000000000072571175775750500202600ustar00rootroot00000000000000from ooMisc import assignScript from baseProblem import MatrixProblem from numpy import asfarray, ones, inf, dot, nan, zeros, any, all, isfinite, eye, vstack, hstack, flatnonzero, isscalar, ndarray, atleast_2d, zeros_like from ooMisc import norm from oologfcn import OpenOptException import NLP from nonOptMisc import scipyInstalled, Vstack try: import scipy scipyInstalled = True except: scipyInstalled = False class SLE(MatrixProblem): expectedArgs = ['C', 'd']# for FD it should be Cd and x0 probType = 'SLE' goal = 'solution' allowedGoals = ['solution'] showGoal = False FuncDesignerSign = 'C' solver = 'defaultSLEsolver' _optionalData = [] _isPrepared = False def __init__(self, *args, **kwargs): MatrixProblem.__init__(self, *args, **kwargs) _useSparse = lambda self: True if (scipyInstalled and self.n > 100) else False def objFunc(self, x): if isinstance(self.C, ndarray): return norm(dot(self.C, x) - self.d, inf) else: # TODO: omit code clone in FD ooFun.py, function _D t1 = self.C_as_csc t2 = scipy.sparse.csr_matrix(x) if t2.shape[0] != t1.shape[1]: if t2.shape[1] == t1.shape[1]: t2 = t2.T else: raise FuncDesignerException('incorrect shape in FuncDesigner function _D(), inform developers about the bug') rr = t1._mul_sparse_matrix(t2) return norm(rr.toarray().flatten() - self.d, inf) def _Prepare(self): if self._isPrepared: return self._isPrepared = True if isinstance(self.d, dict): # FuncDesigner startPoint self.x0 = self.d MatrixProblem._Prepare(self) if self.isFDmodel: equations = self.C AsSparse = bool(self.useSparse) if type(self.useSparse) != str else self._useSparse() C, d = [], [] if len(self._fixedVars) < len(self._freeVars): Z = dict([(v, zeros_like(self._x0[v]) if v not in self._fixedVars else self._x0[v]) for v in self._x0.keys()]) else: Z = dict([(v, zeros_like(self._x0[v]) if v in self._freeVars else self._x0[v]) for v in self._x0.keys()]) #Z = self.x0#self._vector2point(zeros(self.n)) for lin_oofun in equations: if lin_oofun.getOrder(self.freeVars, self.fixedVars) > 1: raise OpenOptException('SLE constructor requires all equations to be linear') C.append(self._pointDerivative2array(lin_oofun.D(Z, **self._D_kwargs), useSparse = AsSparse)) d.append(-lin_oofun(Z)) self.d = hstack(d).flatten() self.C = Vstack(C) if hasattr(self.C, 'tocsc'): self.C_as_csc = self.C.tocsc() if isinstance(self.C,ndarray) and self.n > 100 and len(flatnonzero(self.C))/self.C.size < 0.3: s = "Probably you'd better solve this SLE as sparse" if not scipyInstalled: s += ' (requires scipy installed)' self.pWarn(s) self.x0 = zeros(self.C.shape[1]) # if not self.damp is None and not any(isfinite(self.X)): # self.X = zeros(self.n) #ff = lambda x, LLSPprob: LLSPprob.objFunc(x) #def dff(x, LLSPprob): # r = dot(LLSPprob.C.T, dot(LLSPprob.C,x) - LLSPprob.d) # if not LLSPprob.damp is None: r += LLSPprob.damp*(x - LLSPprob.X) # if LLSPprob.f is not None and all(isfinite(LLSPprob.f)) : r += LLSPprob.f # return r # #def d2ff(x, LLSPprob): # r = dot(LLSPprob.C.T, LLSPprob.C) # if not LLSPprob.damp is None: r += LLSPprob.damp*eye(x.size) # return r openopt-0.38+svn1589/openopt/kernel/SOCP.py000066400000000000000000000013601175775750500203660ustar00rootroot00000000000000from baseProblem import MatrixProblem from numpy import asfarray, ones, inf, dot, asfarray, nan, zeros, isfinite, all, asscalar class SOCP(MatrixProblem): probType = 'SOCP' _optionalData = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub'] goal = 'minimum' allowedGoals = ['minimum', 'min'] #TODO: add goal=max, maximum showGoal = True expectedArgs = ['f', 'C', 'd'] # required are f, C, d def __init__(self, *args, **kwargs): MatrixProblem.__init__(self, *args, **kwargs) self.f = asfarray(self.f) self.n = self.f.size # for p.n to be available immediately after assigning prob if self.x0 is None: self.x0 = zeros(self.n) def objFunc(self, x): return asscalar(dot(self.f, x)) openopt-0.38+svn1589/openopt/kernel/__init__.py000066400000000000000000000000021175775750500213510ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/kernel/baseProblem.py000066400000000000000000001131051175775750500220560ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import * from oologfcn import * from oographics import Graphics from setDefaultIterFuncs import setDefaultIterFuncs, IS_MAX_FUN_EVALS_REACHED, denyingStopFuncs from nonLinFuncs import nonLinFuncs from residuals import residuals from ooIter import ooIter #from Point import Point currently lead to bug from openopt.kernel.Point import Point from iterPrint import ooTextOutput from ooMisc import setNonLinFuncsNumber, assignScript, norm from nonOptMisc import isspmatrix, scipyInstalled, scipyAbsentMsg, csr_matrix, Vstack, Hstack, EmptyClass from copy import copy as Copy try: from DerApproximator import check_d1 DerApproximatorIsInstalled = True except: DerApproximatorIsInstalled = False ProbDefaults = {'diffInt': 1.5e-8, 'xtol': 1e-6, 'noise': 0} from runProbSolver import runProbSolver import GUI from fdmisc import setStartVectorAndTranslators class user: def __init__(self): pass class oomatrix: def __init__(self): pass def matMultVec(self, x, y): return dot(x, y) if not isspmatrix(x) else x._mul_sparse_matrix(csr_matrix(y.reshape((y.size, 1)))).A.flatten() def matmult(self, x, y): return dot(x, y) #return asarray(x) ** asarray(y) def dotmult(self, x, y): return x * y #return asarray(x) * asarray(y) class autocreate: def __init__(self): pass class baseProblem(oomatrix, residuals, ooTextOutput): isObjFunValueASingleNumber = True manage = GUI.manage # GUI func #_useGUIManager = False # TODO: implement it prepared = False _baseProblemIsPrepared = False name = 'unnamed' state = 'init'# other: paused, running etc castFrom = '' # used by converters qp2nlp etc nonStopMsg = '' xlabel = 'time' plot = False # draw picture or not show = True # use command pylab.show() after solver finish or not iter = 0 cpuTimeElapsed = 0. TimeElapsed = 0. isFinished = False invertObjFunc = False # True for goal = 'max' or 'maximum' nProc = 1 # number of processors to use lastPrintedIter = -1 iterObjFunTextFormat = '%0.3e' finalObjFunTextFormat = '%0.8g' debug = 0 iprint = 10 #if iprint<0 -- no output #if iprint==0 -- final output only maxIter = 1000 maxFunEvals = 10000 # TODO: move it to NinLinProblem class? maxCPUTime = inf maxTime = inf maxLineSearch = 500 # TODO: move it to NinLinProblem class? xtol = ProbDefaults['xtol'] # TODO: move it to NinLinProblem class? gtol = 1e-6 # TODO: move it to NinLinProblem class? ftol = 1e-6 contol = 1e-6 fTol = None minIter = 0 minFunEvals = 0 minCPUTime = 0.0 minTime = 0.0 storeIterPoints = False userStop = False # becomes True is stopped by user useSparse = 'auto' # involve sparse matrices: 'auto' (autoselect, premature) | True | False useAttachedConstraints = False x0 = None isFDmodel = False # OO kernel set it to True if oovars/oofuns are used noise = ProbDefaults['noise'] # TODO: move it to NinLinProblem class? showFeas = False useScaledResidualOutput = False hasLogicalConstraints = False # A * x <= b inequalities A = None b = None # Aeq * x = b equalities Aeq = None beq = None scale = None goal = None# should be redefined by child class # possible values: 'maximum', 'min', 'max', 'minimum', 'minimax' etc showGoal = False# can be redefined by child class, used for text & graphic output color = 'b' # blue, color for plotting specifier = '-'# simple line for plotting plotOnlyCurrentMinimum = False # some classes like GLP change the default to True xlim = (nan, nan) ylim = (nan, nan) legend = '' fixedVars = None freeVars = None istop = 0 maxSolutions = 1 # used in interalg and mb other solvers fEnough = -inf # if value less than fEnough will be obtained # and all constraints no greater than contol # then solver will be stopped. # this param is handled in iterfcn of OpenOpt kernel # so it may be ignored with some solvers not closely connected to OO kernel fOpt = None # optimal value, if known implicitBounds = inf def __init__(self, *args, **kwargs): # TODO: add the field to ALL classes self.err = ooerr self.warn = oowarn self.info = ooinfo self.hint = oohint self.pWarn = ooPWarn self.disp = oodisp self.data4TextOutput = ['objFunVal', 'log10(maxResidual)'] self.nEvals = {} if hasattr(self, 'expectedArgs'): if len(self.expectedArgs) 2: # self.pWarn(''' # current implementation of categorical variables with domain size > 2 # that is performed via casting to discrete variable with domain of same lenght # seems to be unstable yet # (may yield incorrect results) and thus is not recommended yet. # It is intended to be fixed in next OpenOpt stable release # (casting to several boolean oovars is intended instead)''') self.x0[key] = searchsorted(key.aux_domain, val, 'left') self.x0 = oopoint(self.x0) if self.probType in ['LP', 'MILP'] and self.f.getOrder(self.freeVars, self.fixedVars) > 1: self.err('for LP/MILP objective function has to be linear, while this one ("%s") is not' % self.f.name) setStartVectorAndTranslators(self) if self.fixedVars is None or (self.freeVars is not None and len(self.freeVars)= v.lb) if not array_equal(v.ub, inf): self.constraints.add(v <= v.ub) if hasattr(self, 'f'): if type(self.f) in [list, tuple, set]: C += list(self.f) else: # self.f is oofun C.append(self.f) if self.useAttachedConstraints: self.constraints.update(_getAllAttachedConstraints(C)) for v in self._freeVars: d = v.domain if d is bool or d is 'bool': #v.domain = array([0, 1]) self.constraints.update([v>0, v<1]) elif d is not None and d is not int and d is not 'int': # TODO: mb add integer domains? v.domain = array(list(d)) v.domain.sort() self.constraints.update([v >= v.domain[0], v <= v.domain[-1]]) if hasattr(v, 'aux_domain'): self.constraints.add(v - (len(v.aux_domain)-1)<=0) # for v in self._categoricalVars: # if isFixed(v): # ind = searchsorted(v.aux_domain, p._x0[v], 'left') # if v.aux_domain """ handling constraints """ StartPointVars = set(self._x0.keys()) self.dictOfFixedFuncs = {} from FuncDesigner import broadcast if self.probType in ['SLE', 'NLSP', 'SNLE', 'LLSP']: for eq in equations: broadcast(formDictOfFixedFuncs, eq, self.dictOfFixedFuncs, areFixed, self._x0) else: broadcast(formDictOfFixedFuncs, self.f, self.dictOfFixedFuncs, areFixed, self._x0) handleConstraint_args = (StartPointVars, areFixed, oovD, A, b, Aeq, beq, Z, D_kwargs, LB, UB) for c in self.constraints: if isinstance(c, ooarray): for elem in c: self.handleConstraint(elem, *handleConstraint_args) elif not hasattr(c, 'isConstraint'): self.err('The type ' + str(type(c)) + ' is inappropriate for problem constraints') else: self.handleConstraint(c, *handleConstraint_args) if len(b) != 0: self.A, self.b = Vstack(A), Hstack(b) if hasattr(self.b, 'toarray'): self.b = self.b.toarray() if len(beq) != 0: self.Aeq, self.beq = Vstack(Aeq), Hstack(beq) if hasattr(self.beq, 'toarray'): self.beq = self.beq.toarray() for vName, vVal in LB.items(): inds = oovD[vName] lb[inds[0]:inds[1]] = vVal for vName, vVal in UB.items(): inds = oovD[vName] ub[inds[0]:inds[1]] = vVal self.lb, self.ub = lb, ub else: # not namedvariablesStyle if self.fixedVars is not None or self.freeVars is not None: self.err('fixedVars and freeVars are valid for optimization of FuncDesigner models only') if self.x0 is None: arr = ['lb', 'ub'] if self.probType in ['LP', 'MILP', 'QP', 'SOCP', 'SDP']: arr.append('f') if self.probType in ['LLSP', 'LLAVP', 'LUNP']: arr.append('D') for fn in arr: if not hasattr(self, fn): continue fv = asarray(getattr(self, fn)) if any(isfinite(fv)): self.x0 = zeros(fv.size) break self.x0 = ravel(self.x0) if not hasattr(self, 'n'): self.n = self.x0.size if not hasattr(self, 'lb'): self.lb = -inf * ones(self.n) if not hasattr(self, 'ub'): self.ub = inf * ones(self.n) for fn in ('A', 'Aeq'): fv = getattr(self, fn) if fv is not None: #afv = asfarray(fv) if not isspmatrix(fv) else fv.toarray() # TODO: omit casting to dense matrix afv = asfarray(fv) if type(fv) in [list, tuple] else fv if len(afv.shape) > 1: if afv.shape[1] != self.n: self.err('incorrect ' + fn + ' size') else: if afv.shape != () and afv.shape[0] == self.n: afv = afv.reshape(1, self.n) setattr(self, fn, afv) else: setattr(self, fn, asfarray([]).reshape(0, self.n)) nA, nAeq = prod(self.A.shape), prod(self.Aeq.shape) SizeThreshold = 2 ** 15 if scipyInstalled: from scipy.sparse import csc_matrix if isspmatrix(self.A) or (nA > SizeThreshold and flatnonzero(self.A).size < 0.25*nA): self._A = csc_matrix(self.A) if isspmatrix(self.Aeq) or (nAeq > SizeThreshold and flatnonzero(self.Aeq).size < 0.25*nAeq): self._Aeq = csc_matrix(self.Aeq) elif nA > SizeThreshold or nAeq > SizeThreshold: self.pWarn(scipyAbsentMsg) self._baseProblemIsPrepared = True def handleConstraint(self, c, StartPointVars, areFixed, oovD, A, b, Aeq, beq, Z, D_kwargs, LB, UB): from FuncDesigner.ooFun import SmoothFDConstraint, BooleanOOFun if not isinstance(c, SmoothFDConstraint) and isinstance(c, BooleanOOFun): self.hasLogicalConstraints = True #continue probtol = self.contol f, tol = c.oofun, c.tol _lb, _ub = c.lb, c.ub f0, lb_0, ub_0 = f, copy(_lb), copy(_ub) Name = f.name dep = set([f]) if f.is_oovar else f._getDep() isFixed = areFixed(dep) if f.is_oovar and isFixed: if self._x0 is None or f not in self._x0: self.err('your problem has fixed oovar '+ Name + ' but no value for the one in start point is provided') return if not dep.issubset(StartPointVars): self.err('your start point has no enough variables to define constraint ' + c.name) if tol < 0: if any(_lb == _ub): self.err("You can't use negative tolerance for the equality constraint " + c.name) elif any(_lb - tol >= _ub + tol): self.err("You can't use negative tolerance for so small gap in constraint" + c.name) Shift = (1.0+1e-13)*probtol ####################### # not inplace modification!!!!!!!!!!!!! _lb = _lb + Shift _ub = _ub - Shift ####################### if tol != 0: self.useScaledResidualOutput = True # TODO: omit it for interalg if tol not in (0, probtol, -probtol): scaleFactor = abs(probtol / tol) f *= scaleFactor #c.oofun = f#c.oofun * scaleFactor _lb, _ub = _lb * scaleFactor, _ub * scaleFactor Contol = tol Contol2 = Contol * scaleFactor else: Contol = asscalar(copy(probtol)) Contol2 = Contol #Contol = tol if tol != 0 else copy(self.contol) if isFixed: # TODO: get rid of self.contol, use separate contols for each constraint if not c(self._x0, tol=Contol): s = """'constraint "%s" with all-fixed optimization variables it depends on is infeasible in start point, hence the problem is infeasible, maybe you should change start point'""" % c.name self.err(s) # TODO: check doesn't constraint value exeed self.contol return from FuncDesigner import broadcast broadcast(formDictOfFixedFuncs, f, self.dictOfFixedFuncs, areFixed, self._x0) #self.dictOfFixedFuncs[f] = f(self.x0) if self.probType in ['LP', 'MILP', 'LLSP', 'LLAVP'] and f.getOrder(self.freeVars, self.fixedVars) > 1: self.err('for LP/MILP/LLSP/LLAVP all constraints have to be linear, while ' + f.name + ' is not') # TODO: simplify condition of box-bounded oovar detection if f.is_oovar: inds = oovD[f] f_size = inds[1] - inds[0] if any(isfinite(_lb)): if _lb.size not in (f_size, 1): self.err('incorrect size of lower box-bound constraint for %s: 1 or %d expected, %d obtained' % (Name, f_size, _lb.size)) # for PyPy compatibility if type(_lb) == ndarray and _lb.size == 1: _lb = _lb.item() val = array(f_size*[_lb] if type(_lb) == ndarray and _lb.size < f_size else _lb) if f not in LB: LB[f] = val else: #max((val, LB[f])) doesn't work for arrays if val.size > 1 or LB[f].size > 1: LB[f][val > LB[f]] = val[val > LB[f]] if val.size > 1 else asscalar(val) else: LB[f] = max((val, LB[f])) if any(isfinite(_ub)): if _ub.size not in (f_size, 1): self.err('incorrect size of upper box-bound constraint for %s: 1 or %d expected, %d obtained' % (Name, f_size, _ub.size)) # for PyPy compatibility if type(_ub) == ndarray and _ub.size == 1: _ub = _ub.item() val = array(f_size*[_ub] if type(_ub) == ndarray and _ub.size < f_size else _ub) if f not in UB: UB[f] = val else: #min((val, UB[f])) doesn't work for arrays if val.size > 1 or UB[f].size > 1: UB[f][val < UB[f]] = val[val < UB[f]] if val.size > 1 else asscalar(val) else: UB[f] = min((val, UB[f])) elif _lb == _ub: if f.getOrder(self.freeVars, self.fixedVars) < 2: Aeq.append(self._pointDerivative2array(f.D(Z, **D_kwargs))) beq.append(-f(Z)+_lb) elif self.h is None: self.h = [f-_lb] else: self.h.append(f-_lb) elif isfinite(_ub): if f.getOrder(self.freeVars, self.fixedVars) < 2: A.append(self._pointDerivative2array(f.D(Z, **D_kwargs))) b.append(-f(Z)+_ub) elif self.c is None: self.c = [f - _ub] else: self.c.append(f - _ub) elif isfinite(_lb): if f.getOrder(self.freeVars, self.fixedVars) < 2: A.append(-self._pointDerivative2array(f.D(Z, **D_kwargs))) b.append(f(Z) - _lb) elif self.c is None: self.c = [- f + _lb] else: self.c.append(- f + _lb) else: self.err('inform OpenOpt developers of the bug') if not f.is_oovar: Contol = max((0, Contol2)) # TODO: handle it more properly, especially for lb, ub of array type # FIXME: name of f0 vs f # self._FD.nonBoxConsWithTolShift.append((f0, lb_0 - Contol, ub_0 + Contol)) # self._FD.nonBoxCons.append((f0, lb_0, ub_0, Contol)) self._FD.nonBoxConsWithTolShift.append((c, f, _lb - Contol, _ub + Contol)) self._FD.nonBoxCons.append((c, f, _lb, _ub, Contol)) def formDictOfFixedFuncs(oof, dictOfFixedFuncs, areFixed, startPoint): dep = set([oof]) if oof.is_oovar else oof._getDep() if areFixed(dep): dictOfFixedFuncs[oof] = oof(startPoint) class MatrixProblem(baseProblem): _baseClassName = 'Matrix' ftol = 1e-8 contol = 1e-8 #obsolete, should be removed # still it is used by lpSolve # Awhole * x {<= | = | >= } b Awhole = None # matrix m x n, n = len(x) bwhole = None # vector, size = m x 1 dwhole = None #vector of descriptors, size = m x 1 # descriptors dwhole[j] should be : # 1 : [j] greater (or equal) than bwhole[j] # -1 : [j] less (or equal) than bwhole[j] # 0 : [j] = bwhole[j] def __init__(self, *args, **kwargs): baseProblem.__init__(self, *args, **kwargs) self.kernelIterFuncs = setDefaultIterFuncs('Matrix') def _Prepare(self): if self.prepared == True: return baseProblem._prepare(self) self.prepared = True # TODO: move the function to child classes def _isUnconstrained(self): if self.b.size !=0 or self.beq.size != 0: return False # for PyPy compatibility if any(atleast_1d(self.lb) != -inf) or any(atleast_1d(self.ub) != inf): return False return True class Parallel: def __init__(self): self.f = False# 0 - don't use parallel calclations, 1 - use self.c = False self.h = False #TODO: add paralell func! #self.parallel.fun = dfeval class Args: def __init__(self): pass f, c, h = (), (), () class NonLinProblem(baseProblem, nonLinFuncs, Args): _baseClassName = 'NonLin' diffInt = ProbDefaults['diffInt'] #finite-difference gradient aproximation step #non-linear constraints c = None # c(x)<=0 h = None # h(x)=0 #lines with |info_user-info_numerical| / (|info_user|+|info_numerical+1e-15) greater than maxViolation will be shown maxViolation = 1e-2 JacobianApproximationStencil = 1 def __init__(self, *args, **kwargs): baseProblem.__init__(self, *args, **kwargs) if not hasattr(self, 'args'): self.args = Args() self.prevVal = {} for fn in ['f', 'c', 'h', 'df', 'dc', 'dh', 'd2f', 'd2c', 'd2h']: self.prevVal[fn] = {'key':None, 'val':None} self.functype = {} #self.isVectoriezed = False # self.fPattern = None # self.cPattern = None # self.hPattern = None self.kernelIterFuncs = setDefaultIterFuncs('NonLin') def checkdf(self, *args, **kwargs): return self.checkGradient('df', *args, **kwargs) def checkdc(self, *args, **kwargs): return self.checkGradient('dc', *args, **kwargs) def checkdh(self, *args, **kwargs): return self.checkGradient('dh', *args, **kwargs) def checkGradient(self, funcType, *args, **kwargs): self._Prepare() if not DerApproximatorIsInstalled: self.err('To perform gradients check you should have DerApproximator installed, see http://openopt.org/DerApproximator') if not getattr(self.userProvided, funcType): self.warn("you haven't analitical gradient provided for " + funcType[1:] + ', turning derivatives check for it off...') return if len(args)>0: if len(args)>1 or 'x' in kwargs: self.err('checkd funcs can have single argument x only (then x should be absent in kwargs )') xCheck = asfarray(args[0]) elif 'x' in kwargs: xCheck = asfarray(kwargs['x']) else: xCheck = asfarray(self.x0) maxViolation = 0.01 if 'maxViolation' in kwargs: maxViolation = kwargs['maxViolation'] self.disp(funcType + (': checking user-supplied gradient of shape (%d, %d)' % (getattr(self, funcType[1:])(xCheck).size, xCheck.size))) self.disp('according to:') self.disp(' diffInt = ' + str(self.diffInt)) # TODO: ADD other parameters: allowed epsilon, maxDiffLines etc self.disp(' |1 - info_user/info_numerical| < maxViolation = '+ str(maxViolation)) check_d1(getattr(self, funcType[1:]), getattr(self, funcType), xCheck, **kwargs) # reset counters that were modified during check derivatives self.nEvals[funcType[1:]] = 0 self.nEvals[funcType] = 0 def _makeCorrectArgs(self): argslist = dir(self.args) if not ('f' in argslist and 'c' in argslist and 'h' in argslist): tmp, self.args = self.args, autocreate() self.args.f = self.args.c = self.args.h = tmp for j in ('f', 'c', 'h'): v = getattr(self.args, j) if type(v) != type(()): setattr(self.args, j, (v,)) def __finalize__(self): #BaseProblem.__finalize__(self) if self.isFDmodel: self.xf = self._vector2point(self.xf) def _Prepare(self): baseProblem._prepare(self) if asarray(self.implicitBounds).size == 1: self.implicitBounds = [-self.implicitBounds, self.implicitBounds] self.implicitBounds.sort()# for more safety, maybe user-provided value is negative if hasattr(self, 'solver'): if not self.solver.iterfcnConnected: if self.solver.funcForIterFcnConnection == 'f': if not hasattr(self, 'f_iter'): self.f_iter = max((self.n, 4)) else: if not hasattr(self, 'df_iter'): self.df_iter = True if self.prepared == True: return # TODO: simplify it self._makeCorrectArgs() for s in ('f', 'df', 'd2f', 'c', 'dc', 'd2c', 'h', 'dh', 'd2h'): derivativeOrder = len(s)-1 self.nEvals[Copy(s)] = 0 if hasattr(self, s) and getattr(self, s) not in (None, (), []) : setattr(self.userProvided, s, True) A = getattr(self,s) if type(A) not in [list, tuple]: #TODO: add or ndarray(A) A = (A,)#make tuple setattr(self.user, s, A) else: setattr(self.userProvided, s, False) if derivativeOrder == 0: setattr(self, s, lambda x, IND=None, userFunctionType= s, ignorePrev=False, getDerivative=False: \ self.wrapped_func(x, IND, userFunctionType, ignorePrev, getDerivative)) elif derivativeOrder == 1: setattr(self, s, lambda x, ind=None, funcType=s[-1], ignorePrev = False, useSparse=self.useSparse: self.wrapped_1st_derivatives(x, ind, funcType, ignorePrev, useSparse)) elif derivativeOrder == 2: setattr(self, s, getattr(self, 'user_'+s)) else: self.err('incorrect non-linear function case') self.diffInt = ravel(self.diffInt) # TODO: mb get rid of the field self.vectorDiffInt = self.diffInt.size > 1 if self.scale is not None: self.scale = ravel(self.scale) if self.vectorDiffInt or self.diffInt[0] != ProbDefaults['diffInt']: self.info('using both non-default scale & diffInt is not recommended. diffInt = diffInt/scale will be used') self.diffInt = self.diffInt / self.scale #initialization, getting nf, nc, nh etc: for s in ['c', 'h', 'f']: if not getattr(self.userProvided, s): setattr(self, 'n'+s, 0) else: setNonLinFuncsNumber(self, s) self.prepared = True # TODO: move the function to child classes def _isUnconstrained(self): # s = ((), [], array([]), None) # print '1:',all(isinf(self.lb)) # print self.b.size,self.beq.size return self.b.size ==0 and self.beq.size==0 and not self.userProvided.c and not self.userProvided.h \ and (len(self.lb)==0 or all(isinf(self.lb))) and (len(self.ub)==0 or all(isinf(self.ub))) def minimize(p, *args, **kwargs): if 'goal' in kwargs: if kwargs['goal'] in ['min', 'minimum']: p.warn("you shouldn't pass 'goal' to the function 'minimize'") else: p.err('ambiguous goal has been requested: function "minimize", goal: %s' % kwargs['goal']) p.goal = 'minimum' return runProbSolver(p, *args, **kwargs) def maximize(p, *args, **kwargs): if 'goal' in kwargs: if kwargs['goal'] in ['max', 'maximum']: p.warn("you shouldn't pass 'goal' to the function 'maximize'") else: p.err('ambiguous goal has been requested: function "maximize", goal: %s' % kwargs['goal']) p.goal = 'maximum' return runProbSolver(p, *args, **kwargs) openopt-0.38+svn1589/openopt/kernel/baseSolver.py000066400000000000000000000112311175775750500217250ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import atleast_1d, all, asarray, ndarray, copy, ravel, isnan, where, isscalar, asscalar from openopt.kernel.Point import Point class baseSolver: def __init__(self):pass __name__ = 'Undefined. If you are a user and got the message, inform developers please.' __license__ = "Undefined. If you are a user and got the message, inform developers please." __authors__ = "Undefined. If you are a user and got the message, inform developers please." __alg__ = "Undefined" __solver__ = "Undefined. If you are a user and got the message, inform developers please." __homepage__ = 'Undefined. Use web search' __info__ = 'None' _requiresBestPointDetection = False _requiresFiniteBoxBounds = False """__cannotHandleExceptions__ is True for ipopt and mb some others, somehow exceptions raised in OO and passed through ipopt cannot be catched by OO """ __cannotHandleExceptions__ = False __optionalDataThatCanBeHandled__ = [] __isIterPointAlwaysFeasible__ = lambda self, p: p.isUC#TODO: provide possibility of simple True, False iterfcnConnected = False funcForIterFcnConnection = 'df' # the field is used for non-linear solvers with not-connected iter function _canHandleScipySparse = False # True if can handle linear constraints Ax<=b, Aeq x = beq and nonlin cons derivs properTextOutput = False # these ones below are used in iterfcn (ooIter.py) # to decode input args # and can be overdetermined by child class (LP, QP, network etc) __expectedArgs__ = ['xk', 'fk', 'rk'] #point, objFunVal, max residual def __decodeIterFcnArgs__(self, p, *args, **kwargs): """ decode and assign x, f, maxConstr (and/or other fields) to p.iterValues """ fArg = True if len(args)>0 and isinstance(args[0], Point): if len(args) != 1: p.err('incorrect iterfcn args, if you see this contact OO developers') point = args[0] p.xk, p.fk = point.x, point.f() p.rk, p.rtk, p.rik = point.mr(True) p.nNaNs = point.nNaNs() if p.solver._requiresBestPointDetection and (p.iter == 0 or point.betterThan(p._bestPoint)): p._bestPoint = point else: if len(args)>0: p.xk = args[0] elif 'xk' in kwargs.keys(): p.xk = kwargs['xk'] elif not hasattr(p, 'xk'): p.err('iterfcn must get x value, if you see it inform oo developers') if p._baseClassName == 'NonLin': p.nNaNs = len(where(isnan(p.c(p.xk)))[0]) + len(where(isnan(p.h(p.xk)))[0]) if p.solver._requiresBestPointDetection: currPoint = p.point(p.xk) if p.iter == 0 or currPoint.betterThan(p._bestPoint): p._bestPoint = currPoint if len(args)>1: p.fk = args[1] elif 'fk' in kwargs.keys(): p.fk = kwargs['fk'] else: fArg = False if len(args)>2: #p.pWarn('executing deprecated code, inform developers') p.rk = args[2] elif 'rk' in kwargs.keys(): #p.pWarn('executing deprecated code, inform developers') p.rk = kwargs['rk'] else: p.rk, p.rtk, p.rik = p.getMaxResidual(p.xk, True) p.iterValues.r.append(ravel(p.rk)[0]) if p.probType != 'IP': # recalculations are not performed p.rk, p.rtk, p.rik = p.getMaxResidual(p.xk, True) p.iterValues.rt.append(p.rtk) p.iterValues.ri.append(p.rik) if p._baseClassName == 'NonLin': p.iterValues.nNaNs.append(p.nNaNs) #TODO: handle kwargs correctly! (decodeIterFcnArgs) # for key in kwargs.keys(): # if p.debug: print 'decodeIterFcnArgs>>', key, kwargs[key] # setattr(p, key, kwargs[key]) p.iterValues.x.append(copy(p.xk)) if not p.storeIterPoints and len(p.iterValues.x) > 2: p.iterValues.x.pop(0) if not fArg: p.Fk = p.F(p.xk) p.fk = copy(p.Fk) else: if asarray(p.fk).size >1: if p.debug and p.iter <= 1: p.warn('please fix solver iter output func, objFuncVal should be single number (use p.F)') p.Fk = p.objFuncMultiple2Single(asarray(p.fk)) else: p.Fk = p.fk #if p.isObjFunValueASingleNumber: p.Fk = p.fk #else: p.Fk = p.objFuncMultiple2Single(fv) v = ravel(p.Fk)[0] if p.invertObjFunc: v = -v p.iterValues.f.append(v) if not isscalar(p.fk) and p.fk.size == 1: p.fk = asscalar(p.fk) openopt-0.38+svn1589/openopt/kernel/check.py000066400000000000000000000017621175775750500207050ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import array, isfinite, any, asarray def check(p): """ this func is called from runProbSolver(), you don't need to call the one """ nErrors = 0 if p.allowedGoals is not None and p.goal is not None and p.goal not in p.allowedGoals: # p.goal is None in EIG p.err('goal '+ p.goal+' is not available for the '+ p.probType + ' class (at least not implemented yet)') for fn in p._optionalData: attr = getattr(p, fn, None) if (attr is None or isinstance(attr, (list,tuple)) and len(attr)==0) or fn in p.solver.__optionalDataThatCanBeHandled__: continue if fn == 'Qc' or \ (callable(attr) and getattr(p.userProvided, fn)) or \ (type(attr) in (set, dict, list, tuple) and len(attr) != 0) or \ (not callable(attr) and asarray(attr).size>0 and any(isfinite(attr))): p.err('the solver ' + p.solver.__name__ + ' cannot handle ' + "'" + fn + "' data") return nErrors openopt-0.38+svn1589/openopt/kernel/fdmisc.py000066400000000000000000000336731175775750500211030ustar00rootroot00000000000000# Handling of FuncDesigner probs from numpy import empty, isscalar, hstack, vstack, asfarray, all, atleast_1d, cumsum, asarray, zeros, atleast_2d, ndarray, prod, ones, copy, nan, flatnonzero, array_equal from nonOptMisc import scipyInstalled, Hstack, Vstack, Find, isspmatrix, SparseMatrixConstructor, DenseMatrixConstructor try: # available since numpy 1.6.x from numpy import count_nonzero except: count_nonzero = lambda elem: len(flatnonzero(asarray(elem))) def setStartVectorAndTranslators(p): startPoint = p.x0 #assert all(asarray([atleast_1d(val).ndim for val in startPoint.values()]) == 1) # !!!! TODO: handle fixed oovars #oovars = list(startPoint.keys()) fixedVars, freeVars = None, None from FuncDesigner import ooarray def getVars(t): vars1 = [v for v in (t if t is not None else []) if type(v) != ooarray] vars2 = [v for v in (t if t is not None else []) if type(v) == ooarray] t = vars1 for elem in vars2: t += elem.tolist() return t if p.freeVars is not None: if not isinstance(p.freeVars, (list, tuple, ndarray, set)): assert hasattr(p.freeVars, 'is_oovar') p.freeVars = [p.freeVars] freeVars = p.freeVars else: freeVars = list(p.freeVars) freeVars = getVars(freeVars) fixedVars = list(set(startPoint.keys()).difference(set(freeVars))) p.fixedVars = fixedVars elif p.fixedVars is not None: if not isinstance(p.fixedVars, (list, tuple, ndarray, set)): assert hasattr(p.fixedVars, 'is_oovar') p.fixedVars = [p.fixedVars] fixedVars = p.fixedVars else: fixedVars = list(p.fixedVars) p.fixedVars = fixedVars fixedVars = getVars(fixedVars) freeVars = list(set(startPoint.keys()).difference(set(fixedVars))) p.freeVars = freeVars else: freeVars = list(startPoint.keys()) # TODO: use ordered set instead freeVars.sort(key=lambda elem: elem._id) # fixedVars.sort() p._freeVarsList = freeVars # to use in interalg, a global solver from UkrOpt p._discreteVarsNumList = [] p._discreteVarsList = [] for i, v in enumerate(p._freeVarsList): if v.domain is not None: p._discreteVarsNumList.append(i) p._discreteVarsList.append(v) p._fixedVars = set(fixedVars) if fixedVars is not None else set() p._freeVars = set(freeVars) if freeVars is not None else set() # point should be FuncDesigner point that currently is Python dict # point2vector = lambda point: atleast_1d(hstack([asfarray(point[oov]) for oov in freeVars])) p._optVarSizes = dict([(oov, asarray(startPoint[oov]).size) for oov in freeVars]) sizes = p._optVarSizes point2vector = lambda point: atleast_1d(hstack([(point[oov] if oov in point else zeros(sizes[oov])) for oov in p._optVarSizes])) # 2nd case can trigger from objective/constraints defined over some of opt oovars only vector_x0 = point2vector(startPoint) n = vector_x0.size p.n = n #oovar_sizes = [asarray(startPoint[elem]).size for elem in freeVars] # temporary walkaround for pypy oovar_sizes = [len(atleast_1d(startPoint[elem]).flatten()) for elem in freeVars] # for elem in freeVars: # print startPoint[elem] # if type(startPoint[elem]) == ndarray: # print '----' # print type(startPoint[elem]) # print startPoint[elem].size # print len(startPoint[elem]) oovar_indexes = cumsum([0] + oovar_sizes) # TODO: mb use oovarsIndDict here as well (as for derivatives?) from FuncDesigner import oopoint startDictData = [] if fixedVars is not None: for v in fixedVars: val = startPoint.get(v, 'absent') if val == 'absent': p.err('value for fixed variable %s is absent in start point' % v.name) startDictData.append((v, val)) #vector2point = lambda x: oopoint(startDictData + [(oov, x[oovar_indexes[i]:oovar_indexes[i+1]]) for i, oov in enumerate(freeVars)]) p._FDtranslator = {'prevX':nan} def vector2point(x): # x = asarray(x) # if not str(x.dtype).startswith('float'): # x = asfarray(x) x = atleast_1d(x).copy() if array_equal(x, p._FDtranslator['prevX']): return p._FDtranslator['prevVal'] # without copy() ipopt and probably others can replace it by noise after closing # r = oopoint(startDictData + \ # [(oov, x[oovar_indexes[i]:oovar_indexes[i+1]]) for i, oov in enumerate(freeVars)]) r = startDictData tmp = [(oov, x[oovar_indexes[i]:oovar_indexes[i+1]] if oovar_indexes[i+1]-oovar_indexes[i]>1 else x[oovar_indexes[i]]) for i, oov in enumerate(freeVars)] # for i, oov in enumerate(freeVars): # #I, J = oovar_indexes[i], oovar_indexes[i+1] # #r.append((oov, x[I] if J - I == 1 else x[I:J])) # r.append((oov, x[oovar_indexes[i]:oovar_indexes[i+1]])) r = oopoint(r+tmp, skipArrayCast = True) p._FDtranslator['prevVal'] = r p._FDtranslator['prevX'] = copy(x) return r oovarsIndDict = dict([(oov, (oovar_indexes[i], oovar_indexes[i+1])) for i, oov in enumerate(freeVars)]) def pointDerivative2array(pointDerivarive, useSparse = 'auto', func=None, point=None): # useSparse can be True, False, 'auto' if not scipyInstalled and useSparse == 'auto': useSparse = False if useSparse is True and not scipyInstalled: p.err('to handle sparse matrices you should have module scipy installed') if len(pointDerivarive) == 0: if func is not None: funcLen = func(point).size if useSparse is not False: return SparseMatrixConstructor((funcLen, n)) else: return DenseMatrixConstructor((funcLen, n)) else: p.err('unclear error, maybe you have constraint independend on any optimization variables') Items = pointDerivarive.items() key, val = Items[0] if type(Items) == list else next(iter(Items)) if isinstance(val, float) or (isinstance(val, ndarray) and val.shape == ()): val = atleast_1d(val) var_inds = oovarsIndDict[key] # val.size works in other way (as nnz) for scipy.sparse matrices funcLen = int(round(prod(val.shape) / (var_inds[1] - var_inds[0]))) # CHANGES # 1. Calculate number of zero/nonzero elements involveSparse = useSparse if useSparse == 'auto': nTotal = n * funcLen#sum([prod(elem.shape) for elem in pointDerivarive.values()]) nNonZero = sum([(elem.size if isspmatrix(elem) else count_nonzero(elem)) for elem in pointDerivarive.values()]) involveSparse = 4*nNonZero < nTotal and nTotal > 1000 if involveSparse:# and newStyle: # USE STACK r2 = [] hasSparse = False if len(freeVars) > 5 * len(pointDerivarive): ind_Z = 0 derivative_items = list(pointDerivarive.items()) derivative_items.sort(key=lambda elem: elem[0]._id) for oov, val in derivative_items: ind_start, ind_end = oovarsIndDict[oov] if ind_start != ind_Z: r2.append(SparseMatrixConstructor((funcLen, ind_start - ind_Z))) if not isspmatrix(val): val = asarray(val) # else bug with scipy sparse hstack r2.append(val) ind_Z = ind_end if ind_Z != n: # assert ind_Z < n r2.append(SparseMatrixConstructor((funcLen, n - ind_Z))) else: zeros_start_ind = 0 zeros_end_ind = 0 for i, var in enumerate(freeVars): if var in pointDerivarive:#i.e. one of its keys if zeros_end_ind != zeros_start_ind: r2.append(SparseMatrixConstructor((funcLen, zeros_end_ind - zeros_start_ind))) zeros_start_ind = zeros_end_ind tmp = pointDerivarive[var] if isspmatrix(tmp): hasSparse = True else: tmp = asarray(tmp) # else bug with scipy sparse hstack if tmp.ndim < 2: tmp = tmp.reshape(funcLen, prod(tmp.shape) // funcLen) r2.append(tmp) else: zeros_end_ind += oovar_sizes[i] hasSparse = True if zeros_end_ind != zeros_start_ind: r2.append(SparseMatrixConstructor((funcLen, zeros_end_ind - zeros_start_ind))) r3 = Hstack(r2) #if hasSparse else hstack(r2) if isspmatrix(r3) and r3.nnz > 0.25 * prod(r3.shape): r3 = r3.A return r3 else: # USE INSERT if funcLen == 1: r = DenseMatrixConstructor(n) else: r = SparseMatrixConstructor((funcLen, n)) if involveSparse else DenseMatrixConstructor((funcLen, n)) #r = DenseMatrixConstructor((funcLen, n)) for key, val in pointDerivarive.items(): # TODO: remove indexes, do as above for sparse indexes = oovarsIndDict[key] if not involveSparse and isspmatrix(val): val = val.A # if isscalar(val) or prod(val.shape)==1: # r[indexes[0]] = val.flatten() if type(val) == ndarray else val # el if r.ndim == 1: r[indexes[0]:indexes[1]] = val.flatten() if type(val) == ndarray else val else: r[:, indexes[0]:indexes[1]] = val if val.shape == r.shape else val.reshape((funcLen, prod(val.shape)/funcLen)) if useSparse is True and funcLen == 1: return SparseMatrixConstructor(r) elif r.ndim <= 1: r = r.reshape(1, -1) if useSparse is False and hasattr(r, 'toarray'): r = r.toarray() return r def getPattern(oofuns): # oofuns is Python list of oofuns assert isinstance(oofuns, list), 'oofuns should be Python list, inform developers of the bug' R = [] for oof in oofuns: SIZE = asarray(oof(startPoint)).size r = [] dep = oof._getDep() if len(p._fixedVars) != 0: dep = dep & p._freeVars if len(p._freeVars) < len(p._fixedVars) else dep.difference(p._fixedVars) # NEW ind_Z = 0 vars = list(dep) vars.sort(key=lambda elem: elem._id) for oov in vars: ind_start, ind_end = oovarsIndDict[oov] if ind_start != ind_Z: r.append(SparseMatrixConstructor((SIZE, ind_start - ind_Z))) r.append(ones((SIZE, ind_end - ind_start))) ind_Z = ind_end if ind_Z != n: # assert ind_Z < n r.append(SparseMatrixConstructor((SIZE, n - ind_Z))) # OLD # Depends = True if freeVars[0] in dep else False # ind_start = 0 # ind_end = asarray(startPoint[freeVars[0]]).size # for oov in freeVars[1:]: # tmp = startPoint[oov] # depends = True if oov in dep else False # if Depends != depends: # if ind_start != ind_end: # constructor = ones if Depends else SparseMatrixConstructor # r.append(constructor((SIZE, ind_end-ind_start))) # ind_start = ind_end # Depends = depends # ind_end += len(tmp) if not isscalar(tmp) else 1 # if ind_start != ind_end: # constructor = ones if Depends else SparseMatrixConstructor # r.append(constructor((SIZE, ind_end-ind_start))) if any([isspmatrix(elem) for elem in r]): rr = Hstack(r) if len(r) > 1 else r[0] elif len(r)>1: rr = hstack(r) else: rr = r[0] R.append(rr) result = Vstack(R) if any([isspmatrix(_r) for _r in R]) else vstack(R) return result p._getPattern = getPattern p.freeVars, p.fixedVars = freeVars, fixedVars p._point2vector, p._vector2point = point2vector, vector2point p._pointDerivative2array = pointDerivative2array p._oovarsIndDict = oovarsIndDict # TODO: replave p.x0 in RunProbSolver finish p._x0, p.x0 = p.x0, vector_x0 def linearOOFunsToMatrices(oofuns): #, useSparse = 'auto' # oofuns should be linear C, d = [], [] Z = p._vector2point(zeros(p.n)) for elem in oofuns: if elem.isConstraint: lin_oofun = elem.oofun else: lin_oofun = elem if lin_oofun.getOrder(p.freeVars, p.fixedVars) > 1: raise OpenOptException("this function hasn't been intended to work with nonlinear FuncDesigner oofuns") C.append(p._pointDerivative2array(lin_oofun.D(Z, **p._D_kwargs), useSparse = p.useSparse)) d.append(-lin_oofun(Z)) if any([isspmatrix(elem) for elem in C]): from scipy.sparse import vstack as Vstack else: Vstack = vstack # i.e. numpy.vstack C, d = Vstack(C), hstack(d).flatten() return C, d p._linearOOFunsToMatrices = linearOOFunsToMatrices openopt-0.38+svn1589/openopt/kernel/iterPrint.py000066400000000000000000000030001175775750500215730ustar00rootroot00000000000000from numpy import atleast_1d, asfarray, log10 def signOfFeasible(p): r = '-' if p.isFeas(p.xk): r = '+' return r textOutputDict = {\ 'objFunVal': lambda p: p.iterObjFunTextFormat % (-p.fk if p.invertObjFunc else p.fk), 'log10(maxResidual)': lambda p: '%0.2f' % log10(p.rk+1e-100), 'log10(MaxResidual/ConTol)':lambda p: '%0.2f' % log10(max((p.rk/p.contol, 1e-100))), 'residual':lambda p: '%0.1e' % p._Residual, 'isFeasible': signOfFeasible, 'nSolutions': lambda p: '%d' % p._nObtainedSolutions, 'front length':lambda p: '%d' % p._frontLength, 'outcome': lambda p: ('%+d' % -p._nOutcome if p._nOutcome != 0 else ''), 'income': lambda p: ('%+d' % p._nIncome if p._nIncome != 0 else ''), } delimiter = ' ' class ooTextOutput: def __init__(self): pass def iterPrint(self): if self.lastPrintedIter == self.iter: return if self.iter == 0 and self.iprint >= 0: # 0th iter (start) s = ' iter' + delimiter for fn in self.data4TextOutput: s += fn + delimiter print(s) elif self.iprint<0 or \ (((self.iprint>0 and self.iter % self.iprint != 0) or self.iprint==0) and not(self.isFinished or self.iter == 0)): return s = str(self.iter).rjust(5) + ' ' for columnName in self.data4TextOutput: val = textOutputDict[columnName](self) #nWhole = length(columnName) s += val.rjust(len(columnName)) + ' ' print(s) self.lastPrintedIter = self.iter openopt-0.38+svn1589/openopt/kernel/mfa.py000066400000000000000000000445321175775750500203750ustar00rootroot00000000000000#!/usr/bin/env python from numpy import inf, copy, abs, all, floor, log10, asfarray, asscalar, argsort TkinterIsInstalled = True try: from Tkinter import Tk, Toplevel, Button, Entry, Menubutton, Label, Frame, StringVar, DISABLED, ACTIVE, END, IntVar, \ Radiobutton, Canvas, Image, PhotoImage from tkFileDialog import asksaveasfilename, askopenfile from tkMessageBox import showerror except ImportError: TkinterIsInstalled = False xtolScaleFactor = 1e-5 class mfa: filename = None # Python pickle file where to save results x0 = None solved = False def startSession(self): assert TkinterIsInstalled, ''' Tkinter is not installed. If you have Linux you could try using "apt-get install python-tk"''' try: import nlopt except ImportError: s = ''' To use OpenOpt multifactor analysis tool you should have nlopt with its Python API installed, see http://openopt.org/nlopt''' print(s) showerror('OpenOpt', s) raw_input() return import os hd = os.getenv("HOME") self.hd = hd root = Tk() self.root = root from openopt import __version__ as oover root.wm_title(' OpenOpt %s Multifactor analysis tool for experiment planning ' % oover) SessionSelectFrame = Frame(root) SessionSelectFrame.pack(side='top', padx=230, ipadx = 40, fill='x', expand=True) var = StringVar() var.set('asdf') Radiobutton(SessionSelectFrame, variable = var, text = 'New', indicatoron=0, \ command=lambda: (SessionSelectFrame.destroy(), self.create())).pack(side = 'top', fill='x', pady=5) Radiobutton(SessionSelectFrame, variable = var, text = 'Load', indicatoron=0, \ command=lambda:self.load(SessionSelectFrame)).pack(side = 'top', fill='x', pady=5) root.protocol("WM_DELETE_WINDOW", self.exit) root.mainloop() self.exit() def create(self, S={}): root = self.root # #BackgroundFile = Image(file='/home/dmitrey/tmp_i/Backgd01.jpg') # bgfile = '/home/dmitrey/tmp_i/Backgd01.gif' # #bgfile = '/home/dmitrey/IP.png' # BackgroundFile = PhotoImage(file=bgfile) # #RootFrame.create_image(0, 0, image=BackgroundFile) RootFrame = Canvas(root)#, image=BackgroundFile) # RootFrame.create_image(0, 0, image=BackgroundFile) # RootFrame.image = BackgroundFile RootFrame.pack() self.NameEntriesList, self.LB_EntriesList, self.UB_EntriesList, self.TolEntriesList, self.ValueEntriesList = [], [], [], [], [] self.calculated_points = S.get('calculated_points', {}) # Title #root.wm_title(' FuncDesigner ' + fdversion + ' Manager') C = Canvas(root) """ Buttons """ Frame(RootFrame).pack(ipady=4) #Label(root, text=' FuncDesigner ' + fdversion + ' ').pack() # Upper Frame UpperFrame = Frame(RootFrame) UpperFrame.pack(side = 'top', expand=True, fill = 'x') ProjectNameFrame = Frame(UpperFrame)#, relief = 'ridge', bd=2) Label(ProjectNameFrame, text = 'Project name:').pack(side = 'left') ProjectNameEntry = Entry(ProjectNameFrame) ProjectNameEntry.pack(side = 'left') self.ProjectNameEntry = ProjectNameEntry ProjectNameFrame.pack(side = 'left') GoalSelectFrame = Frame(UpperFrame, relief = 'ridge', bd=2) GoalSelectText = StringVar(value = 'Goal:') Label(GoalSelectFrame, textvariable = GoalSelectText).pack(side = 'left') goal = StringVar() r1 = Radiobutton(GoalSelectFrame, text = 'Minimum', value = 'min', variable=goal) r1.pack(side = 'left') r2 = Radiobutton(GoalSelectFrame, text = 'Maximum', value = 'max', variable=goal) r2.pack(side = 'left') goal.set('min') GoalSelectFrame.pack(side = 'left', padx = 10) self.goal = goal ObjectiveToleranceFrame = Frame(UpperFrame, relief = 'ridge', bd=2) ObjectiveToleranceFrame.pack(side='left') Label(ObjectiveToleranceFrame, text='Objective function tolerance:').pack(side = 'left') ObTolEntry = Entry(ObjectiveToleranceFrame) ObTolEntry.pack(side='left') self.ObTolEntry = ObTolEntry # Variables Frame varsRoot = Frame(RootFrame) # Lower frame LowerFrame = Frame(varsRoot) LowerFrame.pack(side = 'bottom', expand=True, fill = 'x') from webbrowser import open_new_tab About = Button(LowerFrame, text = 'About', command = lambda: open_new_tab('http://openopt.org/MultiFactorAnalysis')) About.pack(side='left') SaveButton = Button(LowerFrame, text = 'Save', command = self.save) SaveButton.pack(side='left', padx = 15) SaveAsButton = Button(LowerFrame, text = 'Save As ...', command = self.save) SaveAsButton.pack(side='left') Write_xls_Button = Button(LowerFrame, text = 'Write xls report', command = self.write_xls_report) Write_xls_Button.pack(side='left', padx = 15) # PlotButton = Button(LowerFrame, text = 'Plot', command = lambda: Plot(C, self.prob)) # PlotButton.pack(side='left') ExperimentNumber = IntVar() ExperimentNumber.set(1) self.ExperimentNumber = ExperimentNumber ObjVal = StringVar() ObjEntry = Entry(LowerFrame, textvariable = ObjVal) self.ObjEntry = ObjEntry NN = StringVar(LowerFrame) NN_Label = Label(LowerFrame, textvariable = NN) names, lbs, ubs, tols, currValues = \ Frame(varsRoot), Frame(varsRoot), Frame(varsRoot), Frame(varsRoot), Frame(varsRoot) Label(names, text=' Variable Name ').pack(side = 'top') Label(lbs, text=' Lower Bound ').pack(side = 'top') Label(ubs, text=' Upper Bound ').pack(side = 'top') Label(tols, text=' Tolerance ').pack(side = 'top') ValsColumnName = StringVar() ValsColumnName.set(' Initial Point ') Label(currValues, textvariable=ValsColumnName).pack(side = 'top') self.ValsColumnName = ValsColumnName # Commands Frame CommandsRoot = Frame(RootFrame) CommandsRoot.pack(side = 'right', expand = False, fill='y') AddVar = Button(CommandsRoot, text = 'Add Variable', command = \ lambda: self.addVar(names, lbs, ubs, tols, currValues)) AddVar.pack(side = 'top', fill='x') Next = Button(CommandsRoot, text = 'Next', command = lambda: ExperimentNumber.set(ExperimentNumber.get()+1)) #Next.pack(side='bottom', fill='x') names.pack(side = 'left', ipady=5) lbs.pack(side = 'left', ipady=5) ubs.pack(side = 'left', ipady=5) tols.pack(side = 'left', ipady=5) currValues.pack(side = 'left', ipady=5) #currValues.pack_forget() varsRoot.pack() Start = Button(CommandsRoot, text = 'Start', \ command = lambda: (Start.destroy(), \ Next.pack(side='bottom', fill='x'), #C.pack(side = 'bottom', expand=True, fill='both'), r1.config(state=DISABLED), r2.config(state=DISABLED), ObTolEntry.config(state=DISABLED), ObjEntry.pack(side='right', ipady=4), NN_Label.pack(side='right'), \ self.startOptimization(root, varsRoot, AddVar, currValues, ValsColumnName, ObjEntry, ExperimentNumber, Next, NN, goal.get(), float(ObTolEntry.get()), C))) Start.pack(side = 'bottom', fill='x') self.Start = Start if len(S) != 0: for i in range(len(S['names'])): tmp = S['values'][i] if self.x0 is None else self.x0.split(' ')[i] self.addVar(names, lbs, ubs, tols, currValues, S['names'][i], S['lbs'][i], S['ubs'][i], S['tols'][i], tmp) else: self.addVar(names, lbs, ubs, tols, currValues) # for i in range(nVars): # self.addVar(names, lbs, ubs, tols, currValues) def addVar(self, names, lbs, ubs, tols, currValues, _name='', _lb='', _ub='', _tol='', _val=''): nameEntry, lb, ub, tol, valEntry = Entry(names), Entry(lbs), Entry(ubs), Entry(tols), Entry(currValues) nameEntry.insert(0, _name) lb.insert(0, _lb) ub.insert(0, _ub) tol.insert(0, _tol) valEntry.insert(0, _val) self.NameEntriesList.append(nameEntry) self.LB_EntriesList.append(lb) self.UB_EntriesList.append(ub) self.TolEntriesList.append(tol) self.ValueEntriesList.append(valEntry) nameEntry.pack(side = 'top') lb.pack(side = 'top') ub.pack(side = 'top') tol.pack(side = 'top') valEntry.pack(side = 'top') def startOptimization(self, root, varsRoot, AddVar, currValues, \ ValsColumnName, ObjEntry, ExperimentNumber, Next, NN, goal, objtol, C): AddVar.destroy() ValsColumnName.set('Experiment parameters') n = len(self.NameEntriesList) Names, Lb, Ub, Tol, x0 = [], [], [], [], [] for i in range(n): N, L, U, T, valEntry = \ self.NameEntriesList[i], self.LB_EntriesList[i], self.UB_EntriesList[i], self.TolEntriesList[i], self.ValueEntriesList[i] N.config(state=DISABLED) L.config(state=DISABLED) U.config(state=DISABLED) T.config(state=DISABLED) #valEntry.config(state=DISABLED) name, lb, ub, tol, val = N.get(), L.get(), U.get(), T.get(), valEntry.get() Names.append(name) x0.append(float(val)) Lb.append(float(lb) if lb != '' else -inf) Ub.append(float(ub) if ub != '' else inf) # TODO: fix zero Tol.append(float(tol) if tol != '' else 0) x0, Tol, Lb, Ub = asfarray(x0), asfarray(Tol), asfarray(Lb), asfarray(Ub) x0 *= xtolScaleFactor / Tol #self.x0 = copy(x0) from openopt import NLP, oosolver p = NLP(objective, x0, lb = Lb * xtolScaleFactor / Tol, ub=Ub * xtolScaleFactor / Tol) self.prob = p #calculated_points = [(copy(x0), copy(float(ObjEntry.get()))) p.args = (Tol, self, ObjEntry, p, root, ExperimentNumber, Next, NN, objtol, C) #p.graphics.rate = -inf #p.f_iter = 2 solver = oosolver('bobyqa', __cannotHandleExceptions__ = True) p.solve(solver, iprint = 1, goal = goal)#, plot=1, xlabel='nf') self.solved = True if p.stopcase >= 0: self.ValsColumnName.set('Best parameters') NN.set('Best obtained objective value:') #Next.config(state=DISABLED) Next.destroy() #reverse = True if goal == 'min' else False calculated_items = self.calculated_points.items() vals = [calculated_items[i][1] for i in range(len(calculated_items))] ind = argsort(vals) j = ind[0] if goal == 'min' else ind[-1] key, val = calculated_items[j] text_coords = key.split(' ') for i in range(len(self.ValueEntriesList)): self.ValueEntriesList[i].delete(0, END) self.ValueEntriesList[i].insert(0, text_coords[i]) ObjEntry.delete(0, END) obj_tol = self.ObTolEntry.get() val = float(val) * 1e4 * objtol ObjEntry.insert(0, str(val)) ObjEntry.config(state=DISABLED) #print('Finished') def Plot(C, p): pass #C.create_polygon() # import os # if os.fork(): # import pylab # pylab.plot(p.iterValues.f) # pylab.show() def load(self, SessionSelectFrame): file = askopenfile(defaultextension='.pck', initialdir = self.hd, filetypes = [('Python pickle files', '.pck')]) if file in (None, ''): return SessionSelectFrame.destroy() import pickle S = pickle.load(file) if type(S['calculated_points']) == dict: # for backward compatibility S['calculated_points'] = S['calculated_points'].items() #S['goal']='max' self.x0 = S.get('x0', None) # this line should be BEFORE self.create(S) self.create(S) self.ObTolEntry.insert(0, S['ObjTol']) self.ProjectNameEntry.insert(0, S.get('ProjectName', '')) self.goal.set(S['goal']) self.ExperimentNumber.set(len(self.calculated_points)) if len(S['calculated_points']) != 0: self.Start.invoke() def save_as(self, filename=None): if filename is None: filename = asksaveasfilename(defaultextension='.pck', initialdir = self.hd, filetypes = [('Python pickle files', '.pck')]) if filename in (None, ''): return if not self.solved and self.ObjEntry.get() != '': s = 'For the sake of more safety and some other circumstances saving with non-empty objective entry is forbidden' print(s) showerror('OpenOpt', s) return self.filename = filename names = [s.get() for s in self.NameEntriesList] lbs = [s.get() for s in self.LB_EntriesList] ubs = [s.get() for s in self.UB_EntriesList] tols = [s.get() for s in self.TolEntriesList] values = [s.get() for s in self.ValueEntriesList] goal = self.goal.get() ObjTol = self.ObTolEntry.get() calculated_points = self.calculated_points ProjectName = self.ProjectNameEntry.get() S = {'names':names, 'lbs':lbs, 'ubs':ubs, 'tols':tols, 'values':values, 'goal':goal, \ 'ObjTol':ObjTol, 'calculated_points':calculated_points, 'ProjectName':ProjectName, 'x0':self.x0} # TODO: handle exceptions file = open(filename, "w") import pickle pickle.dump(S, file) file.close() save = lambda self: self.save_as(self.filename) def write_xls_report(self): try: import xlwt except ImportError: s = '''To create xls reports you should have xlwt installed, see http://www.python-excel.org/ you could use easy_install xlwt (with admin rights) also, in Linux you could use [sudo] aptitude install python-xlwt ''' print(s) showerror('OpenOpt', s) return xls_file = asksaveasfilename(defaultextension='.xls', initialdir = self.hd, filetypes = [('xls files', '.xls')]) if xls_file in (None, ''): return wb = xlwt.Workbook() ws = wb.add_sheet('OpenOpt factor analysis report') ws.write(0, 0, 'Name') ws.write(0, 1, self.ProjectNameEntry.get()) ws.write(1, 0, 'Goal') ws.write(1, 1, self.goal.get()) ws.write(2, 0, 'Objective Tolerance') ws.write(2, 1, self.ObTolEntry.get()) names = [s.get() for s in self.NameEntriesList] lbs = [s.get() for s in self.LB_EntriesList] ubs = [s.get() for s in self.UB_EntriesList] tols = [s.get() for s in self.TolEntriesList] ws.write(4, 0, 'Variable') ws.write(5, 0, 'Lower Bound') ws.write(6, 0, 'Upper Bound') ws.write(7, 0, 'Tolerance') for i in range(len(names)): ws.write(4, i+1, names[i]) ws.write(5, i+1, float(lbs[i])) ws.write(6, i+1, float(ubs[i])) ws.write(7, i+1, float(tols[i])) ws.write(9, 0, 'Exp number') ws.write(9, len(names)+1, 'Objective') # TODO: minor code cleanup for i in range(len(self.calculated_points)): key, val = self.calculated_points[i] ws.write(10+i, 0, i+1) coords = key.split() for j, coordVal in enumerate(coords): ws.write(10+i, j+1, float(coordVal)) ws.write(10+i, len(coords)+1, float(val)) wb.save(xls_file) def exit(self): try: self.root.quit() except: pass try: self.root.destroy() except: pass def objective(x, Tol, mfa, ObjEntry, p, root, ExperimentNumber, Next, NN, objtol, C): #print 'in objective', x Key = '' Values = [] ValueEntriesList = mfa.ValueEntriesList calculated_points = mfa.calculated_points for i in range(x.size): Format = '%0.9f' if Tol[i] == 0 else ('%0.' + ('%d' % (-floor(log10(Tol[i])))) + 'f') if Tol[i]<1 else '%d' tmp = x[i] * Tol[i] / xtolScaleFactor key = Format % tmp Key += key + ' ' Values.append(key) #print calculated_points #print Key if mfa.x0 is None: mfa.x0 = Key if Key in dict(calculated_points): # TODO: rework it return dict(calculated_points)[Key] for i in range(x.size): ValueEntriesList[i].delete(0, END) ValueEntriesList[i].insert(0, Values[i]) NN.set('Enter experiment %i result:' % int(len(calculated_points)+1)) ObjEntry.delete(0, END) root.wait_variable(ExperimentNumber) r = float(ObjEntry.get()) # from scipy import rand # r = abs(x[0]* Tol[0] / xtolScaleFactor-0.13) + abs(x[1]* Tol[1] /xtolScaleFactor-0.15) #+ 0.0001 * rand(1) r *= 1e-4 / objtol calculated_points.append((Key, asscalar(copy(r)))) # rr = [] # for i, val in enumerate(p.iterValues.f): # rr.append(i) # rr.append(val) # rr.append(i+1) # rr.append(r) # if len(p.iterValues.f) > 1: # C.create_line(*rr, fill = 'blue') return r MFA = lambda: mfa().startSession() if __name__ == '__main__': MFA() openopt-0.38+svn1589/openopt/kernel/nonLinFuncs.py000066400000000000000000000500171175775750500220610ustar00rootroot00000000000000from numpy import * from setDefaultIterFuncs import USER_DEMAND_EXIT from ooMisc import killThread, setNonLinFuncsNumber from nonOptMisc import scipyInstalled, Vstack, isspmatrix, isPyPy try: from DerApproximator import get_d1 DerApproximatorIsInstalled = True except: DerApproximatorIsInstalled = False class nonLinFuncs: def __init__(self): pass def wrapped_func(p, x, IND, userFunctionType, ignorePrev, getDerivative): if isinstance(x, dict): if not p.isFDmodel: p.err('calling the function with argument of type dict is allowed for FuncDesigner models only') x = p._point2vector(x) if not getattr(p.userProvided, userFunctionType): return array([]) if p.istop == USER_DEMAND_EXIT: if p.solver.__cannotHandleExceptions__: return nan else: raise killThread if getDerivative and not p.isFDmodel and not DerApproximatorIsInstalled: p.err('For the problem you should have DerApproximator installed, see http://openopt.org/DerApproximator') #userFunctionType should be 'f', 'c', 'h' funcs = getattr(p.user, userFunctionType) funcs_num = getattr(p, 'n'+userFunctionType) if IND is not None: ind = p.getCorrectInd(IND) else: ind = None # this line had been added because some solvers pass tuple instead of # x being vector p.n x 1 or matrix X=[x1 x2 x3...xk], size(X)=[p.n, k] if not isspmatrix(x): x = atleast_1d(x) # if not str(x.dtype).startswith('float'): # x = asfarray(x) else: if p.debug: p.pWarn('[oo debug] sparse matrix x in nonlinfuncs.py has been encountered') # if not ignorePrev: # prevKey = p.prevVal[userFunctionType]['key'] # else: # prevKey = None # # # TODO: move it into runprobsolver or baseproblem # if p.prevVal[userFunctionType]['val'] is None: # p.prevVal[userFunctionType]['val'] = zeros(getattr(p, 'n'+userFunctionType)) # # if prevKey is not None and p.iter > 0 and array_equal(x, prevKey) and ind is None and not ignorePrev: # #TODO: add counter of the situations # if not getDerivative: # r = copy(p.prevVal[userFunctionType]['val']) # #if p.debug: assert array_equal(r, p.wrapped_func(x, IND, userFunctionType, True, getDerivative)) # if ind is not None: r = r[ind] # # if userFunctionType == 'f': # if p.isObjFunValueASingleNumber: r = r.sum(0) # if p.invertObjFunc: r = -r # if p.solver.funcForIterFcnConnection=='f' and any(isnan(x)): # p.nEvals['f'] += 1 # # if p.nEvals['f']%p.f_iter == 0: # p.iterfcn(x, fk = r) # return r args = getattr(p.args, userFunctionType) # TODO: handle it in prob prepare if not hasattr(p, 'n'+userFunctionType): setNonLinFuncsNumber(p, userFunctionType) if ind is None: nFuncsToObtain = getattr(p, 'n'+ userFunctionType) else: nFuncsToObtain = len(ind) if x.shape[0] != p.n and (x.ndim<2 or x.shape[1] != p.n): p.err('x with incorrect shape passed to non-linear function') #TODO: code cleanup (below) if getDerivative or x.ndim <= 1 or x.shape[0] == 1: nXvectors = 1 x_0 = copy(x) else: nXvectors = x.shape[0] # TODO: use certificate instead if p.isFDmodel: if getDerivative: if p.freeVars is None or (p.fixedVars is not None and len(p.freeVars) < len(p.fixedVars)): funcs2 = [(lambda x, i=i: \ p._pointDerivative2array( funcs[i].D(x, Vars = p.freeVars, useSparse=p.useSparse, fixedVarsScheduleID=p._FDVarsID, exactShape=True), useSparse=p.useSparse, func=funcs[i], point=x)) \ for i in range(len(funcs))] else: funcs2 = [(lambda x, i=i: \ p._pointDerivative2array( funcs[i].D(x, fixedVars = p.fixedVars, useSparse=p.useSparse, fixedVarsScheduleID=p._FDVarsID, exactShape=True), useSparse=p.useSparse, func=funcs[i], point=x)) \ for i in range(len(funcs))] else: if p.freeVars is None or (p.fixedVars is not None and len(p.freeVars) < len(p.fixedVars)): funcs2 = [(lambda x, i=i: \ funcs[i]._getFuncCalcEngine(x, Vars = p.freeVars, fixedVarsScheduleID=p._FDVarsID))\ for i in range(len(funcs))] else: funcs2 = [(lambda x, i=i: \ funcs[i]._getFuncCalcEngine(x, fixedVars = p.fixedVars, fixedVarsScheduleID=p._FDVarsID))\ for i in range(len(funcs))] else: funcs2 = funcs if ind is None: Funcs = funcs2 elif ind is not None and p.functype[userFunctionType] == 'some funcs R^nvars -> R': Funcs = [funcs2[i] for i in ind] else: Funcs = getFuncsAndExtractIndexes(p, funcs2, ind, userFunctionType) agregate_counter = 0 if p.isFDmodel: Args = () else: Args = args if nXvectors == 1: X = p._vector2point(x) if p.isFDmodel else x if nXvectors > 1: # and hence getDerivative isn't involved #temporary, to be fixed assert userFunctionType == 'f' and p.isObjFunValueASingleNumber if p.isFDmodel: X = [p._vector2point(x[i]) for i in range(nXvectors)] elif len(Args) == 0: X = [x[i] for i in range(nXvectors)] else: X = [((x[i],) + Args) for i in range(nXvectors)] #r = hstack([map(fun, X) for fun in Funcs]).reshape(1, -1) r = hstack([[fun(xx) for xx in X] for fun in Funcs]).reshape(1, -1) elif not getDerivative: r = hstack([fun(*(X, )+Args) for fun in Funcs]) # if not ignorePrev and ind is None: # p.prevVal[userFunctionType]['key'] = copy(x_0) # p.prevVal[userFunctionType]['val'] = r.copy() elif getDerivative and p.isFDmodel: rr = [fun(X) for fun in Funcs] r = Vstack(rr) if scipyInstalled and any([isspmatrix(elem) for elem in rr]) else vstack(rr) else: r = [] if getDerivative: #r = zeros((nFuncsToObtain, p.n)) diffInt = p.diffInt abs_x = abs(x) finiteDiffNumbers = 1e-10 * abs_x if p.diffInt.size == 1: finiteDiffNumbers[finiteDiffNumbers < diffInt] = diffInt else: finiteDiffNumbers[finiteDiffNumbers < diffInt] = diffInt[finiteDiffNumbers < diffInt] else: #r = zeros((nFuncsToObtain, nXvectors)) r = [] for index, fun in enumerate(Funcs): # OLD # v = ravel(fun(*((X,) + Args))) # if (ind is None or funcs_num == 1) and not ignorePrev: # #TODO: ADD COUNTER OF THE CASE # if index == 0: p.prevVal[userFunctionType]['key'] = copy(x_0) # p.prevVal[userFunctionType]['val'][agregate_counter:agregate_counter+v.size] = v.copy() # r[agregate_counter:agregate_counter+v.size,0] = v #NEW if not getDerivative: r.append(fun(*((X,) + Args))) # v = r[-1] #r[agregate_counter:agregate_counter+v.size,0] = fun(*((X,) + Args)) # if (ind is None or funcs_num == 1) and not ignorePrev: # #TODO: ADD COUNTER OF THE CASE # if index == 0: p.prevVal[userFunctionType]['key'] = copy(x_0) # p.prevVal[userFunctionType]['val'][agregate_counter:agregate_counter+v.size] = v.copy() """ getting derivatives """ if getDerivative: def func(x): r = fun(*((x,) + Args)) return r if type(r) not in (list, tuple) or len(r)!=1 else r[0] d1 = get_d1(func, x, pointVal = None, diffInt = finiteDiffNumbers, stencil=p.JacobianApproximationStencil, exactShape=True) #r[agregate_counter:agregate_counter+d1.size] = d1 r.append(d1) # v = r[-1] # agregate_counter += atleast_1d(v).shape[0] r = hstack(r) if not getDerivative else vstack(r) #if type(r) == matrix: r = r.A if userFunctionType == 'f' and p.isObjFunValueASingleNumber and prod(r.shape) > 1 and (type(r) == ndarray or min(r.shape) > 1): r = r.sum(0) if userFunctionType == 'f' and p.isObjFunValueASingleNumber: if getDerivative and r.ndim > 1: if min(r.shape) > 1: p.err('incorrect shape of objective func derivative') # TODO: omit cast to dense array. Somewhere bug triggers? if hasattr(r, 'toarray'): r=r.toarray() #if not hasattr(r, 'flatten'): #raise 0 r = r.flatten() # if type(r) == matrix: # raise 0 # r = r.A # if _dense_numpy_matrix ! #assert p.iter != 176 or userFunctionType != 'f' or not getDerivative if nXvectors == 1 and (not getDerivative or prod(r.shape) == 1): # DO NOT REPLACE BY r.size - r may be sparse! r = r.flatten() if type(r) == ndarray else r.toarray().flatten() if not isscalar(r) else atleast_1d(r) if p.invertObjFunc and userFunctionType=='f': r = -r if not getDerivative: if ind is None: p.nEvals[userFunctionType] += nXvectors else: p.nEvals[userFunctionType] = p.nEvals[userFunctionType] + float(nXvectors * len(ind)) / getattr(p, 'n'+ userFunctionType) if getDerivative: assert x.size == p.n#TODO: add python list possibility here x = x_0 # for to suppress numerical instability effects while x +/- delta_x if userFunctionType == 'f' and hasattr(p, 'solver') and p.solver.funcForIterFcnConnection=='f' and hasattr(p, 'f_iter') and not getDerivative: if p.nEvals['f']%p.f_iter == 0: p.iterfcn(x, r) return r def wrapped_1st_derivatives(p, x, ind_, funcType, ignorePrev, useSparse): if isinstance(x, dict): if not p.isFDmodel: p.err('calling the function with argument of type dict is allowed for FuncDesigner models only') if ind_ is not None:p.err('the operation is turned off for argument of type dict when ind!=None') x = p._point2vector(x) if ind_ is not None: ind = p.getCorrectInd(ind_) else: ind = None if p.istop == USER_DEMAND_EXIT: if p.solver.__cannotHandleExceptions__: # if p.solver.__name__ == 'algencan': # return None return nan else: raise killThread derivativesType = 'd'+ funcType prevKey = p.prevVal[derivativesType]['key'] if prevKey is not None and p.iter > 0 and array_equal(x, prevKey) and ind is None and not ignorePrev: #TODO: add counter of the situations assert p.prevVal[derivativesType]['val'] is not None return copy(p.prevVal[derivativesType]['val']) if ind is None and not ignorePrev: p.prevVal[derivativesType]['ind'] = copy(x) #TODO: patterns! nFuncs = getattr(p, 'n'+funcType) x = atleast_1d(x) if hasattr(p.userProvided, derivativesType) and getattr(p.userProvided, derivativesType): funcs = getattr(p.user, derivativesType) if ind is None or (nFuncs == 1 and p.functype[funcType] == 'single func'): Funcs = funcs elif ind is not None and p.functype[funcType] == 'some funcs R^nvars -> R': Funcs = [funcs[i] for i in ind] else: Funcs = getFuncsAndExtractIndexes(p, funcs, ind, funcType) if ind is None: derivativesNumber = nFuncs else: derivativesNumber = len(ind) #derivatives = empty((derivativesNumber, p.n)) derivatives = [] #agregate_counter = 0 for fun in Funcs:#getattr(p.user, derivativesType): tmp = atleast_1d(fun(*(x,)+getattr(p.args, funcType))) # TODO: replace tmp.size here for sparse matrices #assert tmp.size % p.n == mod(tmp.size, p.n) if tmp.size % p.n != 0: if funcType=='f': p.err('incorrect user-supplied (sub)gradient size of objective function') elif funcType=='c': p.err('incorrect user-supplied (sub)gradient size of non-lin inequality constraints') elif funcType=='h': p.err('incorrect user-supplied (sub)gradient size of non-lin equality constraints') if tmp.ndim == 1: m= 1 else: m = tmp.shape[0] if p.functype[funcType] == 'some funcs R^nvars -> R' and m != 1: # TODO: more exact check according to stored p.arr_of_indexes_* arrays p.err('incorrect shape of user-supplied derivative, it should be in accordance with user-provided func size') derivatives.append(tmp) #derivatives[agregate_counter : agregate_counter + m] = tmp#.reshape(tmp.size/p.n,p.n) #agregate_counter += m #TODO: inline ind modification!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! derivatives = Vstack(derivatives) if any(isspmatrix(derivatives)) else vstack(derivatives) if ind is None: p.nEvals[derivativesType] += 1 else: #derivatives = derivatives[ind] p.nEvals[derivativesType] = p.nEvals[derivativesType] + float(len(ind)) / nFuncs if funcType=='f': if p.invertObjFunc: derivatives = -derivatives if p.isObjFunValueASingleNumber: if not isinstance(derivatives, ndarray): derivatives = derivatives.toarray() derivatives = derivatives.flatten() else: #if not getattr(p.userProvided, derivativesType) or p.isFDmodel: # x, IND, userFunctionType, ignorePrev, getDerivative derivatives = p.wrapped_func(x, ind, funcType, True, True) if ind is None: p.nEvals[derivativesType] -= 1 else: p.nEvals[derivativesType] = p.nEvals[derivativesType] - float(len(ind)) / nFuncs #else: if useSparse is False or not scipyInstalled or not hasattr(p, 'solver') or not p.solver._canHandleScipySparse: # p can has no attr 'solver' if it is called from checkdf, checkdc, checkdh if not isinstance(derivatives, ndarray): derivatives = derivatives.toarray() # if min(derivatives.shape) == 1: # if isspmatrix(derivatives): derivatives = derivatives.A # derivatives = derivatives.flatten() if type(derivatives) != ndarray and isinstance(derivatives, ndarray): # dense numpy matrix derivatives = derivatives.A if ind is None and not ignorePrev: p.prevVal[derivativesType]['val'] = derivatives if funcType=='f': if hasattr(p, 'solver') and not p.solver.iterfcnConnected and p.solver.funcForIterFcnConnection=='df': if p.df_iter is True: p.iterfcn(x) elif p.nEvals[derivativesType]%p.df_iter == 0: p.iterfcn(x) # call iterfcn each {p.df_iter}-th df call if p.isObjFunValueASingleNumber and type(derivatives) == ndarray and derivatives.ndim > 1: derivatives = derivatives.flatten() return derivatives # the funcs below are not implemented properly yet def user_d2f(p, x): assert x.ndim == 1 p.nEvals['d2f'] += 1 assert(len(p.user.d2f)==1) r = p.user.d2f[0](*(x, )+p.args.f) if p.invertObjFunc:# and userFunctionType=='f': r = -r return r def user_d2c(p, x): return () def user_d2h(p, x): return () def user_l(p, x): return () def user_dl(p, x): return () def user_d2l(p, x): return () def getCorrectInd(p, ind): if ind is None or type(ind) in [list, tuple]: result = ind else: try: result = atleast_1d(ind).tolist() except: raise ValueError('%s is an unknown func index type!'%type(ind)) return result def getFuncsAndExtractIndexes(p, funcs, ind, userFunctionType): if ind is None: return funcs if len(funcs) == 1 : def f (*args, **kwargs): tmp = funcs[0](*args, **kwargs) if isspmatrix(tmp): tmp = tmp.tocsc() elif not isinstance(tmp, ndarray): tmp = atleast_1d(tmp) if isPyPy: return atleast_1d([tmp[i] for i in ind]) else: return tmp[ind] return [f] #getting number of block and shift arr_of_indexes = getattr(p, 'arr_of_indexes_' + userFunctionType) if isPyPy: # temporary walkaround the bug "int32 is unhashable" Left_arr_indexes = searchsorted(arr_of_indexes, ind) left_arr_indexes = [int(elem) for elem in atleast_1d(Left_arr_indexes)] else: left_arr_indexes = searchsorted(arr_of_indexes, ind) indLenght = len(ind) Funcs2 = [] # TODO: try to get rid of cycles, use vectorization instead IndDict = {} for i in range(indLenght): if left_arr_indexes[i] != 0: num_of_funcs_before_arr_left_border = arr_of_indexes[left_arr_indexes[i]-1] inner_ind = ind[i] - num_of_funcs_before_arr_left_border - 1 else: inner_ind = ind[i] if left_arr_indexes[i] in IndDict.keys(): IndDict[left_arr_indexes[i]].append(inner_ind) else: IndDict[left_arr_indexes[i]] = [inner_ind] Funcs2.append([funcs[left_arr_indexes[i]], IndDict[left_arr_indexes[i]]]) Funcs = [] for i in range(len(Funcs2)): def f_aux(x, i=i): r = Funcs2[i][0](x) # TODO: are other formats better? if not isscalar(r): if isPyPy: if isspmatrix(r): r = r.tocsc()[Funcs2[i][1]] else: # Temporary walkaround of PyPy integer indexation absence tmp = atleast_1d(r) r = atleast_1d([tmp[i] for i in Funcs2[i][1]]) else: r = r.tocsc()[Funcs2[i][1]] if isspmatrix(r) else atleast_1d(r)[Funcs2[i][1]] return r Funcs.append(f_aux) #Funcs.append(lambda x, i=i: Funcs2[i][0](x)[Funcs2[i][1]]) return Funcs#, inner_ind openopt-0.38+svn1589/openopt/kernel/nonOptMisc.py000066400000000000000000000142371175775750500217220ustar00rootroot00000000000000import os from oologfcn import OpenOptException from numpy import zeros, hstack, vstack, ndarray, copy, where, prod, asarray, atleast_1d, isscalar, atleast_2d, eye, diag import sys syspath = sys.path Sep = os.sep try: import scipy scipyInstalled = True scipyAbsentMsg = '' from scipy.sparse import isspmatrix, csr_matrix, coo_matrix from scipy.sparse import hstack as HstackSP, vstack as VstackSP, find as Find def Hstack(Tuple): ind = where([isscalar(elem) or prod(elem.shape)!=0 for elem in Tuple])[0].tolist() elems = [Tuple[i] for i in ind] if any([isspmatrix(elem) for elem in elems]): return HstackSP(elems) s = set([(0 if isscalar(elem) else elem.ndim) for elem in elems]) ndim = max(s) if ndim <= 1: return hstack(elems) #assert ndim <= 2 and 1 not in s, 'bug in OpenOpt kernel, inform developers' return hstack(elems) if 0 not in s else hstack([atleast_2d(elem) for elem in elems]) def Vstack(Tuple): ind = where([prod(elem.shape)!=0 for elem in Tuple])[0].tolist() elems = [Tuple[i] for i in ind] if any([isspmatrix(elem) for elem in elems]): return VstackSP(elems) s = set([(0 if isscalar(elem) else elem.ndim) for elem in elems]) ndim = max(s) if ndim <= 1: return vstack(elems) #assert ndim <= 2 and 1 not in s, 'bug in OpenOpt kernel, inform developers' return vstack(elems) if 0 not in s else vstack([atleast_2d(elem) for elem in elems]) #Hstack = lambda Tuple: HstackSP(Tuple) if any([isspmatrix(elem) for elem in Tuple]) else hstack(Tuple) #Vstack = lambda Tuple: VstackSP(Tuple) if any([isspmatrix(elem) for elem in Tuple]) else vstack(Tuple) SparseMatrixConstructor = lambda *args, **kwargs: scipy.sparse.lil_matrix(*args, **kwargs) except: scipyInstalled = False csr_matrix = None coo_matrix = None scipyAbsentMsg = 'Probably scipy installation could speed up running the code involved' isspmatrix = lambda *args, **kwargs: False Hstack = hstack Vstack = vstack def SparseMatrixConstructor(*args, **kwargs): raise OpenOptException('error in OpenOpt kernel, inform developers') def Find(*args, **kwargs): raise OpenOptException('error in OpenOpt kernel, inform developers') try: import numpypy isPyPy = True except ImportError: isPyPy = False DenseMatrixConstructor = lambda *args, **kwargs: zeros(*args, **kwargs) def Eye(n): if not scipyInstalled and n>150: pWarn(scipyAbsentMsg) if n == 1: return 1.0 elif n <= 16 or not scipyInstalled: return eye(n) else: return scipy.sparse.identity(n) def Diag(x): if not scipyInstalled and len(x)>150: pWarn(scipyAbsentMsg) if isscalar(x): return x elif len(x) == 1: return asfarray(x) elif len(x) < 16 or not scipyInstalled: return diag(x) else: return scipy.sparse.spdiags(x, [0], len(x), len(x)) ################################################################## solverPaths = {} from os import path as os_path FILE = os_path.realpath(__file__) for root, dirs, files in os.walk(''.join([elem + os.sep for elem in FILE.split(os.sep)[:-2]+ ['solvers']])): rd = root.split(os.sep) if '.svn' in rd or '__pycache__' in rd: continue rd = rd[rd.index('solvers')+1:] for file in files: if file.endswith('_oo.py'): solverPaths[file[:-6]] = ''.join(rd+['.',file[:-3]]) def getSolverFromStringName(p, solver_str): if solver_str not in solverPaths: p.err(''' incorrect solver is called, maybe the solver "%s" is misspelled or requires special installation and is not installed, check http://openopt.org/%s''' % (solver_str, p.probType)) if p.debug: solverClass = solver_import(solverPaths[solver_str], solver_str) else: try: solverClass = solver_import(solverPaths[solver_str], solver_str) except ImportError: p.err('incorrect solver is called, maybe the solver "' + solver_str +'" require its installation, check http://www.openopt.org/%s or try p._solve() for more details' % p.probType) r = solverClass() if not hasattr(r, 'fieldsForProbInstance'): r.fieldsForProbInstance = {} return r ################################################################## importedSet = set() ooPath = ''.join(elem+Sep for elem in __file__.split(Sep)[:-3]) def solver_import(solverPath, solverName): if solverPath not in importedSet: importedSet.add(solverPath) syspath.append(ooPath+'openopt'+Sep + 'solvers'+''.join(Sep+elem for elem in solverPath.split('.')[:-1])) name = 'openopt.solvers.' + solverPath mod = __import__(name) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return getattr(mod, solverName) def oosolver(solverName, *args, **kwargs): if args != (): raise OpenOptException("Error: oosolver() doesn't consume any *args, use **kwargs only") try: if ':' in solverName: # TODO: make it more properly # currently it's used for to get filed isInstalled value # from ooSystem solverName = solverName.split(':')[1] solverClass = solver_import(solverPaths[solverName], solverName) solverClassInstance = solverClass() solverClassInstance.fieldsForProbInstance = {} for key, value in kwargs.iteritems(): if hasattr(solverClassInstance, key): setattr(solverClassInstance, key, value) else: solverClassInstance.fieldsForProbInstance[key] = value solverClassInstance.isInstalled = True except ImportError: from baseSolver import baseSolver solverClassInstance = baseSolver() solverClassInstance.__name__ = solverName solverClassInstance.fieldsForProbInstance = {} solverClassInstance.isInstalled = False #assert hasattr(solverClassInstance, 'fieldsForProbInstance') return solverClassInstance def Copy(arg): return arg.copy() if isinstance(arg, ndarray) or isspmatrix(arg) else copy(arg) class EmptyClass: pass openopt-0.38+svn1589/openopt/kernel/ooIter.py000066400000000000000000000115151175775750500210660ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from time import time, clock from numpy import isscalar, array_equal from ooMisc import isSolved from setDefaultIterFuncs import USER_DEMAND_STOP, BUTTON_ENOUGH_HAS_BEEN_PRESSED, IS_NAN_IN_X, SMALL_DELTA_X, IS_MAX_ITER_REACHED, IS_MAX_CPU_TIME_REACHED, IS_MAX_TIME_REACHED, IS_MAX_FUN_EVALS_REACHED has_Tkinter = True try: import Tkinter except: has_Tkinter = False NoneType = type(None) def ooIter(p, *args, **kwargs): """ this func is called from iter to iter it is default iter function of OpenOpt kernel lots of solvers use this one it provides basic graphics output (provided plot option is turned on), maybe in future some text output will also be generated here. also, some stop criteria are handled via the func. """ if p.finalIterFcnFinished: return if has_Tkinter: if p.state == 'paused': p.GUI_root.wait_variable(p.statusTextVariable) if not hasattr(p, 'timeStart'): return#called from check 1st derivatives p.currtime = time() if not p.iter: p.lastDrawTime = p.currtime p.lastDrawIter = 0 if not p.isFinished or len(p.iterValues.f) == 0: p.solver.__decodeIterFcnArgs__(p, *args, **kwargs) condEqualLastPoints = hasattr(p, 'xk_prev') and array_equal(p.xk, p.xk_prev) p.xk_prev = p.xk.copy() if p.graphics.xlabel == 'nf': p.iterValues.nf.append(p.nEvals['f']) p.iterCPUTime.append(clock() - p.cpuTimeStart) p.iterTime.append(p.currtime - p.timeStart) # TODO: rework it if p.probType not in ('GLP', 'MILP') and not p.solver.__name__.startswith('interalg') \ and ((p.iter == 1 and array_equal(p.xk, p.x0)) or condEqualLastPoints): elems = [getattr(p.iterValues, fn) for fn in dir(p.iterValues)] + [p.iterTime, p.iterCPUTime]#dir(p.iterValues) for elem in elems: if type(elem) == list: elem.pop(-1) #TODO: handle case x0 = x1 = x2 = ... if not (p.isFinished and condEqualLastPoints): return #TODO: turn off xtol and ftol for artifically iterfcn funcs if not p.userStop and (not condEqualLastPoints or p.probType == 'GLP'): for key, fun in p.kernelIterFuncs.items(): r = fun(p) if r is not False: p.stopdict[key] = True if p.istop == 0 or key not in [IS_MAX_ITER_REACHED, IS_MAX_CPU_TIME_REACHED, IS_MAX_TIME_REACHED, IS_MAX_FUN_EVALS_REACHED]: p.istop = key if type(r) == tuple: p.msg = r[1] else: p.msg = 'unkown, if you see the message inform openopt developers' if IS_NAN_IN_X in p.stopdict.keys():pass elif SMALL_DELTA_X in p.stopdict.keys() and array_equal(p.iterValues.x[-1], p.iterValues.x[-2]): pass else: p.nonStopMsg = '' for fun in p.denyingStopFuncs.keys(): if not fun(p): p.istop = 0 p.stopdict = {} p.msg = '' p.nonStopMsg = p.denyingStopFuncs[fun] break for fun in p.callback: r = fun(p) if r is None: p.err('user-defined callback function returned None, that is forbidden, see /doc/userCallback.py for allowed return values') if r not in [0, False]: if r in [True, 1]: p.istop = USER_DEMAND_STOP elif isscalar(r): p.istop = r p.msg = 'user-defined' else: p.istop = r[0] p.msg = r[1] p.stopdict[p.istop] = True p.userStop = True if not p.solver.properTextOutput: p.iterPrint() T, cpuT = 0., 0. if p.plot and (p.iter == 0 or p.iter <2 or p.isFinished or \ p.currtime - p.lastDrawTime > p.graphics.rate * (p.currtime - p.iterTime[p.lastDrawIter] - p.timeStart)): for df in p.graphics.drawFuncs: df(p) T = time() - p.timeStart - p.iterTime[-1] cpuT = clock() - p.cpuTimeStart - p.iterCPUTime[-1] p.lastDrawTime = time() p.lastDrawIter = p.iter if p.plot: p.timeElapsedForPlotting.append(T+p.timeElapsedForPlotting[-1]) p.cpuTimeElapsedForPlotting.append(cpuT+p.cpuTimeElapsedForPlotting[-1]) p.iter += 1 if p.isFinished: p.finalIterFcnFinished = True if p.istop and not p.solver.iterfcnConnected and not p.isFinished and not p.solver.__cannotHandleExceptions__: p.debugmsg('exit solver via exception; istop=%d' % p.istop) raise isSolved openopt-0.38+svn1589/openopt/kernel/ooMisc.py000066400000000000000000000225101175775750500210530ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import zeros, ones, copy, isfinite, where, asarray, inf, \ array, asfarray, dot, ndarray, prod, flatnonzero, max, abs, sqrt, sum, atleast_1d from nonOptMisc import scipyAbsentMsg, scipyInstalled, isspmatrix, Hstack, Vstack, SparseMatrixConstructor, coo_matrix, isPyPy Copy = lambda arg: asscalar(arg) if type(arg)==ndarray and arg.size == 1 else arg.copy() if hasattr(arg, 'copy') else copy(arg) try: from numpy import linalg norm = linalg.norm except ImportError: def norm(x, k=2, *args, **kw): if len(args) or len(kw): raise ImportError('openopt overload for PyPy numpy linalg.norm cannot handle additional args or kwargs') if k == 2: return sqrt(sum(asarray(x)**2)) elif k == inf: return max(abs(x)) elif k == 1: return sum(abs(x)) else: raise ImportError('unimplemented') def Len(arg): # for PyPy: if type(arg) == ndarray: if arg.size > 1: return arg.size elif arg.size == 1 and atleast_1d(arg)[0] is not None: return 1 elif arg.size == 0: return 0 if type(arg) in [int, float]: return 1 elif arg == None or arg == [] or (isinstance(arg, ndarray) and arg.size==1 and arg == array(None, dtype=object)): return 0 else: return len(arg) def xBounds2Matrix(p): """ transforms lb - ub bounds into (A, x) <= b, (Aeq, x) = beq conditions this func is developed for those solvers that can handle lb, ub only via c(x)<=0, h(x)=0 """ #TODO: is reshape/flatten required in newest numpy versions? # for PyPy IndLB, IndUB, IndEQ = \ isfinite(p.lb) & ~(p.lb == p.ub), \ isfinite(p.ub) & ~(p.lb == p.ub), \ p.lb == p.ub indLB, indUB, indEQ = \ where(IndLB)[0], \ where(IndUB)[0], \ where(IndEQ)[0] initLenB = Len(p.b) initLenBeq = Len(p.beq) nLB, nUB, nEQ = Len(indLB), Len(indUB), Len(indEQ) if nLB>0 or nUB>0: if p.useSparse is True or (isspmatrix(p.A) or (scipyInstalled and nLB+nUB>=p.A.shape[0]) and p.useSparse is not False): R1 = coo_matrix((-ones(nLB), (range(nLB), indLB)), shape=(nLB, p.n)) if nLB != 0 else zeros((0, p.n)) R2 = coo_matrix((ones(nUB), (range(nUB), indUB)), shape=(nUB, p.n)) if nUB != 0 else zeros((0, p.n)) else: R1 = zeros((nLB, p.n)) if isPyPy: for i in range(nLB): R1[i, indLB[i]] = -1 else: R1[range(nLB), indLB] = -1 R2 = zeros((nUB, p.n)) if isPyPy: for i in range(nUB): R2[i, indUB[i]] = -1 else: R2[range(nUB), indUB] = 1 p.A = Vstack((p.A, R1, R2)) if hasattr(p, '_A'): delattr(p, '_A') if isspmatrix(p.A): if prod(p.A.shape)>10000: p.A = p.A.tocsc() p._A = p.A else: p.A = p.A.A p.b = Hstack((p.b, -p.lb[IndLB], p.ub[IndUB])) if nEQ>0: if p.useSparse is True or (isspmatrix(p.Aeq) or (scipyInstalled and nEQ>=p.Aeq.shape[0]) and p.useSparse is not False): R = coo_matrix(([1]*nEQ, (range(nEQ), indEQ)), shape=(nEQ, p.n)) else: R = zeros((nEQ, p.n)) #raise 0 p.Aeq = Vstack((p.Aeq, R)) if hasattr(p, '_Aeq'): delattr(p, '_Aeq') if isspmatrix(p.Aeq): if prod(p.Aeq.shape)>10000: p.Aeq = p.Aeq.tocsc() p._Aeq = p.Aeq else: p.Aeq = p.Aeq.A p.beq = Hstack((p.beq, p.lb[IndEQ])) p.lb = -inf*ones(p.n) p.ub = inf*ones(p.n) # TODO: prevent code clone with baseProblem.py nA, nAeq = prod(p.A.shape), prod(p.Aeq.shape) SizeThreshold = 2 ** 15 if scipyInstalled and p.useSparse is not False: from scipy.sparse import csc_matrix if nA > SizeThreshold and not isspmatrix(p.A) and flatnonzero(p.A).size < 0.25*nA: p._A = csc_matrix(p.A) if nAeq > SizeThreshold and not isspmatrix(p.Aeq) and flatnonzero(p.Aeq).size < 0.25*nAeq: p._Aeq = csc_matrix(p.Aeq) if (nA > SizeThreshold or nAeq > SizeThreshold) and not scipyInstalled and p.useSparse is not False: p.pWarn(scipyAbsentMsg) def LinConst2WholeRepr(p): """ transforms (A, x) <= b, (Aeq, x) = beq into Awhole, bwhole, dwhole constraints (see help(LP)) this func is developed for those solvers that can handle linear (in)equality constraints only via Awhole """ if p.A == None and p.Aeq == None: return # new p.Awhole = Vstack([elem for elem in [p.Awhole, p.A, p.Aeq] if elem is not None]) #old # Awhole = Copy(p.Awhole) # maybe it's already present and not equal to None # p.Awhole = zeros([Len(p.b) + Len(p.beq) + Len(p.bwhole), p.n]) # if Awhole.size>0: p.Awhole[:Len(p.bwhole)] = Awhole # p.Awhole[Len(p.bwhole):Len(p.bwhole)+Len(p.b)] = p.A # if p.Aeq.size: p.Awhole[Len(p.bwhole)+Len(p.b):] = p.Aeq p.A, p.Aeq = None, None bwhole = Copy(p.bwhole) p.bwhole = zeros(Len(p.b) + Len(p.beq) + Len(p.bwhole)) p.bwhole[:Len(bwhole)] = bwhole p.bwhole[Len(bwhole):Len(bwhole)+Len(p.b)] = p.b p.bwhole[Len(bwhole)+Len(p.b):] = p.beq dwhole = Copy(p.dwhole) p.dwhole = zeros(Len(p.bwhole)) if dwhole.size: p.dwhole[:Len(bwhole)] = dwhole p.dwhole[Len(bwhole):Len(bwhole)+Len(p.b)] = -1 p.dwhole[Len(bwhole)+Len(p.b):] = 0 p.b = None p.beq = None def WholeRepr2LinConst(p): """ transforms Awhole, bwhole, dwhole into (A, x) <= b, (Aeq, x) = beq constraints (see help(LP)) this func is developed for those solvers that can handle linear (in)equality constraints only via Awhole """ if p.dwhole == None: return #TODO: is flatten required in newest numpy versions? ind_less = where(p.dwhole == -1)[0] ind_greater = where(p.dwhole == 1)[0] ind_equal = where(p.dwhole == 0)[0] if len(ind_equal) != 0: Aeq, beq = Copy(p.Aeq) , Copy(p.beq) p.Aeq = zeros([Len(p.beq)+len(ind_equal), p.n]) if Aeq.size: p.Aeq[:Len(p.beq)] = Aeq if len(ind_equal): p.Aeq[Len(p.beq):] = p.Awhole[ind_equal] p.beq = zeros([Len(p.beq)+len(ind_equal)]) if beq.size: p.beq[:Len(beq)] = beq if len(ind_equal): p.beq[Len(beq):] = p.bwhole[ind_equal] if len(ind_less) + len(ind_greater)>0: A, b = Copy(p.A) , Copy(p.b) p.A = zeros([Len(p.b)+len(ind_less)+len(ind_greater), p.n]) if A.size: p.A[:Len(p.b)] = A p.A[Len(p.b):Len(p.b)+len(ind_less)] = p.Awhole[ind_less] p.A[Len(p.b)+len(ind_less):] = -p.Awhole[ind_greater] p.b = zeros(Len(p.b)+len(ind_less)+len(ind_greater)) if b.size: p.b[:Len(b)] = b if len(ind_less): p.b[Len(b):Len(b)+len(ind_less)] = p.bwhole[ind_less] if len(ind_greater): p.b[Len(b)+len(ind_less):] = -p.bwhole[ind_greater] p.Awhole = None p.bwhole = None p.dwhole = None def assignScript(p, dictOfParams): for key, val in dictOfParams.items(): if key == 'manage': #p._useGUIManager = val continue setattr(p, key, val) def setNonLinFuncsNumber(p, userFunctionType): # userFunctionType should be 'f', 'c' or 'h' args = getattr(p.args, userFunctionType) fv = getattr(p.user, userFunctionType) if p.isFDmodel: X = p._x0 kwargs = {'Vars': p.freeVars, 'fixedVarsScheduleID':p._FDVarsID, 'fixedVars': p.fixedVars} else: X = p.x0 kwargs = {} if len(fv) == 1: p.functype[userFunctionType] = 'single func' if fv is None or (type(fv) in [list, tuple] and (len(fv)==0 or fv[0] is None)): setattr(p, 'n'+userFunctionType, 0) elif type(fv) in [list, tuple] and len(fv)>1: # TODO: handle problems w/o x0, like GLP number = 0 arr = [] for func in fv: number += asarray(func(*(X,) + args)).size arr.append(number) if len(arr) < number: p.functype[userFunctionType] = 'block' elif len(arr) > 1: p.functype[userFunctionType] = 'some funcs R^nvars -> R' else: assert p.functype[userFunctionType] == 'single func' setattr(p, 'n' + userFunctionType, number) if p.functype[userFunctionType] == 'block': setattr(p, 'arr_of_indexes_' + userFunctionType, array(arr)-1) else: if type(fv) in [list, tuple]: FV = fv[0] else: FV = fv setattr(p, 'n'+userFunctionType, asfarray(FV(*(X, ) + args, **kwargs)).size) def economyMult(M, V): #return dot(M, V) assert V.ndim <= 1 or V.shape[1] == 1 if True or all(V) or isPyPy: # all v coords are non-zeros return dot(M, V) else: ind = where(V != 0)[0] #ind = V != 0 r = dot(M[:,ind], V[ind]) return r def Find(M): if isinstance(M, np.ndarray): # numpy array or matrix rows, cols = np.where(M) vals = M[rows,cols] else: from scipy import sparse as sp assert sp.isspmatrix(M) rows, cols, vals = sp.find(M) return rows.tolist(), cols.tolist(), vals.tolist() class isSolved(BaseException): def __init__(self): pass class killThread(BaseException): def __init__(self): pass openopt-0.38+svn1589/openopt/kernel/ooRun.py000066400000000000000000000003141175775750500207220ustar00rootroot00000000000000from runProbSolver import runProbSolver def ooRun(prob, solvers, *args, **kwargs): r = [] for solver in solvers: r.append(runProbSolver(prob.copy(), solver, *args, **kwargs)) return r openopt-0.38+svn1589/openopt/kernel/oographics.py000066400000000000000000000360351175775750500217670ustar00rootroot00000000000000from numpy import hstack, ravel, isnan, asfarray, log10, array, isfinite, array, asarray from openopt import __version__ as ooversion ooversion = str(ooversion) from setDefaultIterFuncs import stopcase class Graphics: def __init__(self): self.drawFuncs = [self.oodraw] self.specifierStart = 'd' self.specifierFailed = 'x' self.specifierOK = 'p' self.specifierUndefined = 'o' self.specifierContinueFeasible = 'v' self.specifierContinueInfeasible = '>' self.specifierError = 's' self.REDUCE = 1e8 self.axLineStyle= '-' self.axLineWidth= 2 self.axMarker = '' self.axMarkerSize = 1 self.markerEdgeWidth = 1 self.axMarkerEdgeColor = 'b' self.axFaceColor = 'y' # figure updating rate, (time elapsed for graphics) / (time passed) self.rate = 0.5 self.drawingInOneWindow = True#some solvers for the same problem #what do you want on label x? #self.xlabel = 'time'#case-unsensitive #other values: CPUTime, iter #ignores time, spent on figure updatings #iter not recomended because iterations of different solvers take #different time #cputime is unrecomended on computers with several CPU #because some solvers can handle different number of CPU units #so time is best provided no other programs consume much cputime self.markerSize = 12 self.iterMarkerSize = 1 self.plotIterMarkers = True #self.plotOnlyCurrentMinimum = 0 def oodraw(self, p): #note that self is same as p.graphics try: import pylab except: p.pWarn('to use OpenOpt graphics you need pylab (Python module) installed. Turning graphics off...') p.plot = 0 return #isNewFigure = (not isempty(lastTask) and not isequal(lastTask, {p.name p.primal.fName})) ... #or (~self.drawingInOneWindow and globstat.iter ==1)... #or ~isfield(self, 'figureHandler')... #or (isequal(p.env, 'matlab') and ~ishandle(self.figureHandler)) #todo: fix me later! needNewFigure = not p.iter #lastTask={p.name p.primal.fName} % x0 can be absent colors = ['b', 'k', 'c', 'r', 'g'] specifiers = ['-', ':', '-.', '--'] pylab.ion() if needNewFigure: #self.figureHandler = pylab.figure self.colorCount = -1 self.specifierCount = 0 self.nTrajectories = 0 self.ghandlers = [] #self.solverNames = [] #TODO: the condition should be handled somewhere other place, not here. if p.probType in ('NLSP', 'SNLE'): Y_LABELS = ['maxResidual'] #pylab.plot([0], [log10(p.contol)-1.5]) elif p.probType == 'NLLSP': Y_LABELS = ['sum(residuals^2)'] else: Y_LABELS = ['objective function'] isIterPointAlwaysFeasible = p.solver.__isIterPointAlwaysFeasible__ if type(p.solver.__isIterPointAlwaysFeasible__) == bool \ else p.solver.__isIterPointAlwaysFeasible__(p) if not (p._isUnconstrained() or isIterPointAlwaysFeasible): self.isMaxConstraintSubplotRequired = True if p.useScaledResidualOutput: Y_LABELS.append('MaxConstraint/ConTol') else: Y_LABELS.append('maxConstraint') else: self.isMaxConstraintSubplotRequired = False if self.isMaxConstraintSubplotRequired: self.nSubPlots = 2 else: self.nSubPlots = 1 #creating new trajectory, if needed isNewTrajectory = not p.iter # FIXME if isNewTrajectory: self.colorCount += 1 if self.drawingInOneWindow: if self.colorCount > len(colors) - 1 : self.colorCount = 0 self.specifierCount += 1 if self.specifierCount > len(specifiers) - 1 : p.warn('line types number exeeded') self.specifierCount = 0 #setting color & specifier #color = colors[self.colorCount] #specifier = specifiers[self.specifierCount] color = p.color specifier = p.specifier #setting xlabel, ylabel, title etc tx = p.xlabel.lower() if isNewTrajectory: self.nTrajectories += 1 #win = gtk.Window() #win.set_name("OpenOpt " + str(oover) + ", license: BSD 2.0") pTitle = 'problem: ' + p.name if p.showGoal: pTitle += ' goal: ' + p.goal if self.nSubPlots>1: pylab.subplot(self.nSubPlots, 1, 1) p.figure = pylab.gcf() pylab.title(pTitle) p.figure.canvas.set_window_title('OpenOpt ' + ooversion) if tx == 'cputime': xlabel = 'CPU Time elapsed (without graphic output), sec' d_x = 0.01 elif tx == 'time': xlabel = 'Time elapsed (without graphic output), sec' d_x = 0.01 elif tx in ['niter', 'iter']: xlabel = 'iter' d_x = 4 elif tx == 'nf': xlabel = 'Number of objective function evaluations' d_x = 4 else: p.err('unknown graphic output xlabel: "' + tx + '", should be in "time", "cputime", "iter", "nf"') self.nPointsPlotted = 0 for ind in range(self.nSubPlots): if (self.nSubPlots > 1 and ind != 0) or p.probType in ('NLSP', 'SNLE'): ax = pylab.subplot(self.nSubPlots, 1, ind+1) ax.set_yscale('log') # if self.nSubPlots > 1: # ax = pylab.subplot(self.nSubPlots, 1, ind+1) # if p.probType in ('NLSP', 'SNLE') or ind != 0: # ax.set_yscale('log') pylab.hold(1) pylab.grid(1) pylab.ylabel(Y_LABELS[ind]) pylab.xlabel(xlabel) ################ getting data to plot ############### if p.iter>0: IND_start, IND_end = self.nPointsPlotted-1, p.iter+1#note: indexing from zero assumed #if p.isFinished: IND_end = p.iter else: IND_start, IND_end = 0, 1 if p.plotOnlyCurrentMinimum: yy = array(p.iterValues.f[IND_start:]) if isNewTrajectory: self.currMin = yy[0] k = 0 for j in range(IND_start, IND_start + len(yy)): #todo: min is slow in 1x1 comparison vs if-then-else yy[k] = min(self.currMin, p.iterValues.f[j]) self.currMin = yy[k] k += 1 if IND_start<=IND_end: if len(p.iterValues.f) >= 1: yySave = [p.iterValues.f[-1]] # FIXME! (for constraints) else: yySave = [p.f(p.x0)] else: yy = array(p.iterValues.f[IND_start:IND_end]) if IND_start<=IND_end: if len(p.iterValues.f) >= 1: yySave = [p.iterValues.f[-1]] else: yySave = [p.f(p.x0)] if tx == 'iter': xx = range(IND_start, IND_end) elif tx == 'cputime': if len(p.iterTime) != len(p.cpuTimeElapsedForPlotting): p.iterTime.append(p.iterTime[-1]) xx = asfarray(p.iterCPUTime[IND_start:IND_end]) - asfarray(p.cpuTimeElapsedForPlotting[IND_start:IND_end]) elif tx == 'time': if len(p.iterTime) != len(p.timeElapsedForPlotting): p.iterTime.append(p.iterTime[-1]) xx = asfarray(p.iterTime[IND_start:IND_end]) - asfarray(p.timeElapsedForPlotting[IND_start:IND_end]) elif tx == 'nf': xx = asfarray(p.iterValues.nf[IND_start:IND_end]) else: p.err('unknown labelX case') if len(xx)>len(yy): if p.isFinished: xx = xx[:-1] else: p.err('OpenOpt graphics ERROR - FIXME!') if p.probType in ('NLSP', 'SNLE'): yy = yy+p.ftol/self.REDUCE YY = [yy] #if len(YY) == 0: YY = yySave if self.isMaxConstraintSubplotRequired: yy22 = p.contol/self.REDUCE+asfarray(p.iterValues.r[IND_start:IND_end]) if p.useScaledResidualOutput: yy22 /= p.contol YY.append(yy22) if IND_start<=IND_end: if len(p.iterValues.r) == 0: return rr = p.iterValues.r[-1] if p.useScaledResidualOutput: rr /= p.contol if len(p.iterValues.r) >= 1: yySave.append(p.contol/self.REDUCE+asfarray(rr)) else: yySave.append(p.contol/self.REDUCE+asfarray(p.getMaxResidual(p.x0))) if needNewFigure: if self.nSubPlots > 1: pylab.subplot(2, 1, 2) tmp = 1 if p.useScaledResidualOutput else p.contol pylab.plot([xx[0]],[tmp / 10**1.5]) pylab.plot([xx[0]+d_x],[tmp / 10**1.5]) pylab.plot([xx[0]], [YY[1][0] * 10]) pylab.plot([xx[0]+d_x], [YY[1][0] * 10]) pylab.subplot(2, 1, 1) pylab.plot([xx[0]],[YY[0][0]]) pylab.plot([xx[0]+d_x],[YY[0][0]]) ########################################## if self.plotIterMarkers: usualMarker = 'o' else: usualMarker = '' for ind in range(self.nSubPlots): if self.nSubPlots > 1: pylab.subplot(self.nSubPlots,1,ind+1) yy2 = ravel(YY[ind]) if len(yy2) < len(xx): if IND_start > IND_end: yy2 = ravel(yySave[ind]) elif yy2.size == 0: yy2 = ravel(yySave[ind]) else: yy2 = hstack((yy2, yy2[-1])) # if len(yy2) 0: s = self.specifierOK else:# p.istop = 0 s = self.specifierUndefined else: s = self.specifierError if s == self.specifierOK: marker = (5, 1, 0) else: marker = s if isnan(yy2[-1]): yy2[-1] = 0 pylab.scatter(ravel(xx[-1]), [yy2[-1]], c=color, marker = marker, s=[150]) #pylab.axis('auto') [xmin, xmax, ymin, ymax] = pylab.axis() if ymax - ymin > 25 * (yy2[-1] -ymin): delta = 0.04 * (ymax - ymin) pylab.scatter([(xmin+xmax)/2, (xmin+xmax)/2], [ymin-delta, ymax+delta], s=1, c='w', edgecolors='none', marker='o') pylab.draw() if ind == 0 and p.probType in ('NLSP', 'SNLE'): pylab.plot([xmin, xmax], [log10(p.ftol), log10(p.ftol)],\ linewidth = self.axLineWidth, ls = self.axLineStyle, color='g',\ marker = self.axMarker, ms = self.axMarkerSize, \ mew = self.markerEdgeWidth, mec = self.axMarkerEdgeColor, mfc = self.axFaceColor) if ind == 1: horz_line_value = 0 if p.useScaledResidualOutput else log10(p.primalConTol) pylab.plot([xmin, xmax], [horz_line_value, horz_line_value],\ linewidth = self.axLineWidth, ls = self.axLineStyle, color='g',\ marker = self.axMarker, ms = self.axMarkerSize, \ mew = self.markerEdgeWidth, mec = self.axMarkerEdgeColor, mfc = self.axFaceColor) pylab.subplot(self.nSubPlots, 1, 1) pylab.plot([xmax], [yy2[-1]], color='w') # if p.probType == 'NLSP': # pylab.axhline(y=log10(p.primalConTol), xmin=xmin, xmax=xmax,\ # linewidth = self.axLineWidth, ls = self.axLineStyle, color='g',\ # marker = self.axMarker, ms = self.axMarkerSize, \ # mew = self.markerEdgeWidth, mec = self.axMarkerEdgeColor, mfc = self.axFaceColor) # if p.isFinished: # for ind in range(self.nSubPlots): # if self.nSubPlots>1: pylab.subplot(self.nSubPlots,1,ind+1) #pylab.xlim(min(xMin), max(xMax)) self.nPointsPlotted = p.iter+1 pylab.draw() openopt-0.38+svn1589/openopt/kernel/oologfcn.py000066400000000000000000000012311175775750500214250ustar00rootroot00000000000000class OpenOptException(BaseException): def __init__(self, msg): self.msg = msg def __str__(self): return self.msg #pass #def ooassert(cond, msg): # assert cond, msg def oowarn(msg): print('OpenOpt Warning: %s' % msg) def ooerr(msg): print('OpenOpt Error: %s' % msg) raise OpenOptException(msg) pwSet = set() def ooPWarn(msg): if msg in pwSet: return pwSet.add(msg) oowarn(msg) def ooinfo(msg): print('OpenOpt info: %s' % msg) def oohint(msg): print('OpenOpt hint: %s' % msg) def oodisp(msg): print(msg) def oodebugmsg(p, msg): if p.debug: print('OpenOpt debug msg: %s' % msg) openopt-0.38+svn1589/openopt/kernel/pointProjection.py000066400000000000000000000006241175775750500230120ustar00rootroot00000000000000from numpy import eye def pointProjection(x, lb, ub, A, b, Aeq, beq): from openopt import QP # projection of x to set of linear constraints n = x.size # TODO: INVOLVE SPARSE CVXOPT MATRICES p = QP(H = eye(n), f = -x, A = A, b=b, Aeq=Aeq, beq=beq, lb=lb, ub=ub) #r = p.solve('cvxopt_qp', iprint = -1) r = p.solve('nlp:scipy_slsqp', contol = 1e-8, iprint = -1) return r.xf openopt-0.38+svn1589/openopt/kernel/residuals.py000066400000000000000000000156151175775750500216250ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import concatenate, asfarray, array, asarray, where, argmax, zeros, isfinite, copy, all, isnan, arange from copy import deepcopy empty_arr = asfarray([]) try: from scipy.sparse import csr_matrix except: pass #def MULT(A, x): # if isinstance(A, ndarray): # return dot(A, x) # else: # t2 = csc_matrix(x) # if t2.shape[0] != A.shape[1]: # if t2.shape[1] == A.shape[1]: # t2 = t2.T # return A._mul_sparse_matrix(t2).toarray() class residuals: def __init__(self): pass def _get_nonLinInEq_residuals(self, x): if hasattr(self.userProvided, 'c') and self.userProvided.c: return self.c(x) else: return empty_arr.copy() def _get_nonLinEq_residuals(self, x): if hasattr(self.userProvided, 'h') and self.userProvided.h: return self.h(x) else: return empty_arr.copy() def _get_AX_Less_B_residuals(self, x): if self.A is not None and self.A.size > 0: return self.matmult(self.A, x).flatten() - self.b if not hasattr(self, '_A') else \ self._A._mul_sparse_matrix(csr_matrix((x, (arange(self.n), zeros(self.n))), shape=(self.n, 1))).toarray().flatten() - self.b #return self.matmult(self.A, x).flatten() - self.b if not hasattr(self, '_A') else self._A._mul_sparse_matrix(csr_matrix(x).reshape((self.n, 1))).toarray().flatten() - self.b else: return empty_arr.copy() def _get_AeqX_eq_Beq_residuals(self, x): if self.Aeq is not None and self.Aeq.size>0 : return self.matmult(self.Aeq, x).flatten() - self.beq if not hasattr(self, '_Aeq') else \ self._Aeq._mul_sparse_matrix(csr_matrix((x, (arange(self.n), zeros(self.n))), shape=(self.n, 1))).toarray().flatten() - self.beq else: return empty_arr.copy() def _getLbresiduals(self, x): return self.lb - x def _getUbresiduals(self, x): return x - self.ub def _getresiduals(self, x): # if 'x' in self.prevVal['r'].keys() and all(x == self.prevVal['r']['x']): # return self.prevVal['r']['Val'] # TODO: add quadratic constraints r = EmptyClass() # TODO: simplify it! if self._baseClassName == 'NonLin': r.c = self._get_nonLinInEq_residuals(x) r.h = self._get_nonLinEq_residuals(x) else: r.c = r.h = 0 r.lin_ineq = self._get_AX_Less_B_residuals(x) r.lin_eq= self._get_AeqX_eq_Beq_residuals(x) r.lb = self._getLbresiduals(x) r.ub = self._getUbresiduals(x) # self.prevVal['r']['Val'] = deepcopy(r) # self.prevVal['r']['x'] = copy(x) return r def getMaxResidual(self, x, retAll = False): """ if retAll: returns 1) maxresidual 2) name of residual type (like 'lb', 'c', 'h', 'Aeq') 3) index of the constraint of given type (for example 15, 'lb', 4 means maxresidual is equal to 15, provided by lb[4]) don't forget about Python indexing from zero! if retAll == False: returns only r """ residuals = self._getresiduals(x) r, fname, ind = 0, None, None for field in ('c', 'lin_ineq', 'lb', 'ub'): fv = asarray(getattr(residuals, field)).flatten() if fv.size>0: ind_max = argmax(fv) val_max = fv[ind_max] if r < val_max: r, ind, fname = val_max, ind_max, field for field in ('h', 'lin_eq'): fv = asarray(getattr(residuals, field)).flatten() if fv.size>0: fv = abs(fv) ind_max = argmax(fv) val_max = fv[ind_max] if r < val_max: r, ind, fname = val_max, ind_max, field # if self.probType == 'NLSP': # fv = abs(self.f(x)) # ind_max = argmax(fv) # val_max = fv[ind_max] # if r < val_max: # r, ind, fname = val_max, ind_max, 'f' if retAll: return r, fname, ind else: return r def _getMaxConstrGradient2(self, x): g = zeros(self.n) mr0 = self.getMaxResidual(x) for j in range(self.n): x[j] += self.diffInt g[j] = self.getMaxResidual(x)-mr0 x[j] -= self.diffInt g /= self.diffInt return g def getMaxConstrGradient(self, x, retAll = False): g = zeros(self.n) maxResidual, resType, ind = self.getMaxResidual(x, retAll=True) if resType == 'lb': g[ind] -= 1 # N * (-1), -1 = dConstr/dx = d(lb-x)/dx elif resType == 'ub': g[ind] += 1 # N * (+1), +1 = dConstr/dx = d(x-ub)/dx elif resType == 'A': g += self.A[ind] elif resType == 'Aeq': rr = self.matmult(self.Aeq[ind], x)-self.beq[ind] if rr < 0: g -= self.Aeq[ind] else: g += self.Aeq[ind] elif resType == 'c': dc = self.dc(x, ind).flatten() g += dc elif resType == 'h': dh = self.dh(x, ind).flatten() if self.h(x, ind) < 0: g -= dh#CHECKME!! else: g += dh#CHECKME!! if retAll: return g, resType, ind else: return g def _getLagrangeresiduals(self, x, lm): #lm is Lagrange multipliers residuals = self.getresiduals(x) r = 0 for field in ['c', 'h', 'A', 'Aeq', 'lb', 'ub']: fv = getattr(residuals, field) if fv not in ([], ()) and fv.size>0: r += p.dotwise(fv, getattr(lm, field)) return r #return r.nonLinInEq * lm.nonLinInEq + r.nonLinEq * lm.nonLinEq + \ #r.aX_Less_b * lm.aX_Less_b + r.aeqX_ineq_beq * lm.aeqX_ineq_beq + \ #r.res_lb * lm.res_lb + r.res_ub * lm.res_ub def isFeas(self, x): if any(isnan(self._get_nonLinEq_residuals(x))) or any(isnan(self._get_nonLinInEq_residuals(x))): return False is_X_finite = all(isfinite(x)) is_ConTol_OK = self.getMaxResidual(x) <= self.contol cond1 = is_ConTol_OK and is_X_finite and all(isfinite(self.objFunc(x))) if self.probType in ('NLSP', 'SNLE'): return cond1 and self.F(x) < self.ftol else: return cond1 def discreteConstraintsAreSatisfied(self, x): k = -1 A = array([0, 1]) for i in self.discreteVars.keys():#range(m): # check x-vector # TODO: replace it by "for i, val in dict.itervalues()" s = self.discreteVars[i] if self.discreteVars[i] is not bool and self.discreteVars[i] is not 'bool' else A if not any(abs(x[i] - s) < self.discrtol): k=i # Violation of this set constraint. break # Go and split for this x-component if k == -1: return True else: return False class EmptyClass: pass openopt-0.38+svn1589/openopt/kernel/runProbSolver.py000066400000000000000000000461401175775750500224510ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from time import time, clock from numpy import asfarray, copy, inf, nan, isfinite, ones, ndim, all, atleast_1d, any, isnan, \ array_equal, asscalar, asarray, where, ndarray, isscalar, matrix, seterr, isinf from setDefaultIterFuncs import stopcase, SMALL_DELTA_X, SMALL_DELTA_F, IS_MAX_ITER_REACHED from check import check from oologfcn import OpenOptException from openopt import __version__ as version import copy import os, string from ooMisc import isSolved, killThread #from baseProblem import ProbDefaults from baseSolver import baseSolver from nonOptMisc import getSolverFromStringName, EmptyClass try: import setproctitle hasSetproctitleModule = True except ImportError: hasSetproctitleModule = False #from openopt.kernel.ooMisc import __solverPaths__ ConTolMultiplier = 0.8 #if __solverPaths__ is None: # __solverPaths__ = {} # file = string.join(__file__.split(os.sep)[:-1], os.sep) # for root, dirs, files in os.walk(os.path.dirname(file)+os.sep+'solvers'): # rd = root.split(os.sep) # if '.svn' in rd: continue # rd = rd[rd.index('solvers')+1:] # for file in files: # print file # if len(file)>6 and file[-6:] == '_oo.py': # __solverPaths__[file[:-6]] = 'openopt.solvers.' + string.join(rd,'.') + '.'+file[:-3] #import pickle #f = open('solverPaths.py', 'w') #solverPaths = pickle.load(f) def runProbSolver(p_, solver_str_or_instance=None, *args, **kwargs): #p = copy.deepcopy(p_, memo=None, _nil=[]) p = p_ if len(args) != 0: p.err('unexpected args for p.solve()') if hasattr(p, 'was_involved'): p.err("""You can't run same prob instance for twice. Please reassign prob struct. You can avoid it via using FuncDesigner oosystem.""") else: p.was_involved = True if solver_str_or_instance is None: if hasattr(p, 'solver'): solver_str_or_instance = p.solver elif 'solver' in kwargs.keys(): solver_str_or_instance = kwargs['solver'] if type(solver_str_or_instance) is str and ':' in solver_str_or_instance: isConverter = True probTypeToConvert, solverName = solver_str_or_instance.split(':', 1) converterName = p.probType.lower()+'2'+probTypeToConvert converter = getattr(p, converterName) p.solver = getSolverFromStringName(p, solverName) solver_params = {} #return converter(solverName, *args, **kwargs) else: isConverter = False if solver_str_or_instance is None: p.err('you should provide name of solver') elif type(solver_str_or_instance) is str: p.solver = getSolverFromStringName(p, solver_str_or_instance) else: # solver_str_or_instance is oosolver p.solver = solver_str_or_instance for key, value in solver_str_or_instance.fieldsForProbInstance.iteritems(): setattr(p, key, value) p.isConverterInvolved = isConverter old_err = seterr(all= 'ignore') if 'debug' in kwargs.keys(): p.debug = kwargs['debug'] probAttributes = set(p.__dict__) solverAttributes = set(p.solver.__dict__) intersection = list(probAttributes.intersection(solverAttributes)) if len(intersection) != 0: if p.debug: p.warn(''' attribute %s is present in both solver and prob (probably you assigned solver parameter in prob constructor), the attribute will be assigned to solver''' % intersection[0]) for elem in intersection: setattr(p.solver, elem, getattr(p, elem)) solver = p.solver.__solver__ for key, value in kwargs.items(): if hasattr(p.solver, key): if isConverter: solver_params[key] = value else: setattr(p.solver, key, value) elif hasattr(p, key): setattr(p, key, value) else: p.warn('incorrect parameter for prob.solve(): "' + str(key) + '" - will be ignored (this one has been not found in neither prob nor ' + p.solver.__name__ + ' solver parameters)') if p.probType == 'EIG' and 'goal' in kwargs: p.err('for EIG parameter "goal" should be used only in class instance definition, not in "solve" method') p.iterValues = EmptyClass() p.iterCPUTime = [] p.iterTime = [] p.iterValues.x = [] # iter points p.iterValues.f = [] # iter ObjFunc Values p.iterValues.r = [] # iter MaxResidual p.iterValues.rt = [] # iter MaxResidual Type: 'c', 'h', 'lb' etc p.iterValues.ri = [] # iter MaxResidual Index p.solutions = [] # list of solutions, may contain several elements for interalg and mb other solvers if p._baseClassName == 'NonLin':p.iterValues.nNaNs = [] # number of constraints equal to numpy.nan if p.goal in ['max','maximum']: p.invertObjFunc = True #TODO: remove it! p.advanced = EmptyClass() p.istop = 0 p.iter = 0 p.graphics.nPointsPlotted = 0 p.finalIterFcnFinished = False #for fn in p.nEvals.keys(): p.nEvals[fn] = 0 # NB! f num is used in LP/QP/MILP/etc stop criteria check p.msg = '' if not type(p.callback) in (list, tuple): p.callback = [p.callback] if hasattr(p, 'xlabel'): p.graphics.xlabel = p.xlabel if p.graphics.xlabel == 'nf': p.iterValues.nf = [] # iter ObjFunc evaluation number p._Prepare() for fn in ['FunEvals', 'Iter', 'Time', 'CPUTime']: if hasattr(p,'min'+fn) and hasattr(p,'max'+fn) and getattr(p,'max'+fn) < getattr(p,'min'+fn): p.warn('min' + fn + ' (' + str(getattr(p,'min'+fn)) +') exceeds ' + 'max' + fn + '(' + str(getattr(p,'max'+fn)) +'), setting latter to former') setattr(p,'max'+fn, getattr(p,'min'+fn)) for fn in ['maxFunEvals', 'maxIter']: setattr(p, fn, int(getattr(p, fn)))# to prevent warnings from numbers like 1e7 if hasattr(p, 'x0'): try: p.x0 = atleast_1d(asfarray(p.x0).copy()) except NotImplementedError: p.x0 = asfarray(p.x0.tolist()) for fn in ['lb', 'ub', 'b', 'beq']: if hasattr(p, fn): fv = getattr(p, fn) if fv is not None:# and fv != []: if str(type(fv)) == "": p.err("Python3 incompatibility with previous versions: you can't use 'map' here, use rendered value instead") setattr(p, fn, asfarray(fv).flatten()) else: setattr(p, fn, asfarray([])) if p.solver._requiresFiniteBoxBounds: ind1, ind2 = isinf(p.lb), isinf(p.ub) if isscalar(p.implicitBounds): p.implicitBounds = (-p.implicitBounds, p.implicitBounds) # may be from lp2nlp converter, thus omit nlp init code p.lb[ind1] = p.implicitBounds[0] if asarray(p.implicitBounds[0]).size == 1 else p.implicitBounds[0][ind1] p.ub[ind2] = p.implicitBounds[1] if asarray(p.implicitBounds[1]).size == 1 else p.implicitBounds[0][ind2] # if p.lb.size == 0: # p.lb = -inf * ones(p.n) # if p.ub.size == 0: # p.ub = inf * ones(p.n) p.stopdict = {} for s in ['b','beq']: if hasattr(p, s): setattr(p, 'n'+s, len(getattr(p, s))) #if p.probType not in ['LP', 'QP', 'MILP', 'LLSP']: p.objFunc(p.x0) p.isUC = p._isUnconstrained() isIterPointAlwaysFeasible = p.solver.__isIterPointAlwaysFeasible__ if type(p.solver.__isIterPointAlwaysFeasible__) == bool \ else p.solver.__isIterPointAlwaysFeasible__(p) if isIterPointAlwaysFeasible: #assert p.data4TextOutput[-1] == 'log10(maxResidual)' if p.data4TextOutput[-1] == 'log10(maxResidual)': p.data4TextOutput = p.data4TextOutput[:-1] # else: # p.err('bug in runProbSolver.py') elif p.useScaledResidualOutput: p.data4TextOutput[-1] = 'log10(MaxResidual/ConTol)' if p.showFeas and p.data4TextOutput[-1] != 'isFeasible': p.data4TextOutput.append('isFeasible') if p.maxSolutions != 1: p._nObtainedSolutions = 0 p.data4TextOutput.append('nSolutions') if not p.solver.iterfcnConnected: if SMALL_DELTA_X in p.kernelIterFuncs: p.kernelIterFuncs.pop(SMALL_DELTA_X) if SMALL_DELTA_F in p.kernelIterFuncs: p.kernelIterFuncs.pop(SMALL_DELTA_F) if not p.solver._canHandleScipySparse: if hasattr(p.A, 'toarray'): p.A = p.A.toarray() if hasattr(p.Aeq, 'toarray'): p.Aeq = p.Aeq.toarray() if isinstance(p.A, ndarray) and type(p.A) != ndarray: # numpy matrix p.A = p.A.A if isinstance(p.Aeq, ndarray) and type(p.Aeq) != ndarray: # numpy matrix p.Aeq = p.Aeq.A if hasattr(p, 'optVars'): p.err('"optVars" is deprecated, use "freeVars" instead ("optVars" is not appropriate for some prob types, e.g. systems of (non)linear equations)') # p.xf = nan * ones([p.n, 1]) # p.ff = nan #todo : add scaling, etc p.primalConTol = p.contol if not p.solver.__name__.startswith('interalg'): p.contol *= ConTolMultiplier p.timeStart = time() p.cpuTimeStart = clock() # TODO: move it into solver parameters if p.probType not in ('MINLP', 'IP'): p.plotOnlyCurrentMinimum = p.__isNoMoreThanBoxBounded__() ############################ # Start solving problem: if p.iprint >= 0: p.disp('\n' + '-'*25 + ' OpenOpt %s ' % version + '-'*25) pt = p.probType if p.probType != 'NLSP' else 'SNLE' s = 'solver: ' + p.solver.__name__ + ' problem: ' + p.name + ' type: %s' % pt if p.showGoal: s += ' goal: ' + p.goal p.disp(s) p.extras = {} try: if isConverter: # TODO: will R be somewhere used? R = converter(solverName, **solver_params) else: nErr = check(p) if nErr: p.err("prob check results: " +str(nErr) + "ERRORS!")#however, I guess this line will be never reached. if p.probType not in ('IP', 'EIG'): p.iterfcn(p.x0) if hasSetproctitleModule: try: originalName = setproctitle.getproctitle() if originalName.startswith('OpenOpt-'): originalName = None else: s = 'OpenOpt-' + p.solver.__name__ # if p.name != 'unnamed': s += '-' + p.name setproctitle.setproctitle(s) except: originalName = None else: p.pWarn(''' please install setproctitle module (it's available via easy_install and Linux soft channels like apt-get)''') solver(p) if hasSetproctitleModule and originalName is not None: setproctitle.setproctitle(originalName) # except killThread: # if p.plot: # print 'exiting pylab' # import pylab # if hasattr(p, 'figure'): # print 'closing figure' # #p.figure.canvas.draw_drawable = lambda: None # pylab.ioff() # pylab.close() # #pylab.draw() # #pylab.close() # print 'pylab exited' # return None except isSolved: # p.fk = p.f(p.xk) # p.xf = p.xk # p.ff = p.objFuncMultiple2Single(p.fk) if p.istop == 0: p.istop = 1000 finally: seterr(**old_err) ############################ p.contol = p.primalConTol # Solving finished if p.probType != 'EIG': if not hasattr(p, 'xf') and not hasattr(p, 'xk'): p.xf = p.xk = ones(p.n)*nan if hasattr(p, 'xf') and (not hasattr(p, 'xk') or array_equal(p.xk, p.x0)): p.xk = p.xf if not hasattr(p, 'xf') or all(isnan(p.xf)): p.xf = p.xk if p.xf is nan: p.xf = p.xk = ones(p.n)*nan if p.isFeas(p.xf) and (not p.probType=='MINLP' or p.discreteConstraintsAreSatisfied(p.xf)): p.isFeasible = True else: p.isFeasible = False else: p.isFeasible = True # check it! p.isFinished = True # After the feasibility check above! if p.probType == 'MOP': p.isFeasible = True elif p.probType == 'IP': p.isFeasible = p.rk < p.ftol else: p.ff = p.fk = p.objFunc(p.xk) # walkaround for PyPy: if type(p.ff) == ndarray and p.ff.size == 1: p.ff = p.fk = asscalar(p.ff) if not hasattr(p, 'ff') or any(p.ff==nan): p.iterfcn, tmp_iterfcn = lambda *args: None, p.iterfcn p.ff = p.fk p.iterfcn = tmp_iterfcn if p.invertObjFunc: p.fk, p.ff = -p.fk, -p.ff if asfarray(p.ff).size > 1: p.ff = p.objFuncMultiple2Single(p.fk) #p.ff = p.objFuncMultiple2Single(p.ff) #if not hasattr(p, 'xf'): p.xf = p.xk if type(p.xf) in (list, tuple) or isscalar(p.xf): p.xf = asarray(p.xf) p.xf = p.xf.flatten() p.rf = p.getMaxResidual(p.xf) if not p.probType == 'IP' else p.rk if not p.isFeasible and p.istop > 0: p.istop = -100-p.istop/1000.0 if p.istop == 0 and p.iter >= p.maxIter: p.istop, p.msg = IS_MAX_ITER_REACHED, 'Max Iter has been reached' p.stopcase = stopcase(p) p.xk, p.rk = p.xf, p.rf if p.invertObjFunc: p.fk = -p.ff p.iterfcn(p.xf, -p.ff, p.rf) else: p.fk = p.ff p.iterfcn(p.xf, p.ff, p.rf) p.__finalize__() if not p.storeIterPoints: delattr(p.iterValues, 'x') r = OpenOptResult(p) #TODO: add scaling handling!!!!!!! # for fn in ('df', 'dc', 'dh', 'd2f', 'd2c', 'd2h'): # if hasattr(p, '_' + fn): setattr(r, fn, getattr(p, '_'+fn)) p.invertObjFunc = False if p.isFDmodel: p.x0 = p._x0 finalTextOutput(p, r) if not hasattr(p, 'isManagerUsed') or p.isManagerUsed == False: finalShow(p) return r ################################################################## def finalTextOutput(p, r): if p.iprint >= 0: if len(p.msg): p.disp("istop: " + str(r.istop) + ' (' + p.msg +')') else: p.disp("istop: " + str(r.istop)) p.disp('Solver: Time Elapsed = ' + str(r.elapsed['solver_time']) + ' \tCPU Time Elapsed = ' + str(r.elapsed['solver_cputime'])) if p.plot: p.disp('Plotting: Time Elapsed = '+ str(r.elapsed['plot_time'])+ ' \tCPU Time Elapsed = ' + str(r.elapsed['plot_cputime'])) if p.probType == 'MOP': msg = '%d solutions have been obtained' % len(p.solutions.coords) p.disp(msg) return # TODO: add output of NaNs number in constraints (if presernt) if p.useScaledResidualOutput: rMsg = 'max(residuals/requiredTolerances) = %g' % (r.rf / p.contol) else: rMsg = 'MaxResidual = %g' % r.rf if not p.isFeasible: nNaNs = (len(where(isnan(p.c(p.xf)))[0]) if hasattr(p, 'c') else 0) + (len(where(isnan(p.h(p.xf)))[0]) if hasattr(p, 'h') else 0) if nNaNs == 0: nNaNsMsg = '' elif nNaNs == 1: nNaNsMsg = '1 constraint is equal to NaN, ' else: nNaNsMsg = ('%d constraints are equal to NaN, ' % nNaNs) p.disp('NO FEASIBLE SOLUTION has been obtained (%s%s, objFunc = %0.8g)' % (nNaNsMsg, rMsg, r.ff)) else: if p.maxSolutions == 1: msg = "objFunValue: " + (p.finalObjFunTextFormat % r.ff) if not p.isUC: msg += ' (feasible, %s)' % rMsg else: msg = '%d solutions have been obtained' % len(p.solutions) p.disp(msg) ################################################################## def finalShow(p): if not p.plot: return pylab = __import__('pylab') pylab.ioff() if p.show: # import os # if os.fork(): pylab.show() class OpenOptResult: # TODO: implement it #extras = EmptyClass() # used for some optional output def __call__(self, *args): if not self.isFDmodel: raise OpenOptException('Is callable for FuncDesigner models only') r = [] for arg in args: tmp = [(self._xf[elem] if isinstance(elem, str) else self.xf[elem]) for elem in (arg.tolist() if isinstance(arg, ndarray) else arg if type(arg) in (tuple, list) else [arg])] tmp = [asscalar(item) if type(item) in (ndarray, matrix) and item.size == 1 \ #else item[0] if type(item) in (list, tuple) and len(item) == 0 \ else item for item in tmp] r.append(tmp if type(tmp) not in (list, tuple) or len(tmp)!=1 else tmp[0]) r = r[0] if len(args) == 1 else r if len(args) == 1 and type(r) in (list, tuple) and len(r) >1: r = asfarray(r, dtype = type(r[0])) return r def __init__(self, p): self.rf = asscalar(asarray(p.rf)) self.ff = asscalar(asarray(p.ff)) self.isFDmodel = p.isFDmodel self.probType = p.probType if p.probType == 'EIG': self.eigenvalues, self.eigenvectors = p.eigenvalues, p.eigenvectors if p.isFDmodel: self.xf = dict([(v, asscalar(val) if isinstance(val, ndarray) and val.size ==1 else v.aux_domain[val] if 'aux_domain' in v.__dict__ else val) for v, val in p.xf.items()]) if not hasattr(self, '_xf'): #self._xf = dict([(v.name, asscalar(val) if isinstance(val, ndarray) and val.size ==1 else val) for v, val in p.xf.items()]) self._xf = dict([(v.name, val) for v, val in self.xf.items()]) else: self.xf = p.xf #if len(p.solutions) == 0 and p.isFeas(p.xk): p.solutions = [p.xk] # TODO: mb perform check on each solution for more safety? # although it can slow down calculations for huge solutions number #self.solutions = p.solutions self.elapsed = dict() self.elapsed['solver_time'] = round(100.0*(time() - p.timeStart))/100.0 self.elapsed['solver_cputime'] = clock() - p.cpuTimeStart for fn in ('ff', 'istop', 'duals', 'isFeasible', 'msg', 'stopcase', 'iterValues', 'special', 'extras', 'solutions'): if hasattr(p, fn): setattr(self, fn, getattr(p, fn)) if hasattr(p.solver, 'innerState'): self.extras['innerState'] = p.solver.innerState self.solverInfo = dict() for fn in ('homepage', 'alg', 'authors', 'license', 'info', 'name'): self.solverInfo[fn] = getattr(p.solver, '__' + fn + '__') # note - it doesn't work for len(args)>1 for current Python ver 2.6 #self.__getitem__ = c # = self.__call__ if p.plot: #for df in p.graphics.drawFuncs: df(p) #TODO: include time spent here to (/cpu)timeElapsedForPlotting self.elapsed['plot_time'] = round(100*p.timeElapsedForPlotting[-1])/100 # seconds self.elapsed['plot_cputime'] = p.cpuTimeElapsedForPlotting[-1] else: self.elapsed['plot_time'] = 0 self.elapsed['plot_cputime'] = 0 self.elapsed['solver_time'] -= self.elapsed['plot_time'] self.elapsed['solver_cputime'] -= self.elapsed['plot_cputime'] self.evals = dict([(key, val if type(val) == int else round(val *10) /10.0) for key, val in p.nEvals.items()]) self.evals['iter'] = p.iter openopt-0.38+svn1589/openopt/kernel/setDefaultIterFuncs.py000066400000000000000000000111531175775750500235460ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import * #TODO: add stopcases -10,-11,-12, -13 SMALL_DF = 2 SMALL_DELTA_X = 3 SMALL_DELTA_F = 4 FVAL_IS_ENOUGH = 10 MAX_NON_SUCCESS = 11 USER_DEMAND_STOP = 80 BUTTON_ENOUGH_HAS_BEEN_PRESSED = 88 SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON = 1000 UNDEFINED = 0 IS_NAN_IN_X = -4 IS_LINE_SEARCH_FAILED = -5 IS_MAX_ITER_REACHED = -7 IS_MAX_CPU_TIME_REACHED = -8 IS_MAX_TIME_REACHED = -9 IS_MAX_FUN_EVALS_REACHED = -10 IS_ALL_VARS_FIXED = -11 FAILED_TO_OBTAIN_MOVE_DIRECTION = -13 USER_DEMAND_EXIT = -99 FAILED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON = -1000 def stopcase(arg): if hasattr(arg, 'istop'): istop = arg.istop else: istop = arg if istop > 0: return 1 elif istop in [0, IS_MAX_ITER_REACHED, IS_MAX_CPU_TIME_REACHED, IS_MAX_TIME_REACHED, IS_MAX_FUN_EVALS_REACHED]: return 0 else: return -1 def setDefaultIterFuncs(className): d = dict() # positive: d[SMALL_DF] = lambda p: small_df(p) d[SMALL_DELTA_X] = lambda p: small_deltaX(p) d[SMALL_DELTA_F] = lambda p: small_deltaF(p) d[FVAL_IS_ENOUGH] = lambda p: isEnough(p) #d[11] = lambda p: allVarsAreFixed(p) # negative: d[IS_NAN_IN_X] = lambda p: isNanInX(p) d[IS_MAX_ITER_REACHED] = lambda p: isMaxIterReached(p) d[IS_MAX_CPU_TIME_REACHED] = lambda p: isMaxCPUTimeReached(p) d[IS_MAX_TIME_REACHED] = lambda p: isMaxTimeReached(p) if className == 'NonLin': d[IS_MAX_FUN_EVALS_REACHED] = lambda p: isMaxFunEvalsReached(p) return d def small_df(p): if not hasattr(p, '_df') or p._df is None: return False if hasattr(p._df, 'toarray'):p._df = p._df.toarray() if p.norm(p._df) >= p.gtol or not all(isfinite(p._df)) or not p.isFeas(p.iterValues.x[-1]): return False return (True, '|| gradient F(X[k]) || < gtol') #return False if not hasattr(p, 'dF') or p.dF == None or p.norm(p.dF) > p.gtol else True def small_deltaX(p): if p.iter == 0: return False diffX = p.iterValues.x[-1] - p.iterValues.x[-2] if p.scale is not None: diffX *= p.scale if p.norm(diffX) >= p.xtol: return False else: return (True, '|| X[k] - X[k-1] || < xtol') #r = False if p.norm(p.xk - p.x_prev) > p.xtol else True def small_deltaF(p): if p.iter == 0: return False #r = False if p.norm(p.fk - p.f_prev) > p.ftol else True if isnan(p.iterValues.f[-1]) or isnan(p.iterValues.f[-2]) or p.norm(p.iterValues.f[-1] - p.iterValues.f[-2]) >= p.ftol: # or (p.iterValues.r[-1] > p.contol and p.iterValues.r[-1] - p.iterValues.r[-2] < p.contol): return False else: return (True, '|| F[k] - F[k-1] || < ftol') def isEnough(p): # asscalar(asarray(p.Fk)) was added for compatibility with ironpython if p.fEnough > asscalar(asarray(p.Fk)) and p.isFeas(p.xk): #TODO: mb replace by p.rk= p.maxIter-1: # iter numeration starts from zero return (True, 'Max Iter has been reached') else: return False def isMaxCPUTimeReached(p): if p.iterCPUTime[-1] < p.maxCPUTime + p.cpuTimeElapsedForPlotting[-1]: return False else: return (True, 'max CPU time limit has been reached') #return p.cpuTimeElapsed >= p.maxCPUTime def isMaxTimeReached(p): if p.currtime - p.timeStart < p.maxTime + p.timeElapsedForPlotting[-1]: return False else: return (True, 'max time limit has been reached') def isMaxFunEvalsReached(p): #if not hasattr(p, 'nFunEvals'): p.warn('no nFunEvals field'); return 0 if p.nEvals['f'] >= p.maxFunEvals: return (True, 'max objfunc evals limit has been reached') else: return False #################################################################### def denyingStopFuncs(ProblemGroup=None): #mb in future it will be class-dependend, like Matrix, Nonlinear etc return {isMinIterReached : 'min iter is not reached yet', isMinTimeReached : 'min time is not reached yet', isMinCPUTimeReached:'min cputime is not reached yet', isMinFunEvalsReached:'min objective function evaluations nuber is not reached yet'} isMinFunEvalsReached = lambda p: p.minFunEvals==0 or ('f' in p.nEvals.keys() and p.nEvals['f'] >= p.minFunEvals) isMinTimeReached = lambda p: p.currtime - p.timeStart > p.minTime + p.timeElapsedForPlotting[-1] isMinCPUTimeReached = lambda p: p.iterCPUTime[-1] >= p.minCPUTime + p.cpuTimeElapsedForPlotting[-1] isMinIterReached = lambda p: p.iter >= p.minIter openopt-0.38+svn1589/openopt/oo.py000066400000000000000000000632771175775750500167760ustar00rootroot00000000000000import os,sys sys.path.append(os.getcwd()+os.sep+'kernel') from LP import LP as CLP from LCP import LCP as CLCP from EIG import EIG as CEIG from SDP import SDP as CSDP from QP import QP as CQP from MILP import MILP as CMILP from NSP import NSP as CNSP from NLP import NLP as CNLP from MOP import MOP as CMOP from MINLP import MINLP as CMINLP from NLSP import NLSP as CNLSP from NLLSP import NLLSP as CNLLSP from GLP import GLP as CGLP from SLE import SLE as CSLE from LLSP import LLSP as CLLSP from MMP import MMP as CMMP from LLAVP import LLAVP as CLLAVP from LUNP import LUNP as CLUNP from SOCP import SOCP as CSOCP from DFP import DFP as CDFP from IP import IP as CIP from ODE import ODE as CODE def MILP(*args, **kwargs): """ MILP: constructor for Mixed Integer Linear Problem assignment f' x -> min subjected to lb <= x <= ub A x <= b Aeq x = beq for all i from intVars: i-th coordinate of x is required to be integer for all j from binVars: j-th coordinate of x is required to be from {0, 1} Examples of valid calls: p = MILP(f, ) p = MILP(f=objFunVector, ) p = MILP(f, A=A, intVars = myIntVars, Aeq=Aeq, b=b, beq=beq, lb=lb, ub=ub, binVars = binVars) See also: /examples/milp_*.py :Parameters: - intVars : Python list of those coordinates that are required to be integers. - binVars : Python list of those coordinates that are required to be binary. all other input parameters are same to LP class constructor ones :Returns: OpenOpt MILP class instance Notes ----- Solving of MILPs is performed via r = p.solve(string_name_of_solver) or p.maximize, p.minimize r.xf - desired solution (NaNs if a problem occured) r.ff - objFun value () (NaN if a problem occured) (see also other r fields) Solvers available for now: lpSolve (LGPL) - requires lpsolve + Python bindings installations (all mentioned is available in http://sourceforge.net/projects/lpsolve) glpk (GPL 2) - requires glpk + CVXOPT v >= 1.0 installations (read OO MILP webpage for more details) """ return CMILP(*args, **kwargs) def LP(*args, **kwargs): """ LP: constructor for Linear Problem assignment f' x -> min subjected to lb <= x <= ub A x <= b Aeq x = beq valid calls are: p = LP(f, ) p = LP(f=objFunVector, ) p = LP(f, A=A, Aeq=Aeq, Awhole=Awhole, b=b, beq=beq, bwhole=bwhole, dwhole=dwhole, lb=lb, ub=ub) See also: /examples/lp_*.py :Parameters: f: vector of length n A: size m1 x n matrix, subjected to A * x <= b Aeq: size m2 x n matrix, subjected to Aeq * x = beq b, beq: corresponding vectors of lengthes m1, m2 lb, ub: vectors of length n, some coords may be +/- inf :Returns: OpenOpt LP class instance Notes ----- Solving of LPs is performed via r = p.solve(string_name_of_solver) or p.maximize, p.minimize r.xf - desired solution (NaNs if a problem occured) r.ff - objFun value () (NaN if a problem occured) (see also other r fields) Solvers available for now: pclp (BSD) - premature but pure Python implementation with permissive license lpSolve (LGPL) - requires lpsolve + Python bindings installations (all mentioned is available in http://sourceforge.net/projects/lpsolve) cvxopt_lp (GPL) - requires CVXOPT (http://abel.ee.ucla.edu/cvxopt) glpk(GPL2) - requires CVXOPT(http://abel.ee.ucla.edu/cvxopt) & glpk (www.gnu.org/software/glpk) converter to NLP. Example: r = p.solve('nlp:ipopt') """ return CLP(*args, **kwargs) def LCP(*args, **kwargs): """ LCP: constructor for Linear Complementarity Problem assignment find w, z: w = Mz + q valid calls are: p = LP(M, q, ) p = LP(M=M, q=q, ) See also: /examples/lcp_*.py :Parameters: M: numpy array of size n x n q: vector of length n :Returns: OpenOpt LCP class instance Notes ----- Solving of LCPs is performed via r = p.solve(string_name_of_solver) r.xf - desired solution (1st n/2 coords are w, other n/2 coords are z) r.ff - objFun value (max residual of Mz+q-w) (NaN if a problem occured) (see also other r fields) Solvers available for now: lcpsolve (BSD) """ return CLCP(*args, **kwargs) def EIG(*args, **kwargs): """ EIG: constructor for Eigenvalues Problem assignment to solve standard eigenvalue problem: find eigenvalues and eigenvectors of square matrix A: A x = lambda x or general eigenvalue problem: A x = lambda M x valid calls are: p = EIG(M, q, ) p = EIG(M=M, q=q, ) See also: /examples/eig_*.py :Parameters: A, (optional) M: numpy array or scipy sparse matrix of size n x n :Returns: OpenOpt EIG class instance Notes ----- Solving of EIGs is performed via r = p.solve(string_name_of_solver) see http://openopt.org/EIG for more info Solvers available for now: arpack (license: BSD) """ return CEIG(*args, **kwargs) def SDP(*args, **kwargs): """ SDP: constructor for SemiDefinite Problem assignment f' x -> min subjected to lb <= x <= ub A x <= b Aeq x = beq For all i = 0, ..., I: Sum [j = 0, ..., n-1] {S_i_j x_j} <= d_i (matrix componentwise inequality), d_i are square matrices S_i_j are square positive semidefinite matrices of size same to d_i valid calls are: p = SDP(f, ) p = SDP(f=objFunVector, ) p = SDP(f, S=S, d=d, A=A, Aeq=Aeq, Awhole=Awhole, b=b, beq=beq, bwhole=bwhole, dwhole=dwhole, lb=lb, ub=ub) See also: /examples/sdp_*.py :Parameters: f: vector of length n S: Python dict of square matrices S[0, 0], S[0,1], ..., S[I,J] S[i, j] are real symmetric positive-definite matrices d: Python dict of square matrices d[0], ..., d[I] A: size m1 x n matrix, subjected to A * x <= b Aeq: size m2 x n matrix, subjected to Aeq * x = beq b, beq: corresponding vectors of lengthes m1, m2 lb, ub: vectors of length n, some coords may be +/- inf :Returns: OpenOpt SDP class instance Notes ----- Solving of SDPs is performed via r = p.solve(string_name_of_solver) r.xf - desired solution (NaNs if a problem occured) r.ff - objFun value () (NaN if a problem occured) (see also other r fields) Solvers available for now: cvxopt_sdp (LGPL) - requires CVXOPT (http://abel.ee.ucla.edu/cvxopt) dsdp (GPL) - requires CVXOPT + DSDP installation, can't handle linear equality constraints Aeq x = beq """ return CSDP(*args, **kwargs) def SOCP(*args, **kwargs): """ SOCP: constructor for Second-Order Cone Problem assignment f' x -> min subjected to lb <= x <= ub Aeq x = beq For all i = 0, ..., I: ||C_i x + d_i|| <= q_i x + s_i valid calls are: p = SDP(f, ) p = SDP(f=objFunVector, ) p = SDP(f, S=S, d=d, A=A, Aeq=Aeq, Awhole=Awhole, b=b, beq=beq, bwhole=bwhole, dwhole=dwhole, lb=lb, ub=ub) See also: /examples/sdp_*.py :Parameters: f: vector of length n Aeq: size M x n matrix, subjected to Aeq * x = beq beq: corresponding vector of length M C: Python list of matrices C_i of shape (m_i, n) d: Python list of vectors of length m_i q: Python list of vectors of length n s: Python list of numbers, len(s) = n lb, ub: vectors of length n, some coords may be +/- inf :Returns: OpenOpt SDP class instance Notes ----- Solving of SOCPs is performed via r = p.solve(string_name_of_solver) r.xf - desired solution (NaNs if a problem occured) r.ff - objFun value () (NaN if a problem occured) (see also other r fields) Solvers available for now: cvxopt_socp (LGPL) - requires CVXOPT (http://abel.ee.ucla.edu/cvxopt) """ return CSOCP(*args, **kwargs) def QP(*args, **kwargs): """ QP: constructor for Quadratic Problem assignment 1/2 x' H x + f' x -> min subjected to A x <= b Aeq x = beq lb <= x <= ub Examples of valid calls: p = QP(H, f, ) p = QP(numpy.ones((3,3)), f=numpy.array([1,2,4]), ) p = QP(f=range(8)+15, H = numpy.diag(numpy.ones(8)), ) p = QP(H, f, A=A, Aeq=Aeq, b=b, beq=beq, lb=lb, ub=ub, ) See also: /examples/qp_*.py INPUT: H: size n x n matrix, symmetric, positive-definite f: vector of length n lb, ub: vectors of length n, some coords may be +/- inf A: size m1 x n matrix, subjected to A * x <= b Aeq: size m2 x n matrix, subjected to Aeq * x = beq b, beq: vectors of lengths m1, m2 Alternatively to A/Aeq you can use Awhole matrix as it's described in LP documentation (or both A, Aeq, Awhole) OUTPUT: OpenOpt QP class instance Solving of QPs is performed via r = p.solve(string_name_of_solver) r.xf - desired solution (NaNs if a problem occured) r.ff - objFun value (NaN if a problem occured) (see also other r fields) Solvers available for now: cvxopt_qp (GPL) - requires CVXOPT (http://abel.ee.ucla.edu/cvxopt) converter to NLP. Example: r = p.solve('nlp:ipopt') """ return CQP(*args, **kwargs) def NLP(*args, **kwargs): """ NLP: constructor for general Non-Linear Problem assignment f(x) -> min (or -> max) subjected to c(x) <= 0 h(x) = 0 A x <= b Aeq x = beq lb <= x <= ub Examples of valid usage: p = NLP(f, x0, ) p = NLP(f=objFun, x0 = myX0, ) p = NLP(f, x0, A=A, df = objFunGradient, Aeq=Aeq, b=b, beq=beq, lb=lb, ub=ub) See also: /examples/nlp_*.py INPUTS: f: objFun x0: start point, vector of length n Optional: name: problem name (string), is used in text & graphics output df: user-supplied gradient of objective function c, h - functions defining nonlinear equality/inequality constraints dc, dh - functions defining 1st derivatives of non-linear constraints A: size m1 x n matrix, subjected to A * x <= b Aeq: size m2 x n matrix, subjected to Aeq * x = beq b, beq: corresponding vectors of lengthes m1, m2 lb, ub: vectors of length n subjected to lb <= x <= ub constraints, may include +/- inf values iprint = {10}: print text output every iteration goal = {'minimum'} | 'min' | 'maximum' | 'max' - minimize or maximize objective function diffInt = {1e-7} : finite-difference gradient aproximation step, scalar or vector of length nVars scale = {None} : scale factor, see /examples/badlyScaled.py for more details stencil = {1}|2|3: finite-differences derivatives approximation stencil, used by most of solvers (except scipy_cobyla) when no user-supplied for objfun / nonline constraints derivatives are provided 1: (f(x+dx)-f(x))/dx (faster but less precize) 2: (f(x+dx)-f(x-dx))/(2*dx) (slower but more exact) 3: (-f(x+2*dx)+8*f(x+dx)-8*f(x-dx)+f(x-2*dx))/(12*dx) (even more slower, but even more exact) check.df, check.dc, check.dh: if set to True, OpenOpt will check user-supplied gradients. args (or args.f, args.c, args.h) - additional arguments to objFunc and non-linear constraints, see /examples/userArgs.py for more details. contol: max allowed residual in optim point (for any constraint from problem constraints: constraint(x_optim) < contol is required from solver) stop criteria: maxIter {400} maxFunEvals {1e5} maxCPUTime {inf} maxTime {inf} maxLineSearch {500} fEnough {-inf for min problems, +inf for max problems}: stop if objFunc vulue better than fEnough and all constraints less than contol ftol {1e-6}: used in stop criterium || f[iter_k] - f[iter_k+1] || < ftol xtol {1e-6}: used in stop criterium || x[iter_k] - x[iter_k+1] || < xtol gtol {1e-6}: used in stop criteria || gradient(x[iter_k]) || < gtol callback - user-defined callback function(s), see /examples/userCallback.py Notes: 1) for more safety default values checking/reassigning (via print p.maxIter / prob.maxIter = 400) is recommended (they may change in future OpenOpt versions and/or not updated in time in the documentation) 2) some solvers may ignore some of the stop criteria above and/or use their own ones 3) for NSP constructor ftol, xtol, gtol defaults may have other values graphic options: plot = {False} | True : plot figure (now implemented for UC problems only), requires matplotlib installed color = {'blue'} | black | ... (any valid matplotlib color) specifier = {'-'} | '--' | ':' | '-.' - plot specifier show = {True} | False : call pylab.show() after solver finish or not xlim {(nan, nan)}, ylim {(nan, nan)} - initial estimation for graphical output borders (you can use for example p.xlim = (nan, 10) or p.ylim = [-8, 15] or p.xlim=[inf, 15], only real finite values will be taken into account) for constrained problems ylim affects only 1st subplot p.graphics.xlabel or p.xlabel = {'time'} | 'cputime' | 'iter' # desired graphic output units in x-axe, case-unsensetive Note: some Python IDEs have problems with matplotlib! Also, after assignment NLP instance you may modify prob fields inplace: p.maxIter = 1000 p.df = lambda x: cos(x) OUTPUT: OpenOpt NLP class instance Solving of NLPs is performed via r = p.solve(string_name_of_solver) or p.maximize, p.minimize r.xf - desired solution (NaNs if a problem occured) r.ff - objFun value (NaN if a problem occured) (see also other fields, such as CPUTimeElapsed, TimeElapsed, isFeasible, iter etc, via dir(r)) Solvers available for now: single-variable: goldenSection, scipy_fminbound (latter is not recommended) (both these solvers require finite lb-ub and ignore user-supplied gradient) unconstrained: scipy_bfgs, scipy_cg, scipy_ncg, (these ones cannot handle user-provided gradient) scipy_powell and scipy_fmin amsg2p - requires knowing fOpt (optimal value) box-bounded: scipy_lbfgsb, scipy_tnc - require scipy installed bobyqa - doesn't use derivatives; requires http://openopt.org/nlopt installed ptn, slmvm1, slmvm2 - require http://openopt.org/nlopt installed all constraints: ralg ipopt (requires ipopt + pyipopt installed) scipy_slsqp scipy_cobyla (this one cannot handle user-supplied gradients) lincher (requires CVXOPT QP solver), gsubg - for large-scaled problems algencan (ver. 2.0.3 or more recent, very powerful constrained solver, GPL, requires ALGENCAN + Python interface installed, see http://www.ime.usp.br/~egbirgin/tango/) mma and auglag - require http://openopt.org/nlopt installed """ return CNLP(*args, **kwargs) def MINLP(*args, **kwargs): """ MINLP: constructor for general Mixed-Integer Non-Linear Problem assignment parameters and usage: same to NLP, + parameters discreteVars: dictionary numberOfCoord <-> list (or tuple) of allowed values, eg p.discreteVars = {0: [1, 2.5], 15: (3.1, 4), 150: [4,5, 6]} discrtol (default 1e-5) - tolerance required for discrete constraints available solvers: branb (branch-and-bound) - translation of fminconset routine, requires non-default string parameter nlpSolver """ return CMINLP(*args, **kwargs) def NSP(*args, **kwargs): """ Non-Smooth Problem constructor Same usage as NLP (see help(NLP) and /examples/nsp_*.py), but default values of contol, xtol, ftol, diffInt may differ Also, default finite-differences derivatives approximation stencil is 3 instead of 1 for NLP Solvers available for now: ralg - all constraints, medium-scaled (nVars = 1...1000), can handle user-provided gradient/subgradient amsg2p - requires knowing fOpt (optimal value), medium-scaled (nVars = 1...1000), can handle user-provided gradient/subgradient gsubg - for large-scaled problems scipy_fmin - a Nelder-Mead simplex algorithm implementation, cannot handle constraints and derivatives sbplx - A variant of Nelder-Mead algorithm; requires http://openopt.org/nlopt installed ShorEllipsoid (unconstrained for now) - small-scale, nVars=1...10, requires r0: ||x0-x*||<=r0 """ return CNSP(*args, **kwargs) def NLSP(*args, **kwargs): """ Solving systems of n non-linear equations with n variables Parameters and usage: same as NLP (see help(NLP) and /examples/nlsp_*.py) Solvers available for now: scipy_fsolve (can handle df); converter to NLP. Example: r = p.solve('nlp:ipopt'); nssolve (primarily for non-smooth and noisy funcs; can handle all types of constraints and 1st derivatives df,dc,dh; splitting equations to Python list or tuple is recommended to speedup calculations) (these ones below are very unstable and can't use user-supplied gradient - at least, for scipy 0.6.0) scipy_anderson scipy_anderson2 scipy_broyden1 scipy_broyden2 scipy_broyden3 scipy_broyden_generalized """ r = CNLSP(*args, **kwargs) r.pWarn(''' OpenOpt NLSP class had been renamed to SNLE (system of nonlinear equations), use "SNLE" instead of "NLSP" ''') return r def SNLE(*args, **kwargs): """ Solving systems of n non-linear equations with n variables Parameters and usage: same as NLP (see help(NLP) and /examples/nlsp_*.py) Solvers available for now: scipy_fsolve (can handle df); converter to NLP. Example: r = p.solve('nlp:ipopt'); nssolve (primarily for non-smooth and noisy funcs; can handle all types of constraints and 1st derivatives df,dc,dh; splitting equations to Python list or tuple is recommended to speedup calculations) (these ones below are very unstable and can't use user-supplied gradient - at least, for scipy 0.6.0) scipy_anderson scipy_anderson2 scipy_broyden1 scipy_broyden2 scipy_broyden3 scipy_broyden_generalized """ return CNLSP(*args, **kwargs) def NLLSP(*args, **kwargs): """ Given set of non-linear equations f1(x)=0, f2(x)=0, ... fm(x)=0 search for x: f1(x, )^2 + ,,, + fm(x, )^2 -> min Parameters and usage: same as NLP (see help(openopt.NLP) and /examples/nllsp_*.py) Solvers available for now: scipy_leastsq (requires scipy installed) converter to NLP. Example: r = p.solve('nlp:ralg') """ return CNLLSP(*args, **kwargs) def MOP(*args, **kwargs): ''' Multiobjective optimization Search for weak or strong Pareto front Solvers available for now: interalg (http://openopt.org/interalg) ''' return CMOP(*args, **kwargs) def IP(*args, **kwargs): """ Integrate a function f: R^n -> R over a given domain lb_i <= x_i <= ub_i """ return CIP(*args, **kwargs) def ODE(*args, **kwargs): """ Solve ODE dy/dt = f(y,t), y(0) = y0 """ return CODE(*args, **kwargs) def SLE(*args, **kwargs): """ SLE: constructor for system of linear equations C*x = d assignment Examples of valid usage: p = SLE(C, d, ) p = SLE(C=C, d=d, ) """ return CSLE(*args, **kwargs) def DFP(*args, **kwargs): """ Data Fit Problem constructor Search for x: Sum_i || F(x, X_i) - Y_i ||^2 -> min subjected to c(x) <= 0 h(x) = 0 A x <= b Aeq x = beq lb <= x <= ub Some examples of valid usage: p = NLP(f, x0, X, Y, ) p = NLP(f=objFun, x0 = my_x0, X = my_X, Y=my_Y, ) p = NLP(f, x0, X, Y, A=A, Aeq=Aeq, b=b, beq=beq, lb=lb, ub=ub, ) Parameters and usage: same as NLP, see help(openopt.NLP) See also: /examples/dfp_*.py Solvers available for now: converter to NLP. Example: r = p.solve('nlp:ralg') """ return CDFP(*args, **kwargs) def GLP(*args, **kwargs): """ GLP: constructor for general GLobal Problem search for global optimum of general non-linear (maybe discontinious) function f(x) -> min/max subjected to lb <= x <= ub Ax <= b c(x) <= 0 usage: p = GLP(f, ) Solving of NLPs is performed via r = p.solve(string_name_of_solver) or p.maximize, p.minimize Parameters and usage: same as NLP (see help(NLP) and /examples/glp_*.py) One more stop criterion is maxNonSuccess (default: 15) See also: /examples/glp_*.py Solvers available: galileo - a GA-based solver by Donald Goodman, requires finite lb <= x <= ub pswarm (requires PSwarm installed), license: BSD, can handle Ax<=b, requires finite search area de (this is temporary name, will be changed till next OO release v. 0.22), license: BSD, requires finite lb <= x <= ub, can handle Ax<=b, c(x) <= 0. The solver is based on differential evolution and made by Stepan Hlushak. stogo and mlsl - can use derivatives; require http://openopt.org/nlopt installed isres - can handle any constraints; requires http://openopt.org/nlopt installed interalg - exact optimum wrt required tolerance, see http://openopt.org/interalg for details """ return CGLP(*args, **kwargs) def LLSP(*args, **kwargs): """ LLSP: constructor for Linear Least Squares Problem assignment 0.5*||C*x-d||^2 + 0.5*damp*||x-X||^2 + -> min subjected to: lb <= x <= ub Examples of valid calls: p = LLSP(C, d, ) p = LLSP(C=my_C, d=my_d, ) p = LLSP(C, d, lb=lb, ub=ub) See also: /examples/llsp_*.py :Parameters: C - float m x n numpy.ndarray, numpy.matrix or Python list of lists d - float array of length m (numpy.ndarray, numpy.matrix, Python list or tuple) damp - non-negative float number X - float array of length n (by default all-zeros) f - float array of length n (by default all-zeros) lb, ub - float arrays of length n (numpy.ndarray, numpy.matrix, Python list or tuple) :Returns: OpenOpt LLSP class instance Notes ----- Solving of LLSPs is performed via r = p.solve(string_name_of_solver) r.xf - desired solution (NaNs if a problem occured) r.ff - objFun value (NaN if a problem occured) (see also other r fields) Solvers available for now: lsqr (license: GPL) - most efficient, can hanlde scipy.sparse matrices, user-supplied or generated by FuncDesigner models automatically lapack_dgelss (license: BSD) - slow but stable, requires scipy; unconstrained lapack_sgelss (license: BSD) - single precesion, requires scipy; unconstrained bvls (license: BSD) - requires installation from OO LLSP webpage, can handle lb, ub converter to nlp. Example: r = p.solve('nlp:ralg', plot=1, iprint =15, <...>) """ return CLLSP(*args, **kwargs) def MMP(*args, **kwargs): """ MMP: constructor for Mini-Max Problem search for minimum of max(func0(x), func1(x), ... funcN(x)) See also: /examples/mmp_*.py Parameters and usage: same as NLP (see help(NLP) and /examples/mmp_*.py) Solvers available: nsmm (currently unconstrained, NonSmooth-based MiniMax, uses NSP ralg solver) """ return CMMP(*args, **kwargs) def LLAVP(*args, **kwargs): """ LLAVP : constructor for Linear Least Absolute Value Problem assignment ||C * x - d||_1 + damp*||x-X||_1-> min subjected to: lb <= x <= ub Examples of valid calls: p = LLAVP(C, d, ) p = LLAVP(C=my_C, d=my_d, ) p = LLAVP(C, d, lb=lb, ub=ub) See also: /examples/llavp_*.py :Parameters: C - float m x n numpy.ndarray, numpy.matrix or Python list of lists d - float array of length m (numpy.ndarray, numpy.matrix, Python list or tuple) damp - non-negative float number X - float array of length n (by default all-zeros) lb, ub - float arrays of length n (numpy.ndarray, numpy.matrix, Python list or tuple) :Returns: OpenOpt LLAVP class instance Notes ----- Solving of LLAVPs is performed via r = p.solve(string_name_of_solver) r.xf - desired solution (NaNs if a problem occured) r.ff - objFun value (NaN if a problem occured) (see also other r fields) Solvers available for now: nsp: - converter llavp2nsp. Example: r = p.solve('nsp:ralg', plot=1, iprint =15, <...>) """ return CLLAVP(*args, **kwargs) def LUNP(*args, **kwargs): """ LUNP : constructor for Linear Uniform Norm Problem assignment || C * x - d ||_inf (that is max | C * x - d |) -> min subjected to: lb <= x <= ub A x <= b Aeq x = beq Examples of valid calls: p = LUNP(C, d, ) p = LUNP(C=my_C, d=my_d, ) p = LUNP(C, d, lb=lb, ub=ub, A = A, b = b, Aeq = Aeq, beq=beq, ...) See also: /examples/lunp_*.py :Parameters: C - float m x n numpy.ndarray, numpy.matrix or Python list of lists d - float array of length m (numpy.ndarray, numpy.matrix, Python list or tuple) damp - non-negative float number lb, ub - float arrays of length n (numpy.ndarray, numpy.matrix, Python list or tuple) :Returns: OpenOpt LUNP class instance Notes ----- Solving of LUNPs is performed via r = p.solve(string_name_of_solver) r.xf - desired solution (NaNs if a problem occured) r.ff - objFun value (NaN if a problem occured) (see also other r fields) Solvers available for now: lp: - converter lunp2lp. Example: r = p.solve('lp:lpSolve', <...>) """ return CLUNP(*args, **kwargs) openopt-0.38+svn1589/openopt/ooVersionNumber.py000066400000000000000000000003061175775750500214750ustar00rootroot00000000000000""" OpenOpt: numerical optimization package for Python Copyright (C) 2007-2010 Dmitrey Kroshko LICENSE: new BSD. See COPYING.txt for details. """ __version__ = '0.38' openopt-0.38+svn1589/openopt/solvers/000077500000000000000000000000001175775750500174655ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/solvers/BrasilOpt/000077500000000000000000000000001175775750500213645ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/solvers/BrasilOpt/__init__.py000066400000000000000000000000021175775750500234650ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/solvers/BrasilOpt/algencan_oo.py000066400000000000000000000516661175775750500242210ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import * from openopt.kernel.baseSolver import baseSolver import pywrapper from openopt.kernel.setDefaultIterFuncs import SMALL_DF class algencan(baseSolver): __name__ = 'algencan' __license__ = "GPL" __authors__ = 'J. M. Martinez martinezimecc@gmail.com, Ernesto G. Birgin egbirgin@ime.usp.br, Jan Marcel Paiva Gentil jgmarcel@ime.usp.br' __alg__ = "Augmented Lagrangian Multipliers" __homepage__ = 'http://www.ime.usp.br/~egbirgin/tango/' #TODO: edit info! __info__ = "please pay more attention to gtol param, it's the only one ALGENCAN positive stop criterium, xtol and ftol are unused" __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] __isIterPointAlwaysFeasible__ = lambda self, p: p.__isNoMoreThanBoxBounded__() __cannotHandleExceptions__ = True def __init__(self): pass def __solver__(self, p): def inip(): """This subroutine must set some problem data. For achieving this objective YOU MUST MODIFY it according to your problem. See below where your modifications must be inserted. Parameters of the subroutine: On Entry: This subroutine has no input parameters. On Return n integer, number of variables, x double precision x(n), initial point, l double precision l(n), lower bounds on x, u double precision u(n), upper bounds on x, m integer, number of constraints (excluding the bounds), lambda double precision lambda(m), initial estimation of the Lagrange multipliers, equatn logical equatn(m) for each constraint j, set equatn(j) = .true. if it is an equality constraint of the form c_j(x) = 0, and set equatn(j) = .false. if it is an inequality constraint of the form c_j(x) <= 0, linear logical linear(m) for each constraint j, set linear(j) = .true. if it is a linear constraint, and set linear(j) = .false. if it is a nonlinear constraint. """ # Number of variables n = p.n # Number of constraints (equalities plus inequalities) # if p.userProvided.c: nc = p.c(p.x0).size # else: nc = 0 # if p.userProvided.h: nh = p.h(p.x0).size # else: nh = 0 nc, nh = p.nc, p.nh nb, nbeq = p.b.size, p.beq.size #p.algencan.nc, p.algencan.nh, p.algencan.nb, p.algencan.nbeq = nc, nh, nb, nbeq m = nc + nh + nb + nbeq # Initial point x = p.x0 # Lower and upper bounds l = p.lb l[l<-1.0e20] = -1.0e20 u = p.ub u[u>1.0e20] = 1.0e20 # Lagrange multipliers approximation. Most users prefer to use the # null initial Lagrange multipliers estimates. However, if the # problem that you are solving is "slightly different" from a # previously solved problem of which you know the correct Lagrange # multipliers, we encourage you to set these multipliers as initial # estimates. Of course, in this case you are also encouraged to use # the solution of the previous problem as initial estimate of the # solution. Similarly, most users prefer to use rho = 10 as initial # penalty parameters. But in the case mentioned above (good # estimates of solution and Lagrange multipliers) larger values of # the penalty parameters (say, rho = 1000) may be more useful. More # warm-start procedures are being elaborated. lambda_ = zeros(m) # For each constraint i, set equatn[i] = 1. if it is an equality # constraint of the form c_i(x) = 0, and set equatn[i] = 0 if # it is an inequality constraint of the form c_i(x) <= 0. equatn = array( [False]*nc + [True]*nh + [False]*nb + [True]*nbeq) # For each constraint i, set linear[i] = 1 if it is a linear # constraint, otherwise set linear[i] = 0. linear = array( [False]*nc + [False]*nh + [True]*nb + [True]*nbeq) coded = [True, # evalf True, # evalg p.userProvided.d2f, # evalh True, # evalc True, # evaljac False, # evalhc False, # evalfc False, # evalgjac False, # evalhl False] # evalhlp checkder = False #checkder = 1 return n,x,l,u,m,lambda_,equatn.tolist(),linear.tolist(),coded,checkder # ****************************************************************** # ****************************************************************** def evalf(x): """This subroutine must compute the objective function. For achieving this objective YOU MUST MODIFY it according to your problem. See below where your modifications must be inserted. Parameters of the subroutine: On Entry: x double precision x(n), current point, On Return f double precision, objective function value at x, flag integer, You must set it to any number different of 0 (zero) if some error ocurred during the evaluation of the objective function. (For example, trying to compute the square root of a negative number, dividing by zero or a very small number, etc.) If everything was o.k. you must set it equal to zero. """ f = p.f(x) if f is not nan: flag = 0 else: flag = 1 return f,flag # ****************************************************************** # ****************************************************************** def evalg(x): """This subroutine must compute the gradient vector of the objective \ function. For achieving these objective YOU MUST MODIFY it in the way specified below. However, if you decide to use numerical derivatives (we dont encourage this option at all!) you dont need to modify evalg. Parameters of the subroutine: On Entry: x double precision x(n), current point, On Return g double precision g(n), gradient vector of the objective function evaluated at x, flag integer, You must set it to any number different of 0 (zero) if some error ocurred during the evaluation of any component of the gradient vector. (For example, trying to compute the square root of a negative number, dividing by zero or a very small number, etc.) If everything was o.k. you must set it equal to zero. """ g = p.df(x) if any(isnan(g)): flag = 1 else: flag = 0 return g,flag # ****************************************************************** # ****************************************************************** def evalh(x): # """This subroutine might compute the Hessian matrix of the objective \ # function. # # For achieving this objective YOU MAY MODIFY it according to your # problem. To modify this subroutine IS NOT MANDATORY. See below # where your modifications must be inserted. # # Parameters of the subroutine: # # On Entry: # # x double precision x(n), # current point, # # On Return # # nnzh integer, # number of perhaps-non-null elements of the computed # Hessian, # # hlin integer hlin(nnzh), # see below, # # hcol integer hcol(nnzh), # see below, # # hval double precision hval(nnzh), # the non-null value of the (hlin(k),hcol(k)) position # of the Hessian matrix of the objective function must # be saved at hval(k). Just the lower triangular part of # Hessian matrix must be computed, # # flag integer, # You must set it to any number different of 0 (zero) if # some error ocurred during the evaluation of the Hessian # matrix of the objective funtion. (For example, trying # to compute the square root of a negative number, # dividing by zero or a very small number, etc.) If # everything was o.k. you must set it equal to zero. # """ # flag = 0 # if hasattr(self, 'd2f'): # return self.d2f try: H = p.d2f(x) except: nnzh = 0 hlin = zeros(nnzh, int) hcol = zeros(nnzh, int) hval = zeros(nnzh, float) flag = 1 return hlin,hcol,hval,nnzh,flag ind = H.nonzero() (ind_0, ind_1) = ind ind_greater = ind_0 >= ind_1 ind_0, ind_1 = ind_0[ind_greater], ind_1[ind_greater] nnzh = ind_0.size val = H[(ind_0, ind_1)] hlin, hcol, hval = ind_0, ind_1, val # if lower(p.castFrom) in ('QP', 'LLSP'): # self.d2f = hlin,hcol,hval,nnzh,flag return hlin,hcol,hval,nnzh,flag # ****************************************************************** # ****************************************************************** def evalc(x,ind): """This subroutine must compute the ind-th constraint. For achieving this objective YOU MUST MOFIFY it according to your problem. See below the places where your modifications must be inserted. Parameters of the subroutine: On Entry: x double precision x(n), current point, ind integer, index of the constraint to be computed, On Return c double precision, i-th constraint evaluated at x, flag integer You must set it to any number different of 0 (zero) if some error ocurred during the evaluation of the constraint. (For example, trying to compute the square root of a negative number, dividing by zero or a very small number, etc.) If everything was o.k. you must set it equal to zero. """ flag = 0 #TODO: recalculate i-th constraint, not all i = ind - 1 # Python enumeration starts from 0, not 1 if i < p.nc: c = p.c(x, i) elif p.nc <= i < p.nc + p.nh: c = p.h(x, i-p.nc) elif p.nc + p.nh <= i < p.nc + p.nh + p.nb: j = i - p.nc - p.nh c = p.dotmult(p.A[j], x).sum() - p.b[j] elif i < p.nc + p.nh + p.nb + p.nbeq: j = i - p.nc - p.nh - p.nb c = p.dotmult(p.Aeq[j], x).sum() - p.beq[j] else: flag = -1 p.err('error in connection algencan to openopt') if any(isnan(c)): flag = -1 return c,flag # ****************************************************************** # ****************************************************************** def evaljac(x,ind): """This subroutine must compute the gradient of the ind-th constraint. For achieving these objective YOU MUST MODIFY it in the way specified below. Parameters of the subroutine: On Entry: x double precision x(n), current point, ind integer, index of the constraint whose gradient will be computed, On Return nnzjac integer, number of perhaps-non-null elements of the computed gradient, indjac integer indjac(nnzjac), see below, valjac double precision valjac(nnzjac), the non-null value of the partial derivative of the i-th constraint with respect to the indjac(k)-th variable must be saved at valjac(k). flag integer You must set it to any number different of 0 (zero) if some error ocurred during the evaluation of the constraint. (For example, trying to compute the square root of a negative number, dividing by zero or a very small number, etc.) If everything was o.k. you must set it equal to zero. """ flag = 0 #TODO: recalculate i-th constraint, not all i = ind - 1 # Python enumeration starts from 0, not 1 if i < p.nc: dc = p.dc(x, i) elif p.nc <= i < p.nc + p.nh: dc = p.dh(x, i-p.nc) elif p.nc + p.nh <= i < p.nc + p.nh + p.nb: j = i - p.nc - p.nh dc = p.A[j] elif i < p.nc + p.nh + p.nb + p.nbeq: j = i - p.nc - p.nh - p.nb dc = p.Aeq[j] else: p.err('error in connection algencan to openopt') dc = dc.flatten() if any(isnan(dc)): flag = -1 if p.debug: p.warn('algencan: nan in jacobian') indjac, = dc.nonzero() valjac = dc[indjac] nnzjac = indjac.size return indjac,valjac,nnzjac,flag # ****************************************************************** # ****************************************************************** def evalhc(x,ind): pass # """This subroutine might compute the Hessian matrix of the ind-th \ # constraint. # # For achieving this objective YOU MAY MODIFY it according to your # problem. To modify this subroutine IS NOT MANDATORY. See below # where your modifications must be inserted. # # Parameters of the subroutine: # # On Entry: # # x double precision x(n), # current point, # # ind integer, # index of the constraint whose Hessian will be computed, # # On Return # # nnzhc integer, # number of perhaps-non-null elements of the computed # Hessian, # # hclin integer hclin(nnzhc), # see below, # # hccol integer hccol(nnzhc), # see below, # # hcval double precision hcval(nnzhc), # the non-null value of the (hclin(k),hccol(k)) position # of the Hessian matrix of the ind-th constraint must # be saved at hcval(k). Just the lower triangular part of # Hessian matrix must be computed, # # flag integer, # You must set it to any number different of 0 (zero) if # some error ocurred during the evaluation of the Hessian # matrix of the ind-th constraint. (For example, trying # to compute the square root of a negative number, # dividing by zero or a very small number, etc.) If # everything was o.k. you must set it equal to zero. # """ # # n = len(x) # # nnzhc = 1 # # hclin = zeros(nnzhc, int) # hccol = zeros(nnzhc, int) # hcval = zeros(nnzhc, float) # # if ind == 1: # hclin[0] = 0 # hccol[0] = 0 # hcval[0] = 2.0 # # flag = 0 # # elif ind == 2: # nnzhc = 0 # # flag = 0 # # else: # flag = -1 # # return hclin,hccol,hcval,nnzhc,flag # ****************************************************************** # ****************************************************************** def evalhlp(x,m,lambda_,p,goth): pass """This subroutine computes the product of the Hessian of the Lagrangian \ times a vector. This subroutine might compute the product of the Hessian of the Lagrangian times vector p (just the Hessian of the objective function in the unconstrained or bound-constrained case). Parameters of the subroutine: On Entry: x double precision x(n), current point, m integer, number of constraints, lambda double precision lambda(m), vector of Lagrange multipliers, p double precision p(n), vector of the matrix-vector product, goth logical, can be used to indicate if the Hessian matrices were computed at the current point. It is set to .false. by the optimization method every time the current point is modified. Sugestion: if its value is .false. then compute the Hessians, save them in a common structure and set goth to .true.. Otherwise, just use the Hessians saved in the common block structure, On Return hp double precision hp(n), Hessian-vector product, goth logical, see above, flag integer, You must set it to any number different of 0 (zero) if some error ocurred during the evaluation of the Hessian-vector product. (For example, trying to compute the square root of a negative number, dividing by zero or a very small number, etc.) If everything was o.k. you must set it equal to zero. """ # n = len(x) # # hp = zeros(n) # # flag = -1 # # return hp,goth,flag # ****************************************************************** # ****************************************************************** def evalfc(*args, **kwargs): pass def evalgjac(*args, **kwargs): pass def evalhl(*args, **kwargs): pass def endp(x,l,u,m,lambda_,equatn,linear): """This subroutine can be used to do some extra job. This subroutine can be used to do some extra job after the solver has found the solution, like some extra statistics, or to save the solution in some special format or to draw some graphical representation of the solution. If the information given by the solver is enough for you then leave the body of this subroutine empty. Parameters of the subroutine: The parameters of this subroutine are the same parameters of subroutine inip. But in this subroutine there are not output parameter. All the parameters are input parameters. """ p.xk = x.copy() #p.fk = p.f(x) #p.xf = x.copy() #p.ff = p.fk #p.iterfcn() ########################################################################### # solver body param = {'epsfeas': p.contol,'epsopt' : p.gtol,'iprint': 0, 'ncomp':5,'maxtotit' : p.maxIter, 'maxtotfc': p.maxFunEvals} pywrapper.solver(evalf,evalg,evalh,evalc,evaljac,evalhc,evalfc,evalgjac,evalhl, evalhlp,inip,endp,param) if p.istop == 0: p.istop = SMALL_DF p.msg = '|| gradient F(X[k]) || < gtol' #p.iterfcn() openopt-0.38+svn1589/openopt/solvers/CVXOPT/000077500000000000000000000000001175775750500205105ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/solvers/CVXOPT/CVXOPT_LLSP_Solver.py000066400000000000000000000022451175775750500242740ustar00rootroot00000000000000from numpy import asfarray, ones, all, isfinite, copy, nan, concatenate, dot from openopt.kernel.ooMisc import WholeRepr2LinConst, xBounds2Matrix, xBounds2cvxoptMatrix from cvxopt_misc import * import cvxopt.solvers as cvxopt_solvers def CVXOPT_LLSP_Solver(p, solverName): cvxopt_solvers.options['maxiters'] = p.maxIter cvxopt_solvers.options['feastol'] = p.contol cvxopt_solvers.options['abstol'] = p.ftol if p.iprint <= 0: cvxopt_solvers.options['show_progress'] = False cvxopt_solvers.options['MSK_IPAR_LOG'] = 0 xBounds2cvxoptMatrix(p) #f = copy(p.f).reshape(-1,1) #H = sol = cvxopt_solvers.qp(Matrix(p.H), Matrix(p.f), Matrix(p.A), Matrix(p.b), Matrix(p.Aeq), Matrix(p.beq), solverName) p.msg = sol['status'] if p.msg == 'optimal' : p.istop = 1000 else: p.istop = -100 if sol['x'] is not None: p.xf = xf = asfarray(sol['x']).flatten() p.ff = asfarray(0.5*dot(xf, dot(p.H, xf)) + p.dotmult(p.f, xf).sum()).flatten() p.duals = concatenate((asfarray(sol['y']).flatten(), asfarray(sol['z']).flatten())) else: p.ff = nan p.xf = nan*ones(p.n) openopt-0.38+svn1589/openopt/solvers/CVXOPT/CVXOPT_LP_Solver.py000066400000000000000000000063141175775750500240360ustar00rootroot00000000000000from numpy import asarray, ones, all, isfinite, copy, nan, concatenate, array, dot from openopt.kernel.ooMisc import WholeRepr2LinConst, xBounds2Matrix from cvxopt_misc import * import cvxopt.solvers as cvxopt_solvers from cvxopt.base import matrix from openopt.kernel.setDefaultIterFuncs import SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON, IS_MAX_ITER_REACHED, IS_MAX_TIME_REACHED, FAILED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON, UNDEFINED import os def CVXOPT_LP_Solver(p, solverName): #os.close(1); os.close(2) if solverName == 'native_CVXOPT_LP_Solver': solverName = None cvxopt_solvers.options['maxiters'] = p.maxIter cvxopt_solvers.options['feastol'] = p.contol cvxopt_solvers.options['abstol'] = p.ftol if p.iprint <= 0: cvxopt_solvers.options['show_progress'] = False cvxopt_solvers.options['LPX_K_MSGLEV'] = 0 cvxopt_solvers.options['MSK_IPAR_LOG'] = 0 xBounds2Matrix(p) #WholeRepr2LinConst(p) f = copy(p.f).reshape(-1,1) # CVXOPT have some problems with x0 so currently I decided to avoid using the one #if p.x0.size>0 and p.x0.flatten()[0] != None and all(isfinite(p.x0)): # sol= cvxopt_solvers.solvers.lp(Matrix(p.f), Matrix(p.A), Matrix(p.b), Matrix(p.Aeq), Matrix(p.beq), solverName) #else: if (len(p.intVars)>0 or len(p.binVars)>0) and solverName == 'glpk': from cvxopt.glpk import ilp c = Matrix(p.f) A, b = Matrix(p.Aeq), Matrix(p.beq) G, h = Matrix(p.A), Matrix(p.b) if A is None: A = matrix(0.0, (0, p.n)) b = matrix(0.0,(0,1)) if G is None: G = matrix(0.0, (0, p.n)) h = matrix(0.0,(0,1)) (status, x) = ilp(c, G, h, A, b, set(p.intVars), B=set(p.binVars)) if status == 'optimal': p.istop = SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON elif status == 'maxiters exceeded': p.istop = IS_MAX_ITER_REACHED elif status == 'time limit exceeded': p.istop = IS_MAX_TIME_REACHED elif status == 'unknown': p.istop = UNDEFINED else: p.istop = FAILED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON if x is None: p.xf = nan*ones(p.n) else: p.xf = array(x).flatten()#w/o flatten it yields incorrect result in ff! p.ff = sum(p.dotmult(p.f, p.xf)) p.msg = status else: # if len(p.b) != 0: # s0 = matrix(p.b - dot(p.A, p.x0)) # else: # s0 = matrix() # primalstart = {'x': matrix(p.x0), 's': s0} # sol = cvxopt_solvers.lp(Matrix(p.f), Matrix(p.A), Matrix(p.b), Matrix(p.Aeq), Matrix(p.beq), solverName, primalstart) sol = cvxopt_solvers.lp(Matrix(p.f), Matrix(p.A), Matrix(p.b), Matrix(p.Aeq), Matrix(p.beq), solverName) p.msg = sol['status'] if p.msg == 'optimal' : p.istop = SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON else: p.istop = -100 if sol['x'] is not None: p.xf = asarray(sol['x']).flatten() # ! don't involve p.ff - it can be different because of goal and additional constant from FuncDesigner p.duals = concatenate((asarray(sol['y']).flatten(), asarray(sol['z']).flatten())) else: p.ff = nan p.xf = nan*ones(p.n) openopt-0.38+svn1589/openopt/solvers/CVXOPT/CVXOPT_QP_Solver.py000066400000000000000000000023531175775750500240420ustar00rootroot00000000000000from numpy import asfarray, ones, all, isfinite, copy, nan, concatenate, dot from openopt.kernel.ooMisc import WholeRepr2LinConst, xBounds2Matrix from cvxopt_misc import * import cvxopt.solvers as cvxopt_solvers def CVXOPT_QP_Solver(p, solverName): if solverName == 'native_CVXOPT_QP_Solver': solverName = None cvxopt_solvers.options['maxiters'] = p.maxIter cvxopt_solvers.options['feastol'] = p.contol cvxopt_solvers.options['abstol'] = p.ftol cvxopt_solvers.options['reltol'] = 1e-16 if p.iprint <= 0: cvxopt_solvers.options['show_progress'] = False cvxopt_solvers.options['MSK_IPAR_LOG'] = 0 xBounds2Matrix(p) f = copy(p.f).reshape(-1,1) sol = cvxopt_solvers.qp(Matrix(p.H), Matrix(p.f), Matrix(p.A), Matrix(p.b), Matrix(p.Aeq), Matrix(p.beq), solverName) p.msg = sol['status'] if p.msg == 'optimal' : p.istop = 1000 else: p.istop = -100 if sol['x'] is not None: p.xf = xf = asfarray(sol['x']).flatten() p.ff = asfarray(0.5*dot(xf, p.matMultVec(p.H, xf)) + p.dotmult(p.f, xf).sum()).flatten() p.duals = concatenate((asfarray(sol['y']).flatten(), asfarray(sol['z']).flatten())) else: p.ff = nan p.xf = nan*ones(p.n) openopt-0.38+svn1589/openopt/solvers/CVXOPT/CVXOPT_SDP_Solver.py000066400000000000000000000045521175775750500241530ustar00rootroot00000000000000from numpy import asarray, ones, all, isfinite, copy, nan, concatenate, array, asfarray, zeros from openopt.kernel.ooMisc import WholeRepr2LinConst, xBounds2Matrix from cvxopt_misc import * import cvxopt.solvers as cvxopt_solvers from cvxopt.base import matrix from openopt.kernel.setDefaultIterFuncs import SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON, IS_MAX_ITER_REACHED, IS_MAX_TIME_REACHED, FAILED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON, UNDEFINED def converter_to_CVXOPT_SDP_Matrices_from_OO_SDP_Class(OO_SDP_Class_2D_Dict_S, nVars): # nVars can be extracted from OO_SDP_Class_2D_Dict_S but it's easier just to pass as param a = OO_SDP_Class_2D_Dict_S #r = [] R = {} for i, j in a.keys(): if i not in R.keys(): R[i] = zeros((nVars, asarray(a[i, 0]).size)) R[i][j] = asfarray(a[i, j]).flatten() r = [] for i in R.keys(): r.append(Matrix(R[i].T)) return r def DictToList(d): i = 0 r = [] while i in d.keys(): r.append(matrix(d[i], tc = 'd')) i += 1 return r def CVXOPT_SDP_Solver(p, solverName): if solverName == 'native_CVXOPT_SDP_Solver': solverName = None cvxopt_solvers.options['maxiters'] = p.maxIter cvxopt_solvers.options['feastol'] = p.contol cvxopt_solvers.options['abstol'] = p.ftol if p.iprint <= 0: cvxopt_solvers.options['show_progress'] = False cvxopt_solvers.options['LPX_K_MSGLEV'] = 0 #cvxopt_solvers.options['MSK_IPAR_LOG'] = 0 xBounds2Matrix(p) #FIXME: if problem is search for MAXIMUM, not MINIMUM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! f = copy(p.f).reshape(-1,1) # CVXOPT have some problems with x0 so currently I decided to avoid using the one sol = cvxopt_solvers.sdp(Matrix(p.f), Matrix(p.A), Matrix(p.b), \ converter_to_CVXOPT_SDP_Matrices_from_OO_SDP_Class(p.S, p.n), \ DictToList(p.d), Matrix(p.Aeq), Matrix(p.beq), solverName) p.msg = sol['status'] if p.msg == 'optimal' : p.istop = SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON else: p.istop = -100 if sol['x'] is not None: p.xf = asarray(sol['x']).flatten() p.ff = sum(p.dotmult(p.f, p.xf)) #p.duals = concatenate((asarray(sol['y']).flatten(), asarray(sol['z']).flatten())) else: p.ff = nan p.xf = nan*ones(p.n) openopt-0.38+svn1589/openopt/solvers/CVXOPT/CVXOPT_SOCP_Solver.py000066400000000000000000000035531175775750500242710ustar00rootroot00000000000000from numpy import asarray, ones, all, isfinite, copy, nan, concatenate, array, hstack, vstack, atleast_1d from openopt.kernel.ooMisc import WholeRepr2LinConst, xBounds2Matrix #from openopt.kernel.nonOptMisc import Vstack from cvxopt_misc import * import cvxopt.solvers as cvxopt_solvers from cvxopt.base import matrix from openopt.kernel.setDefaultIterFuncs import SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON, IS_MAX_ITER_REACHED, IS_MAX_TIME_REACHED, FAILED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON, UNDEFINED def CVXOPT_SOCP_Solver(p, solverName): if solverName == 'native_CVXOPT_SOCP_Solver': solverName = None cvxopt_solvers.options['maxiters'] = p.maxIter cvxopt_solvers.options['feastol'] = p.contol cvxopt_solvers.options['abstol'] = p.ftol if p.iprint <= 0: cvxopt_solvers.options['show_progress'] = False cvxopt_solvers.options['LPX_K_MSGLEV'] = 0 cvxopt_solvers.options['MSK_IPAR_LOG'] = 0 xBounds2Matrix(p) #FIXME: if problem is search for MAXIMUM, not MINIMUM!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! f = copy(p.f).reshape(-1,1) # CVXOPT has some problems with x0 so currently I decided to avoid using the one Gq, hq = [], [] C, d, q, s = p.C, p.d, p.q, p.s for i in range(len(q)): Gq.append(Matrix(vstack((-atleast_1d(q[i]),-atleast_1d(C[i]))))) hq.append(matrix(hstack((atleast_1d(s[i]), atleast_1d(d[i]))), tc='d')) sol = cvxopt_solvers.socp(Matrix(p.f), Gl=Matrix(p.A), hl = Matrix(p.b), Gq=Gq, hq=hq, A=Matrix(p.Aeq), b=Matrix(p.beq), solver=solverName) p.msg = sol['status'] if p.msg == 'optimal' : p.istop = SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON else: p.istop = -100 if sol['x'] is not None: p.xf = asarray(sol['x']).flatten() p.ff = sum(p.dotmult(p.f, p.xf)) else: p.ff = nan p.xf = nan*ones([p.n,1]) openopt-0.38+svn1589/openopt/solvers/CVXOPT/__init__.py000066400000000000000000000000021175775750500226110ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/solvers/CVXOPT/cvxopt_lp_oo.py000066400000000000000000000010301175775750500235670ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver from CVXOPT_LP_Solver import CVXOPT_LP_Solver class cvxopt_lp(baseSolver): __name__ = 'cvxopt_lp' __license__ = "LGPL" __authors__ = "http://abel.ee.ucla.edu/cvxopt" __alg__ = "see http://abel.ee.ucla.edu/cvxopt" __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub'] properTextOutput = True _canHandleScipySparse = True def __init__(self): pass def __solver__(self, p): return CVXOPT_LP_Solver(p, 'native_CVXOPT_LP_Solver') openopt-0.38+svn1589/openopt/solvers/CVXOPT/cvxopt_misc.py000066400000000000000000000044721175775750500234270ustar00rootroot00000000000000import cvxopt.base from openopt.kernel.ooMisc import Len matrix = cvxopt.base.matrix sparse = cvxopt.base.sparse Sparse = cvxopt.spmatrix from numpy import asfarray, copy, array, prod from openopt.kernel.nonOptMisc import isspmatrix def Matrix(x): if x is None or (hasattr(x, 'shape') and prod(x.shape) == 0): return None if isspmatrix(x): if min(x.shape) > 1: from scipy.sparse import find I, J, values = find(x) return Sparse(array(values, float).tolist(), I.tolist(), J.tolist(), x.shape) else: x = x.toarray() x = asfarray(x) if x.ndim > 1 and x.nonzero()[0].size < 0.3*x.size: #todo: replace 0.3 by prob param return sparse(x.tolist()).T # without tolist currently it doesn't work else: return matrix(x, tc='d') def xBounds2cvxoptMatrix(p): """ transforms lb - ub bounds into (A, x) <= b, (Aeq, x) = beq conditions this func is developed for those solvers that can handle lb, ub only via c(x)<=0, h(x)=0 """ #TODO: is reshape/flatten required in newest numpy versions? indLB, indUB, indEQ = \ where(isfinite(p.lb) & ~(p.lb == p.ub))[0], \ where(isfinite(p.ub) & ~(p.lb == p.ub))[0], \ where(p.lb == p.ub)[0] initLenB = Len(p.b) initLenBeq = Len(p.beq) nLB, nUB, nEQ = Len(indLB), Len(indUB), Len(indEQ) if nLB>0 or nUB>0: A, b = copy(p.A), copy(p.b) p.A = zeros([Len(p.b) + nLB+nUB, p.n]) p.b = zeros(Len(p.b) + nLB+nUB) p.b[:Len(b)] = b.flatten() # sometimes flatten is needed when called before runProbSolver(), from tests p.A[:Len(b)] = A for i in range(len(indLB)): p.A[initLenB+i, indLB[i]] = -1 p.b[initLenB+i] = -p.lb[indLB[i]] for i in range(len(indUB)): p.A[initLenB+len(indLB)+i, indUB[i]] = 1 p.b[initLenB+len(indLB)+i] = p.ub[indUB[i]] if nEQ>0: Aeq, beq = copy(p.Aeq), copy(p.beq) p.Aeq = zeros([Len(p.beq) + nEQ, p.n]) p.beq = zeros(Len(p.beq) + nEQ) p.beq[:Len(beq)] = beq p.Aeq[:Len(beq)] = Aeq for i in range(len(indEQ)): p.Aeq[initLenBeq+i, indEQ[i]] = 1 p.beq[initLenBeq+i] = p.lb[indEQ[i]] # = p.ub[indEQ[i]], because they are the same p.lb = -inf*ones(p.n) p.ub = inf*ones(p.n) openopt-0.38+svn1589/openopt/solvers/CVXOPT/cvxopt_qp_oo.py000066400000000000000000000010301175775750500235740ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver from CVXOPT_QP_Solver import CVXOPT_QP_Solver class cvxopt_qp(baseSolver): __name__ = 'cvxopt_qp' __license__ = "LGPL" __authors__ = "http://abel.ee.ucla.edu/cvxopt" __alg__ = "see http://abel.ee.ucla.edu/cvxopt" __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub'] properTextOutput = True _canHandleScipySparse = True def __init__(self): pass def __solver__(self, p): return CVXOPT_QP_Solver(p, 'native_CVXOPT_QP_Solver') openopt-0.38+svn1589/openopt/solvers/CVXOPT/cvxopt_sdp_oo.py000066400000000000000000000010511175775750500237450ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver from CVXOPT_SDP_Solver import CVXOPT_SDP_Solver class cvxopt_sdp(baseSolver): __name__ = 'cvxopt_sdp' __license__ = "LGPL" __authors__ = "http://abel.ee.ucla.edu/cvxopt" __alg__ = "see http://abel.ee.ucla.edu/cvxopt" __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'S', 'd'] properTextOutput = True _canHandleScipySparse = True def __init__(self): pass def __solver__(self, p): return CVXOPT_SDP_Solver(p, 'native_CVXOPT_SDP_Solver') openopt-0.38+svn1589/openopt/solvers/CVXOPT/cvxopt_socp_oo.py000066400000000000000000000010431175775750500241240ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver from CVXOPT_SOCP_Solver import CVXOPT_SOCP_Solver class cvxopt_socp(baseSolver): __name__ = 'cvxopt_socp' __license__ = "LGPL" __authors__ = "http://abel.ee.ucla.edu/cvxopt" __alg__ = "see http://abel.ee.ucla.edu/cvxopt" __optionalDataThatCanBeHandled__ = ['A','b','Aeq', 'beq', 'lb', 'ub'] properTextOutput = True _canHandleScipySparse = True def __init__(self): pass def __solver__(self, p): return CVXOPT_SOCP_Solver(p, 'native_CVXOPT_SOCP_Solver') openopt-0.38+svn1589/openopt/solvers/CVXOPT/dsdp_oo.py000066400000000000000000000015151175775750500225130ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver from CVXOPT_SDP_Solver import CVXOPT_SDP_Solver class dsdp(baseSolver): __name__ = 'dsdp' __license__ = "GPL" __authors__ = "Steven J. Benson and Yinyu Ye, Mathematics and Computer Science Division, Argonne National Laboratory, IL" __homepage__ = 'http://www-unix.mcs.anl.gov/DSDP/' #__alg__ = "" __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'S', 'd'] gaptol = 1e-5 properTextOutput = True _canHandleScipySparse = True def __init__(self): pass def __solver__(self, p): from cvxopt import solvers solvers.options['DSDP_Monitor'] = p.iprint solvers.options['DSDP_MaxIts'] = p.maxIter solvers.options['DSDP_GapTolerance'] = self.gaptol return CVXOPT_SDP_Solver(p, 'dsdp') openopt-0.38+svn1589/openopt/solvers/CVXOPT/glpk_oo.py000066400000000000000000000011131175775750500225100ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver from CVXOPT_LP_Solver import CVXOPT_LP_Solver class glpk(baseSolver): __name__ = 'glpk' __license__ = "GPL v.2" __authors__ = "http://www.gnu.org/software/glpk + Python bindings from http://abel.ee.ucla.edu/cvxopt" __homepage__ = 'http://www.gnu.org/software/glpk' #__alg__ = "" __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'intVars', 'binVars'] _canHandleScipySparse = True def __init__(self): pass def __solver__(self, p): return CVXOPT_LP_Solver(p, 'glpk') openopt-0.38+svn1589/openopt/solvers/CoinOr/000077500000000000000000000000001175775750500206565ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/solvers/CoinOr/__init__.py000066400000000000000000000000011175775750500227560ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/solvers/CoinOr/cplex_oo.py000066400000000000000000000126041175775750500230430ustar00rootroot00000000000000import sys, numpy as np from openopt.kernel.baseSolver import baseSolver from openopt.kernel.setDefaultIterFuncs import * from openopt.kernel.ooMisc import LinConst2WholeRepr #from openopt.kernel.ooMisc import isSolved #from openopt.kernel.nonOptMisc import scipyInstalled, Hstack, Vstack, Find, isspmatrix import os import cplex as CPLEX from openopt.kernel.setDefaultIterFuncs import SMALL_DELTA_X, SMALL_DELTA_F, IS_NAN_IN_X class cplex(baseSolver): __name__ = 'cplex' __license__ = "free for academic" #__authors__ = '' #__alg__ = "" #__homepage__ = 'http://www.coin-or.org/' #__info__ = "" #__cannotHandleExceptions__ = True __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'intVars', 'H', 'QC'] _canHandleScipySparse = True __isIterPointAlwaysFeasible__ = lambda self, p: p.intVars not in ((), [], None) preprocessor = lambda *args, **kwargs: None #options = '' def __init__(self): pass def __solver__(self, p): for key in (SMALL_DELTA_X, SMALL_DELTA_F, IS_NAN_IN_X): if key in p.kernelIterFuncs: p.kernelIterFuncs.pop(key) # reduce text output # try: # os.close(1); os.close(2) # may not work for non-Unix OS # except: # pass n = p.f.size P = CPLEX.Cplex() P.set_results_stream(None) if np.isfinite(p.maxTime): P.parameters.timelimit.set(p.maxTime) kwargs = {} if hasattr(p, 'intVars') and len(p.intVars)!=0: tmp = np.asarray(['C']*n, dtype=object) for v in p.intVars: tmp[v] = 'I' kwargs['types'] = ''.join(tmp.tolist()) P.variables.add(obj = p.f.tolist(), ub = p.ub.tolist(), lb = p.lb.tolist(), **kwargs) P.objective.set_sense(P.objective.sense.minimize) LinConst2WholeRepr(p) if p.Awhole is not None: m = np.asarray(p.bwhole).size senses = ''.join(where(p.dwhole == -1, 'L', 'E').tolist()) P.linear_constraints.add(rhs=np.asarray(p.bwhole).tolist(), senses = senses) P.linear_constraints.set_coefficients(zip(*Find(p.Awhole))) if p.probType.endswith('QP') or p.probType == 'SOCP': assert p.probType in ('QP', 'QCQP','SOCP') P.objective.set_quadratic_coefficients(zip(*Find(p.H))) if hasattr(p, 'QC'): for q, u, v in p.QC: rows, cols, vals = Find(q) quad_expr = CPLEX.SparseTriple(ind1=rows, ind2=cols, val = vals) #lin_expr = zip(np.arange(np.atleast_1d(u).size), u) lin_expr = CPLEX.SparsePair(ind=np.arange(np.atleast_1d(u).size), val=u) P.quadratic_constraints.add(quad_expr = quad_expr, lin_expr = lin_expr, rhs = -v if isscalar(v) else -asscalar(v)) X = np.nan*np.ones(p.n) if p.intVars in ([], (), None): class ooContinuousCallback(CPLEX.callbacks.ContinuousCallback): def __call__(self): p.iterfcn(X, self.get_objective_value(), self.get_primal_infeasibility()) if p.istop != 0: self.abort() P.register_callback(ooContinuousCallback) else: class ooMIPCallback(CPLEX.callbacks.MIPInfoCallback): def __call__(self): #if not self.aborted: p.iterfcn(X, self.get_best_objective_value(), 0.0) if p.istop != 0: self.abort() P.register_callback(ooMIPCallback) #get_incumbent_values # Temporary walkaround Cplex 12.2.0.0 bug with integers in QP/QCQP P.SOS.get_num() self.preprocessor(P, p) p.extras['CplexProb'] = P P.solve() s = P.solution.get_status() p.msg = 'Cplex status: "%s"; exit code: %d' % (P.solution.get_status_string(), s) try: p.xf = np.asfarray(P.solution.get_values()) p.istop = 1000 except CPLEX.exceptions.CplexError: p.xf = p.x0 * np.nan p.istop = -1 # TODO: replace by normal OOP solution if s == P.solution.status.abort_iteration_limit: p.istop = IS_MAX_ITER_REACHED p.msg = 'Max Iter has been reached' elif s == P.solution.status.abort_obj_limit: p.istop = IS_MAX_FUN_EVALS_REACHED p.msg = 'max objfunc evals limit has been reached' elif s == P.solution.status.abort_time_limit or s == P.solution.status.conflict_abort_time_limit: p.istop = IS_MAX_TIME_REACHED p.msg = 'max time limit has been reached' #class ooContinuousCallback(CPLEX.callbacks.ContinuousCallback): # def __call__(self): # print 'current objective:', self.get_objective_value() # self.p.iterfcn(f=self.get_objective_value()) # if self.p.istop != 0: # cplex.terminate() # return # is "return" nessesary here? def Find(M): if isinstance(M, np.ndarray): # numpy array or matrix rows, cols = np.where(M) vals = M[rows,cols] else: from scipy import sparse as sp assert sp.isspmatrix(M) rows, cols, vals = sp.find(M) return rows.tolist(), cols.tolist(), vals.tolist() openopt-0.38+svn1589/openopt/solvers/CoinOr/ipopt_oo.py000066400000000000000000000154441175775750500230700ustar00rootroot00000000000000from numpy import * import re from openopt.kernel.baseSolver import baseSolver from openopt.kernel.ooMisc import isSolved from openopt.kernel.nonOptMisc import scipyInstalled, Hstack, Vstack, Find, isspmatrix import os #from openopt.kernel.setDefaultIterFuncs import SMALL_DF try: import pyipopt pyipoptInstalled = True except: pyipoptInstalled = False class ipopt(baseSolver): __name__ = 'ipopt' __license__ = "CPL" __authors__ = 'Carl Laird (Carnegie Mellon University) and Andreas Wachter' __alg__ = "A. Wachter and L. T. Biegler, On the Implementation of a Primal-Dual Interior Point Filter Line Search Algorithm for Large-Scale Nonlinear Programming, Mathematical Programming 106(1), pp. 25-57, 2006 " __homepage__ = 'http://www.coin-or.org/' __info__ = "requires pyipopt made by Eric Xu You" __cannotHandleExceptions__ = True __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] _canHandleScipySparse = True # CHECK ME! #__isIterPointAlwaysFeasible__ = lambda self, p: p.__isNoMoreThanBoxBounded__() optFile = 'auto' options = '' def __init__(self): pass def __solver__(self, p): if not pyipoptInstalled: p.err('you should have pyipopt installed') # try: # os.close(1); os.close(2) # may not work for non-Unix OS # except: # pass nvar = p.n x_L = p.lb x_U = p.ub ncon = p.nc + p.nh + p.b.size + p.beq.size g_L, g_U = zeros(ncon), zeros(ncon) g_L[:p.nc] = -inf g_L[p.nc+p.nh:p.nc+p.nh+p.b.size] = -inf # IPOPT non-linear constraints, both eq and ineq if p.isFDmodel: r = [] if p.nc != 0: r.append(p._getPattern(p.user.c)) if p.nh != 0: r.append(p._getPattern(p.user.h)) if p.nb != 0: r.append(p.A) if p.nbeq != 0: r.append(p.Aeq) if len(r)>0: if all([isinstance(elem, ndarray) for elem in r]): r = vstack(r) else: r = Vstack(r) if isspmatrix(r): from scipy import __version__ if __version__.startswith('0.7.3') or __version__.startswith('0.7.2') or __version__.startswith('0.7.1') or __version__.startswith('0.7.0'): p.pWarn('updating scipy to version >= 0.7.4 is very recommended for the problem with the solver IPOPT') else: r = array([]) #if isspmatrix(r): r = r.A # isspmatrix(r) turned off till more proper sparse matrices fancy indexation if isspmatrix(r): I, J, _ = Find(r) # DON'T remove it! I, J = array(I, int64), array(J, int64) elif isinstance(r, ndarray): if r.size == 0: I, J= array([], dtype=int64),array([], dtype=int64) else: I, J = where(r) else: p.disp('unimplemented type:%s' % str(type(r))) # dense matrix? nnzj = len(I) else: I, J = where(ones((ncon, p.n))) #I, J = None, None nnzj = ncon * p.n #TODO: reduce it def eval_g(x): r = array(()) if p.userProvided.c: r = p.c(x) if p.userProvided.h: r = hstack((r, p.h(x))) r = hstack((r, p._get_AX_Less_B_residuals(x), p._get_AeqX_eq_Beq_residuals(x))) return r # def eval_jac_g(x, flag, userdata = None): # r = [] # if p.userProvided.c: r.append(p.dc(x)) # if p.userProvided.h: r.append(p.dh(x)) # if p.nb > 0: p.append(p.A) # if p.nbeq > 0: p.append(p.Aeq) # # if flag: # return where(ones(r.shape)) # else: # return r.flatten() #def eval_jac_g(x, flag, userdata = None): def eval_jac_g(x, flag, userdata = (I, J)): (I, J) = userdata if flag and p.isFDmodel: return (I, J) r = [] if p.userProvided.c: r.append(p.dc(x)) if p.userProvided.h: r.append(p.dh(x)) if p.nb != 0: r.append(p.A) if p.nbeq != 0: r.append(p.Aeq) # TODO: fix it! if any([isspmatrix(elem) for elem in r]): r = Vstack([(atleast_2d(elem) if elem.ndim < 2 else elem) for elem in r]) elif len(r)!=0: r = vstack(r) if p.isFDmodel: # TODO: make it more properly if isspmatrix(r): R = r.tocsr() R = R[I, J] else: R = r[I, J] if isspmatrix(R): return R.A elif isinstance(R, ndarray): return R else: p.err('bug in OpenOpt-ipopt connection, inform OpenOpt developers, type(R) = %s' % type(R)) if flag: #I, J = where(ones(r.shape)) return (I, J) else: if isspmatrix(r): r = r.A return r.flatten() """ This function might be buggy, """ # // comment by Eric nnzh = 0 def eval_h(lagrange, obj_factor, flag): return None # def apply_new(x): # return True nlp = pyipopt.create(nvar, x_L, x_U, ncon, g_L, g_U, nnzj, nnzh, p.f, p.df, eval_g, eval_jac_g) if self.optFile == 'auto': lines = ['# generated automatically by OpenOpt\n','print_level 0\n'] lines.append('tol ' + str(p.ftol)+ '\n') lines.append('constr_viol_tol ' + str(p.contol)+ '\n') lines.append('max_iter ' + str(min(15000, p.maxIter))+ '\n') if self.options != '' : for s in re.split(',|;', self.options): lines.append(s.strip().replace('=', ' ', 1) + '\n') if p.nc == 0: lines.append('jac_d_constant yes\n') if p.nh == 0: lines.append('jac_c_constant yes\n') if p.castFrom.lower() in ('lp', 'qp', 'llsp'): lines.append('hessian_constant yes\n') ipopt_opt_file = open('ipopt.opt', 'w') ipopt_opt_file.writelines(lines) ipopt_opt_file.close() try: x, zl, zu, obj = nlp.solve(p.x0)[:4] if p.point(p.xk).betterThan(p.point(x)): obj = p.fk p.xk = p.xk.copy() # for more safety else: p.xk, p.fk = x.copy(), obj if p.istop == 0: p.istop = 1000 finally: nlp.close() openopt-0.38+svn1589/openopt/solvers/HongKongOpt/000077500000000000000000000000001175775750500216625ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/solvers/HongKongOpt/LCPSolve.py000066400000000000000000000115661175775750500236740ustar00rootroot00000000000000''' LCPSolve(M,q): procedure to solve the linear complementarity problem: w = M z + q w and z >= 0 w'z = 0 The procedure takes the matrix M and vector q as arguments. The procedure has three returns. The first and second returns are the final values of the vectors w and z found by complementary pivoting. The third return is a 2 by 1 vector. Its first component is a 1 if the algorithm was successful, and a 2 if a ray termination resulted. The second component is the value of the artificial variable upon termination of the algorithm. The third component is the number of iterations performed in the outer loop. Derived from: http://www1.american.edu/academic.depts/cas/econ/gaussres/optimize/quadprog.src (original GAUSS code by Rob Dittmar ) Lemke's Complementary Pivot algorithm is used here. For a description, see: http://ioe.engin.umich.edu/people/fac/books/murty/linear_complementarity_webbook/kat2.pdf Copyright (c) 2010 Rob Dittmar, Enzo Michelangeli and IT Vision Ltd Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' from numpy import * def LCPSolve(M,q, pivtol=1e-8): # pivtol = smallest allowable pivot element rayTerm = False loopcount = 0 if (q >= 0.).all(): # Test missing in Rob Dittmar's code # As w - Mz = q, if q >= 0 then w = q and z = 0 w = q z = zeros_like(q) retcode = 0. else: dimen = M.shape[0] # number of rows # Create initial tableau tableau = hstack([eye(dimen), -M, -ones((dimen, 1)), asarray(asmatrix(q).T)]) # Let artificial variable enter the basis basis = range(dimen) # basis contains a set of COLUMN indices in the tableau locat = argmin(tableau[:,2*dimen+1]) # row of minimum element in column 2*dimen+1 (last of tableau) basis[locat] = 2*dimen # replace that choice with the row cand = locat + dimen pivot = tableau[locat,:]/tableau[locat,2*dimen] tableau -= tableau[:,2*dimen:2*dimen+1]*pivot # from each column subtract the column 2*dimen, multiplied by pivot tableau[locat,:] = pivot # set all elements of row locat to pivot # Perform complementary pivoting oldDivideErr = seterr(divide='ignore')['divide'] # suppress warnings or exceptions on zerodivide inside numpy while amax(basis) == 2*dimen: loopcount += 1 eMs = tableau[:,cand] # Note: eMs is a view, not a copy! Do not assign to it... missmask = eMs <= 0. quots = tableau[:,2*dimen+1] / eMs # sometimes eMs elements are zero, but we suppressed warnings... quots[missmask] = Inf # in any event, we set to +Inf elements of quots corresp. to eMs <= 0. locat = argmin(quots) if abs(eMs[locat]) > pivtol and not missmask.all(): # and if at least one element is not missing # reduce tableau pivot = tableau[locat,:]/tableau[locat,cand] tableau -= tableau[:,cand:cand+1]*pivot tableau[locat,:] = pivot oldVar = basis[locat] # New variable enters the basis basis[locat] = cand # Select next candidate for entering the basis if oldVar >= dimen: cand = oldVar - dimen else: cand = oldVar + dimen else: rayTerm = True break seterr(divide=oldDivideErr) # restore original handling of zerodivide in Numpy # Return solution to LCP vars = zeros(2*dimen+1) vars[basis] = tableau[:,2*dimen+1] w = vars[:dimen] z = vars[dimen:2*dimen] retcode = vars[2*dimen] # end if (q >= 0.).all() if rayTerm: retcode = (2, retcode, loopcount) # ray termination else: retcode = (1, retcode, loopcount) # success return (w, z, retcode) openopt-0.38+svn1589/openopt/solvers/HongKongOpt/QPSolve.py000066400000000000000000000132531175775750500235710ustar00rootroot00000000000000''' Copyright (c) 2010 Enzo Michelangeli and IT Vision Ltd Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' from numpy import * from LCPSolve import LCPSolve def QPSolve(Q, e, A=None, b=None, Aeq=None, beq=None, lb=None, ub=None): ''' Note: if lb == None lower bounds are assumed to be -Inf if ub == None upper bounds are assumed to be +Inf i.e., x is NOT assumed to be non-negative by default This quadratic solver works by converting the QP problem into an LCP problem. It does well up to few hundred variables and dense problems (it doesn't take advantage of sparsity). It fails if Aeq is not full row rank, or if Q is singular. ''' nvars = Q.shape[0] # also e.shape[0] # convert lb and ub (if present) into Ax <=> b conditions, but # skip redundant rows: the ones where lb[i] == -Inf or ub[i] == Inf if lb != None: delmask = (lb != -Inf) addA = compress(delmask, eye(nvars), axis=0) addb = compress(delmask, lb, axis=0) A = vstack([A, -addA]) if A != None else -addA b = concatenate([b, -addb]) if b != None else -addb if ub != None: delmask = (ub != Inf) addA = compress(delmask, eye(nvars), axis=0) addb = compress(delmask, ub, axis=0) A = vstack([A, addA]) if A != None else addA b = concatenate([b, addb]) if b != None else addb n_ineq = A.shape[0] #print "nett ineq cons:", n_ineq # if there are equality constraints, it's equiv to particular MLCP that # can anyway be converted to LCP ''' minimize: e' x + 1/2 x' Q x s.t.: A x <= b Aeq x = beq Upper and lower bounds, if presents, are automatically added to (A, b) The Karush-Kuhn-Tucker first-order conditions (being mu and lambda the KKT multipliers) are: (1.1) e + Q x + Aeq' mu + A' lambda = 0 (1.2) Aeq x = beq (1.3) s = b - A x (1.4) s >= 0 (1.5) lambda >= 0 (1.6) s' lambda = 0 lambda are multipliers of inequality constr., mu of equality constr., s are the slack variables for inequalities. This is a MLCP, where s and lambda are complementary. However, we can re-write (1.1) and (1.2) as: | Q Aeq'| * | x | = - | e + A' lambda | |-Aeq 0 | |mu | | beq | ...and, as long as | Q Aeq'| |-Aeq 0 | ...is non-singular (TODO: this should be checked!), we can solve: | x | = inv(| Q Aeq'|) * | -e - A' lambda | |mu | |-Aeq 0 | | -beq | Then, if we define: M = | A 0 | * inv( | Q Aeq'| ) * | A'| |-Aeq 0 | | 0 | q = b + | A 0 | * inv( | Q Aeq'| ) * | e | |-Aeq 0 | | beq | ...(1.3) can be rewritten as an LCP problem in (s, lambda): s = M lambda + q (proof: replace M and q in the eq. above, and simplify remembering that | A'| lmbd == | A' lmbd | , finally reobtaining s = b - Ax ) | 0 | | 0 | Now, as we saw, | Q Aeq'| * | x | = - | e + A' lambda | |-Aeq 0 | |mu | | beq | ...so we can find | x | = inv( | Q Aeq'| ) * - | e + A' lambda | |mu | |-Aeq | | beq | ...and x will be in the first nvar elements of the solution. (we can also verify that b - A x == s) The advantage of having an LCP in lambda and s alone is also greater efficiency (no mu's and x's are calculated by the Lemke solver). Also, x's are not necessarily positive (unlike s's and lambda's), unless there are eplicit A,b conditions about it. However, the matrix inversion does cause a loss of accuracy (which could be estimated through B's condition number: should this value be returned with the status?). ''' if Aeq != None: n_eq = Aeq.shape[0] B = vstack([ hstack([ Q, Aeq.T]), hstack([-Aeq, zeros((n_eq, n_eq))]) ]) A0 = hstack([A, zeros((n_ineq, n_eq))]) else: B = Q A0 = A #print "det(M):", linalg.det(B) #print "B's log10(condition number):", log10(linalg.cond(B)) BI = linalg.inv(B) A0BI = dot(A0, BI) M = dot(A0BI, A0.T) q = b + dot(A0BI, concatenate((e, beq))) if Aeq != None else b + dot(A0BI, e) # LCP: s = M lambda + q, s >= 0, lambda >= 0, s'lambda = 0 # print "M is",M.shape,", q is ",q.shape s, lmbd, retcode = LCPSolve(M,q) if retcode[0] == 1: xmu = dot(BI, -concatenate([e + dot(A.T, lmbd), beq])) if Aeq != None else dot(BI, -(e + dot(A.T, lmbd))) x = xmu[:nvars] else: x = None return (x, retcode) openopt-0.38+svn1589/openopt/solvers/HongKongOpt/QPSparse.py000066400000000000000000000316271175775750500237430ustar00rootroot00000000000000""" pname, e, Q, A=None, b=None, Aeq=None, beq=None, lb=None, ub=None, c0 = MPSparse(filename) Reads the description of a QP problem from a file in the extended MPS format (QPS) described by Istvan Maros and Csaba Meszaros at: http://www.sztaki.hu/~meszaros/public_ftp/qpdata/qpdata.ps Returns a tuple (pname, e, Q, Aeq, beq, lb, ub, c0) name: string all others: numpy arrays QPS Format: The QP problems are assumed to be in the following form: min f(x) = e'x + 1/2 x' Q x, Q symmetric and positive semidefinite subject to Aeq x = beq, l <= x <= u. After the BOUNDS section of MPS there is an new section introduced by a QUADOBJ record followed by columnwise elements of Q; row and columns are column names of A. Being the matrix symmetrical, only lower triangular elements are listed. --------------------------------------------------------------------- Field: 1 2 3 4 5 6 Columns: 2-3 5-12 15-22 25-36 40-47 50-61 0 1 2 3 4 5 6 1234567890123456789012345678901234567890123456789012345678901 << column 11 22222222 33333333 444444444444 55555555 666666666666 << field --------------------------------------------------------------- NAME problem name ROWS type name COLUMNS column row value row value name name name RHS rhs row value row value name name name RANGES range row value row value name name name BOUNDS type bound column value name name ENDATA --------------------------------------------------------------------- --------------------------------------------------------------- NAME QP example ROWS N obj G r1 L r2 COLUMNS 11 22222222 33333333 444444444444 55555555 666666666666 << field c1 r1 2.0 r2 -1.0 c1 obj 1.5 c2 r1 1.0 r2 2.0 c2 obj -2.0 RHS rhs1 r1 2.0 r2 6.0 BOUNDS UP bnd1 c1 20.0 QUADOBJ c1 c1 8.0 c1 c2 2.0 c2 c2 10.0 ENDATA --------------------------------------------------------------- """ from numpy import * def QPSparse(filename): pname = e = Q = A = b = Aeq = beq = lb = ub = None # defaults for ret. params c0 = 0. f = open(filename, 'r') section = None rowtype = {} # dict of row type corresponding to a given row name colnum = {} # dict of col number corresponding to a given col name colcnt = 0 # counter of columns acnt = 0 # counter of inequalities (up to size of A matrix) aeqcnt = 0 # counter of equalities (up to size of Aeq matrix) aindx = {} # dict of row number in A matrix corresponding to a given row name aeqindx = {} # dict of row number in Aeq matrix corresponding to a given row name objcoef = {} # dict of coefficient in obj function corresponding to a given column name RHSdic = {} # dict containing {row_name, RHSvalue} RANGESdic = {} # dict containing {row_name, RANGEvalue} ucnt = 0 qcnt = 0 lineno = 0 for line in f: lineno += 1 line = line.upper().strip("\n\r") f1 = line[1:3].strip() f2 = line[4:12].strip() f3 = line[14:22].strip() f4 = line[24:36].strip().replace('D','E') f4 = 0. if f4 == "" else float(f4) f5 = line[39:47].strip() f6 = line[49:61].strip().replace('D','E') f6 = 0. if f6 == "" else float(f6) if line[0] != ' ': # indicator record, switches current section # see which section is being closed, and take appropriate action if section == 'ROWS': # being closed # we know how many rows we have. Allocate lists of lists for A, Aeq # Alist[n][colname] contains coeff for row n and col name colname in Aeq Alist = [{} for i in range(acnt)] # Aeqlist[n][colname] contains coeff for row n and col name colname in Aeq Aeqlist = [{} for i in range(aeqcnt)] elif section == 'COLUMNS': # being closed # we know how any columns we have (colcnt). So we can now build Q, ub and lb Q = zeros((colcnt,colcnt)) ub = array([Inf]*colcnt) lb = zeros(colcnt) elif section == 'RHS': # being closed pass # b, beq and c0 have been already set up elif section == 'RANGES': # being closed pass # TODO: add ranges elif section == 'BOUNDS': # being closed if ucnt == 0: ub = None elif section == 'QUADOBJ': # being closed if qcnt == 0: Q = None # set the section indicator according to the new section if f1 == 'AM': section = 'NAME' # being opened elif f1 == 'OW': section = 'ROWS' # being opened elif f1 == 'OL': section = 'COLUMNS' # being opened elif f1 == 'HS': section = 'RHS' # being opened elif f1 == 'AN': section = 'RANGES' # being opened elif f1 == 'OU': section = 'BOUNDS' # being opened elif f1 == 'UA': section = 'QUADOBJ' # being opened elif f1 == 'ND': section = None break; else: f.close() raise(ValueError('invalid indicator record in line '+str(lineno)+': "'+line+'"')) elif section == 'NAME': pname = f3 elif section == 'ROWS': rname = f2 if f1 == 'N': rowtype[rname] = 'N' obj = rname elif f1 == 'G': rowtype[rname] = 'G' aindx[rname] = acnt acnt += 1 elif f1 == 'L': rowtype[rname] = 'L' aindx[rname] = acnt acnt += 1 elif f1 == 'E': rowtype[rname] = 'E' aeqindx[rname] = aeqcnt aeqcnt += 1 else: f.close() raise(ValueError('invalid row type "'+f1+'" in line '+str(lineno)+': "'+line+'"')) elif section == 'COLUMNS': cname = f2 rnames = [0,0] vals = [0,0] if cname not in colnum: colnum[cname] = colcnt # alocate a new column number colcnt += 1 rnames[0] = f3 vals[0] = f4 rnames[1] = f5 vals[1] = f6 for i in (0,1): # both are possible rn = rnames[i] value = vals[i] if rn == '': break if rn == obj: # then value is the coefficient of col cname in the obj function objcoef[cname] = value elif rowtype[rn] == 'L': # Alist[aindx[rn]][cname] = value elif rowtype[rn] == 'G': # Alist[aindx[rn]][cname] = -value elif rowtype[rn] == 'E': # Aeqlist[aeqindx[rn]][cname] = value elif section == 'RHS': # What is the RHS name for???? rnames = [0,0] vals = [0,0] rnames[0] = f3 vals[0] = f4 rnames[1] = f5 vals[1] = f6 for i in (0,1): # both are possible rname = rnames[i] value = vals[i] if rname == '': break RHSdic[rname] = value elif section == 'RANGES': # What is the RANGE name for???? rnames = [0,0] vals = [0,0] rnames[0] = f3 vals[0] = f4 rnames[1] = f5 vals[1] = f6 for i in (0,1): # both are possible rname = rnames[i] value = vals[i] if rname == '': break RANGESdic[rname] = value elif section == 'BOUNDS': # by default, x >= 0 # what is the Bound name in f2 for??? # UP : x <= b, x >= 0 # LO : x >= b # FX : x == b # FR : (no bound: remove default >= 0) # MI : x > -Inf # BV : x in (0, 1) # NOT SUPPORTED ic = colnum[f3] val = f4 if f1 == 'UP': ub[ic] = f4 ucnt += 1 elif f1 == 'LO': lb[ic] = f4 elif f1 == 'FX': # TODO add an equality constraint raise(ValueError('fixed variable (FX) bound not supported in line '+str(lineno)+': "'+line+'"')) elif f1 == 'FR': lb[ic] = -Inf ub[ic] = Inf elif f1 == 'MI': lb[ic] = -Inf elif f1 == 'BV': raise(ValueError('binary value (BV) bound not supported in line '+str(lineno)+': "'+line+'"')) elif section == 'QUADOBJ': ic1 = colnum[f2] ic2 = colnum[f3] val = f4 Q[ic1,ic2] = val if ic1 != ic2: # if not on diagonal Q[ic2,ic1] = val qcnt += 1 f.close() if section != None: raise(EOFError('unexpected EOF while in section '+section)) # Now we have all necessary info and we can build A,b,Aeq and Beq if acnt > 0: A = zeros((acnt, colcnt)) b = zeros(acnt) for rn in range(acnt): for c in Alist[rn]: A[rn, colnum[c]] = Alist[rn][c] if aeqcnt > 0: Aeq = zeros((aeqcnt, colcnt)) beq = zeros(aeqcnt) for rn in range(aeqcnt): for c in Aeqlist[rn]: Aeq[rn, colnum[c]] = Aeqlist[rn][c] # ########## process RHS for rname in RHSdic: value = RHSdic[rname] rt = rowtype[rname] if rt == 'L': # b[aindx[rname]] = value # constant term in obj function elif rt == 'G': # b[aindx[rname]] = -value elif rt == 'E': # beq[aeqindx[rname]] = value elif rt == 'N': c0 = -value # constant term in obj function # Handle RANGE lines. Each range causes a duplicate of a # row in A and b, and a modification of original and new b. """ D. The RANGES section is for constraints of the form: h <= constraint <= u . The range of the constraint is r = u - h . The value of r is specified in the RANGES section, and the value of u or h is specified in the RHS section. If b is the value entered in the RHS section, and r is the value entered in the RANGES section, then u and h are thus defined: row type sign of r h u ---------------------------------------------- L + or - b - |r| b G + or - b b + |r| E + b b + |r| E - b - |r| b """ if A != None: addA = zeros((len(RANGESdic),A.shape[1])) addb = zeros(len(RANGESdic)) for rname in RANGESdic: index = aindx[rname] # row index in A and index in b value = RANGESdic[rname] rt = rowtype[rname] if rt == 'L': # b1 = b[index] + abs(value) # sign??? elif rt == 'G': # b1 = b[index] - abs(value) # sign??? elif rt == 'E': # raise(ValueError('RANGES for rows of type E not yet supported in line '+str(lineno)+': "'+line+'"')) #b1 = b[index] - value addA[index,:] = -A[index,:] # append to A duplicate of index row, with sign changed addb[index] = -b1 # append to b other extreme, with sign changed A = vstack([A, addA]) b = concatenate([b, addb]) e = zeros(colcnt) for c in objcoef: e[colnum[c]] = objcoef[c] # suppress redundant lb/ub nvars = e.shape[0] if lb != None and (lb == array([-Inf]*nvars)).all(): lb = None if ub != None and (ub == array([Inf]*nvars)).all(): ub = None return (pname, e, Q, A, b, Aeq, beq, lb, ub, c0) openopt-0.38+svn1589/openopt/solvers/HongKongOpt/__init__.py000066400000000000000000000000001175775750500237610ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/solvers/HongKongOpt/lcpsolve_oo.py000066400000000000000000000015301175775750500245570ustar00rootroot00000000000000from numpy import isfinite, any, hstack from openopt.kernel.baseSolver import * from sqlcp import sqlcp as SQLCP from numpy.linalg import LinAlgError from LCPSolve import LCPSolve class lcpsolve(baseSolver): __name__ = 'lcp' __license__ = "MIT" __authors__ = "Rob Dittmar, Enzo Michelangeli and IT Vision Ltd" __alg__ = "Lemke's Complementary Pivot algorithm" __optionalDataThatCanBeHandled__ = [] #iterfcnConnected = True #_canHandleScipySparse = True __info__ = ''' ''' pivtol = 1e-8 def __init__(self): pass def __solver__(self, p): w, z, retcode = LCPSolve(p.M,p.q, pivtol=self.pivtol) p.xf = hstack((w, z)) if retcode[0] == 1: p.istop = 1000 p.msg = 'success' elif retcode[0] == 2: p.istop = -1000 p.msg = 'ray termination' openopt-0.38+svn1589/openopt/solvers/HongKongOpt/qlcp.py000066400000000000000000000165221175775750500232010ustar00rootroot00000000000000''' Copyright (c) 2010 Enzo Michelangeli and IT Vision Ltd Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' from numpy import * from scipy.linalg import lu_factor, lu_solve from LCPSolve import LCPSolve def qlcp(Q, e, A=None, b=None, Aeq=None, beq=None, lb=None, ub=None, QI=None): ''' Minimizes e'x + 1/2 x'Q x subject to optional inequality, equality and box-bound (converted ti inequality) constraints. Note: x is NOT assumed to be non-negative by default. This quadratic solver works by converting the QP problem into an LCP problem. It does well up to few hundred variables and dense problems (it doesn't take advantage of sparsity). If there are equality constraints, the problem may be feasible even when Q is singular. If Q is not singular, it is possible to precompute its inverse and pass it as parameter QI (this is useful in SQP applications with approximation of the Hessian and its inverse, such as DFP or BFGS. Returns: x, the solution (or None in case of failure due to ray termination in the LCP solver). ''' nvars = Q.shape[0] # also e.shape[0] # convert lb and ub (if present) into Ax <=> b conditions, but # skip redundant rows: the ones where lb[i] == -Inf or ub[i] == Inf if lb != None: delmask = (lb != -Inf) addA = compress(delmask, eye(nvars), axis=0) addb = compress(delmask, lb, axis=0) A = vstack([A, -addA]) if A != None else -addA b = concatenate([b, -addb]) if b != None else -addb if ub != None: delmask = (ub != Inf) addA = compress(delmask, eye(nvars), axis=0) addb = compress(delmask, ub, axis=0) A = vstack([A, addA]) if A != None else addA b = concatenate([b, addb]) if b != None else addb n_ineq = A.shape[0] if A != None else 0 #print "nett ineq cons:", n_ineq # if there are equality constraints, it's equiv to particular MLCP that # can anyway be converted to LCP ''' The Karush-Kuhn-Tucker first-order conditions (being mu and lambda the KKT multipliers) are: (1.1) e + Q x + Aeq' mu + A' lambda = 0 (1.2) Aeq x = beq (1.3) s = b - A x (1.4) s >= 0 (1.5) lambda >= 0 (1.6) s' lambda = 0 lambda are the multipliers of inequality constr., mu of equality constr., and s are the slack variables for inequalities. This is a MLCP, where s and lambda are complementary. However, we can re-write (1.1) and (1.2) as: | Q Aeq'| * | x | = - | e + A' lambda | |-Aeq 0 | |mu | | beq | ...and, as long as | Q Aeq'| |-Aeq 0 | ...(in the program called B) is non-singular, we can solve: | x | = inv(| Q Aeq'|) * | -e - A' lambda | |mu | |-Aeq 0 | | -beq | Then, if we define: M = | A 0 | * inv( | Q Aeq'| ) * | A'| |-Aeq 0 | | 0 | q = b + | A 0 | * inv( | Q Aeq'| ) * | e | |-Aeq 0 | | beq | ...(1.3) can be rewritten as an LCP problem in (s, lambda): s = M lambda + q (proof: replace M and q in the eq. above, and simplify remembering that | A'| lmbd == | A' lmbd | , finally reobtaining s = b - Ax ) | 0 | | 0 | Now, as we saw, | Q Aeq'| * | x | = - | e + A' lambda | |-Aeq 0 | |mu | | beq | ...so we can find | x | = inv( | Q Aeq'| ) * - | e + A' lambda | |mu | |-Aeq | | beq | ...and x will be in the first nvar elements of the solution. (we can also verify that b - A x == s) The advantage of having an LCP in lambda and s alone is also greater efficiency trough reduction of dimensionality (no mu's and x's are calculated by the Lemke solver). Also, x's are not necessarily positive (unlike s's and lambda's), unless there are eplicit A,b conditions about it. However, the matrix inversion does cause a loss of accuracy(which could be estimated through B's condition number: should this value be returned with the status?). ''' if Aeq != None: n_eq = Aeq.shape[0] B = vstack([ hstack([ Q, Aeq.T]), hstack([-Aeq, zeros((n_eq, n_eq))]) ]) A0 = hstack([A, zeros((n_ineq, n_eq))]) if A != None else None else: B = Q A0 = A #print "det(B):", linalg.det(B) #print "B's log10(condition number):", log10(linalg.cond(B)) ee = concatenate((e, beq)) if Aeq != None else e if A == None: # if no ineq constraints, no need of LCP: just solve a linear system xmu = linalg.solve(B, ee) x = xmu[:nvars] else: # ve have to compute B's inverse, possibly using Q's inverse (if passed as parameter) if QI == None: # Even when Q is singular, B might not be, as long as the Eq. Constr. define a suitable subspace BI = linalg.inv(B) else: # the inverse of Q was precomputed and passed by the caller (which requires Q not to be singular!) if Aeq == None: BI = QI else: # Use formula (1) at http://www.csd.uwo.ca/~watt/pub/reprints/2006-mc-bminv-poster.pdf # This is applicable only as long as Q and Aeq.T * Q * Aeq are not singular (i.e., # Q not singular and Aeq full row rank). QIAeqT = dot(QI,Aeq.T) SQI = linalg.inv(dot(Aeq, QIAeqT)) # inverse of Shur's complement of Q in B QIAeqTSQI = dot(QIAeqT,SQI) BI = vstack([ hstack([QI-dot(dot(QIAeqTSQI,Aeq),QI), -QIAeqTSQI]), hstack([dot(SQI,dot(Aeq,QI)), SQI]), ]) A0BI = dot(A0, BI) M = dot(A0BI, A0.T) q = b + dot(A0BI, ee) # LCP: s = M lambda + q, s >= 0, lambda >= 0, s'lambda = 0 # print "M is",M.shape,", q is ",q.shape s, lmbd, retcode = LCPSolve(M,q) if retcode[0] == 1: # xmu = dot(BI, -concatenate([e + dot(A.T, lmbd), beq])) if Aeq != None else dot(BI, -(e + dot(A.T, lmbd))) kk = -concatenate([e + dot(A.T, lmbd), beq]) if Aeq != None else -(e + dot(A.T, lmbd)) xmu = dot(BI, kk) x = xmu[:nvars] else: x = None return x openopt-0.38+svn1589/openopt/solvers/HongKongOpt/qlcp_oo.py000066400000000000000000000014631175775750500236740ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver from QPSolve import QPSolve class qlcp(baseSolver): __license__ = "MIT" __authors__ = "Enzo Michelangeli" #_requiresBestPointDetection = True __name__ = 'qlcp' __alg__ = 'Lemke algorithm, using linear complementarity problem' #__isIterPointAlwaysFeasible__ = True __optionalDataThatCanBeHandled__ = ['lb', 'ub', 'A', 'b', 'Aeq', 'beq'] def __init__(self): pass def __solver__(self, p): # TODO: add QI x, retcode = QPSolve(p.H, p.f, p.A, p.b, p.Aeq, p.beq, p.lb, p.ub) #Q, e, A=None, b=None, Aeq=None, beq=None, lb=None, ub=None, QI=None if retcode[0] == 1: p.istop = 1000 p.xf = x else: p.istop = -1 # TODO: istop, msg wrt retcode openopt-0.38+svn1589/openopt/solvers/HongKongOpt/sqlcp.py000066400000000000000000000142351175775750500233630ustar00rootroot00000000000000''' Copyright (c) 2010 Enzo Michelangeli and IT Vision Ltd Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ''' from numpy import * from qlcp import qlcp try: import openopt except: pass # if OpenOpt is not installed, the qpsolver kwarg can't be specified def _simple_grad(f, x, delta = 1e-8): nvars = x.shape[0] Id = eye(nvars)*delta grad = array([(f(x+Id[i,:]) - f(x-Id[i,:]))/(2*delta) for i in range(nvars)]) return grad def _simple_hessian(f, x, delta = 1e-4): # generally too slow for use g = lambda x: _simple_grad(f, x, delta = delta) # g(x) is the gradient of f return _simple_grad(g, x, delta=delta) def _simple_hessdiag(f, x, delta = 1e-4): nvars = x.shape[0] Id = eye(nvars)*delta hd = array([(f(x+Id[i,:]) + f(x-Id[i,:]) - 2*f(x))/delta**2 for i in range(nvars)]).flatten() return diag(hd) def sqlcp(f, x0, df=None, A=None, b=None, Aeq=None, beq=None, lb=None, ub=None, minstep=1e-15, minfchg=1e-15, qpsolver=None, callback = None): ''' SQP solver. Approximates f in x0 with paraboloid with same gradient and hessian, then finds its minimum with a quadratic solver (qlcp by default) and uses it as new point, iterating till changes in x and/or f drop below given limits. Requires the Hessian to be definite positive. The Hessian is initially approximated by its principal diagonal, and then updated at every step with the BFGS method. f: objective function of x to be minimized x0: initial value for f df: gradient of f: df(f) should return a function of such as f(x) would return the gradient of f in x. If missing or None, an approximation will be calculated with an internal finite-differences procedure. A: array of inequality constraints (A x >= b) b: right-hand side of A x >= b Aeq: array of equality constraints (Aeq x = beq) beq: right-hand side of Aeq x >= beq lb: lower bounds for x (assumed -Inf if missing) ub: upper bounds for x (assumed +Inf if missing) minstep: iterations terminate when updates to x become < minstep (default: 1e-15) minfchg: iterations terminate when RELATIVE changes in f become < minfchg (default: 1e-15) qpsolver: if None, qlcp; else a solver accepted by openopt.QP (if OpenOpt and that particular solver are installed) ''' nvars = x0.shape[0] x = x0.copy() niter = 0 deltah = 1e-4 deltag = deltah**2 if df == None: # df(x) is the gradient of f in x df = lambda x: _simple_grad(f, x, deltag) twoI = 2.*eye(nvars) oldfx = f(x) gradfx = df(x) # return the gradient of f() at x hessfx = _simple_hessdiag(f,x,delta=deltah) # good enough, and much faster, but only works if REAL Hessian is DP! invhessfx = linalg.inv(hessfx) while True: niter += 1 # compute the b, beq, lb and ub for the QP sub-problem (as bx, beqx, lbx, ubx) bx = b if b == None else b-dot(A,x) beqx = beq if beq == None else beq-dot(Aeq,x) lbx = lb if lb == None else lb - x ubx = ub if ub == None else ub - x if qpsolver == None: deltax = qlcp(hessfx, gradfx, A=A, b=bx, Aeq=Aeq, beq=beqx, lb=lbx, ub=ubx, QI=invhessfx) else: p = openopt.QP(hessfx, gradfx, A=A, b=bx, Aeq=Aeq, beq=beqx, lb=lbx, ub=ubx) p.ftol = 1.e-10 r = p.solve(qpsolver, iprint = -1) deltax = p.xf if deltax == None: #print("Cannot converge, sorry.") x = None break x += deltax if linalg.norm(deltax) < minstep: break fx = f(x) if abs(fx-oldfx) < minfchg*abs(fx): break if callback is not None and callback(x): break oldfx = fx oldgradfx = gradfx.copy() gradfx = df(x) # return the gradient of f() at the new x # we might also put a termination test on the norm of grad... ''' # recalc hessian afresh would be sloooow... #hessfx = _simple_hessian(f,x,delta=deltah) # return the hessian of f() at x hessfx = _simple_hessdiag(f,x,delta=deltah) # return the hessian (diag only) of f() at x invhessfx = linalg.inv(hessfx) ''' # update Hessian and its inverse with BFGS based on current Hessian, deltax and deltagrad # See http://en.wikipedia.org/wiki/BFGS deltagrad = gradfx - oldgradfx hdx = dot(hessfx, deltax) dgdx = dot(deltagrad,deltax) #if dgdx < 0.: # print "deltagrad * deltax < 0!" # a bad sign hessfx += ( outer(deltagrad,deltagrad) / dgdx - outer(hdx, hdx) / dot(deltax, hdx) ) # now update inverse of Hessian ''' invhessfx = linalg.inv(hessfx) ''' hidg = dot(invhessfx,deltagrad) oIdgdeltax = outer(hidg,deltax) invhessfx += ( (dgdx+dot(deltagrad,hidg))*outer(deltax,deltax)/(dgdx**2) - (oIdgdeltax+oIdgdeltax.T)/dgdx ) # just because invhessfx is symmetric, or else: #(oIdgdeltax+outer(deltax,dot(invhessfx.T,deltagrad)))/dgdx ) return x, niter openopt-0.38+svn1589/openopt/solvers/HongKongOpt/sqlcp_oo.py000066400000000000000000000035571175775750500240650ustar00rootroot00000000000000from numpy import isfinite, any from openopt.kernel.baseSolver import * from sqlcp import sqlcp as SQLCP from numpy.linalg import LinAlgError class sqlcp(baseSolver): __name__ = 'sqlcp' __license__ = "MIT" __authors__ = "Enzo Michelangeli" __alg__ = "an SQP implementation" __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub'] iterfcnConnected = True #_canHandleScipySparse = True QPsolver=None __info__ = '''SQP solver. Approximates f in x0 with paraboloid with same gradient and hessian, then finds its minimum with a quadratic solver (qlcp by default) and uses it as new point, iterating till changes in x and/or f drop below given limits. Requires the Hessian to be definite positive. The Hessian is initially approximated by its principal diagonal, and then updated at every step with the BFGS method. By default it uses QP solver qlcp (license: MIT), however, latter uses LCP solver LCPSolve, that is "free for education" for now. You can use other QP solver via "oosolver('sqlcp', QPsolver='cvxopt_qp')" or any other, including converters. Copyright (c) 2010 Enzo Michelangeli and IT Vision Ltd ''' def __init__(self): pass def __solver__(self, p): (A, b) = (p.A, p.b) if p.nb else (None, None) (Aeq, beq) = (p.Aeq, p.beq) if p.nbeq else (None, None) lb = p.lb if any(isfinite(p.lb)) else None ub = p.ub if any(isfinite(p.ub)) else None def callback(x): p.iterfcn(x) return True if p.istop else False try: SQLCP(p.f, p.x0, df=p.df, A=A , b=b, Aeq=Aeq, beq=beq, lb=p.lb, ub=p.ub, minstep=p.xtol, minfchg=1e-15, qpsolver=self.QPsolver, callback = callback) except LinAlgError: p.msg = 'linalg error, probably failed to invert Hesse matrix' p.istop = -100 openopt-0.38+svn1589/openopt/solvers/Standalone/000077500000000000000000000000001175775750500215555ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/solvers/Standalone/__init__.py000066400000000000000000000000021175775750500236560ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/solvers/Standalone/arpack_oo.py000066400000000000000000000021201175775750500240600ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver from openopt.kernel.nonOptMisc import Vstack from scipy.sparse.linalg import eigs #from nonOptMisc import Hstack class arpack(baseSolver): __name__ = 'arpack' __license__ = "BSD" __authors__ = '' __alg__ = '' __info__ = """ """ __optionalDataThatCanBeHandled__ = ['M'] _canHandleScipySparse = True #def __init__(self): pass def __solver__(self, p): A = p.C M = p.M if p._goal == 'all': p.err('You should change prob "goal" argument, solver arpack can search at most n-2 eigenvectors') if p.N > A.shape[0] - 2: p.err('solver arpack can find at most n-2 eigenvalues, where n is height of matrix') eigenvalues, eigenvectors = \ eigs(A, k=p.N, M=M, sigma=None, which='LM', v0=None, ncv=None, maxiter=None, \ tol=p.xtol, return_eigenvectors=True) p.xf = p.xk = Vstack((eigenvalues, eigenvectors)) p.eigenvalues = eigenvalues p.eigenvectors = eigenvectors p.ff = 0 openopt-0.38+svn1589/openopt/solvers/Standalone/branb_oo.py000066400000000000000000000122171175775750500237130ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver from openopt.kernel.ooMisc import isSolved from openopt.kernel.setDefaultIterFuncs import IS_NAN_IN_X, SMALL_DELTA_X, SMALL_DELTA_F #from numpy import asarray, inf, ones, nan from numpy import * #import openopt from openopt import NLP, OpenOptException class branb(baseSolver): __name__ = 'branb' __license__ = "BSD" __authors__ = "Ingar Solberg, Institutt for teknisk kybernetikk, Norges Tekniske Hrgskole, Norway, translated to Python by Dmitrey" __homepage__ = '' __alg__ = "branch-and-cut (currently the implementation is quite primitive)" __info__ = '' __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'discreteVars', 'c', 'h'] iterfcnConnected = True __isIterPointAlwaysFeasible__ = lambda self, p: True #eps = 1e-7 nlpSolver = None def __init__(self): pass def __solver__(self, p): if self.nlpSolver is None: p.err('you should explicitely provide parameter nlpSolver (name of NLP solver to use for NLP subproblems)') # TODO: check it # it can be removed in other place during prob preparation for key in [IS_NAN_IN_X, SMALL_DELTA_X, SMALL_DELTA_F]: if key in p.kernelIterFuncs.keys(): p.kernelIterFuncs.pop(key) p.nlpSolver = self.nlpSolver startPoint = p.point(p.x0) startPoint._f = inf fPoint = fminconset(p, startPoint, p) p.iterfcn(fPoint) p.istop = 1000 def fminconset(p_current, bestPoint, p): p2 = milpTransfer(p) p2.lb, p2.ub = p_current.lb, p_current.ub try: r = p2.solve(p.nlpSolver) curr_NLP_Point = p.point(r.xf) curr_NLP_Point._f = r.ff except OpenOptException: r = None resultPoint = p.point(bestPoint.x) if r is None or r.istop <0 or curr_NLP_Point.f() >= bestPoint.f(): resultPoint._f = inf return resultPoint elif r.istop == 0: pass# TODO: fix it # check if all discrete constraints are satisfied x = curr_NLP_Point.x k = -1 for i in p.discreteVars.keys():#range(m): # check x-vector # TODO: replace it by "for i, val in dict.itervalues()" if not any(abs(x[i] - p.discreteVars[i]) < p.discrtol): k=i # Violation of this set constraint. break # Go and split for this x-component if k != -1: # some discrete constraint violated => recursive search is required p.debugmsg('k='+str(k)+' x[k]=' + str(x[k]) + ' p.discreteVars[k]=' +str(p.discreteVars[k])) Above=where(p.discreteVars[k]>x[k])[0] Below=where(p.discreteVars[k]100000: s = """You have no scipy installed . Thus the SLE will be solved as dense. """ p.pWarn(s) solver = self.defaultDenseSolver self.matrixSLEsolver = solver else: solver = self.defaultSparseSolver self.matrixSLEsolver = solver useDense = False else: p.err('Incorrect SLE solver (%s)' % solver) if isinstance(solver, str): if solver == 'numpy_linalg_solve': solver = linalg.solve else: solver = getattr(scipy.sparse.linalg, solver) if useDense: #p.debugmsg('dense SLE solver') try: C = p.C.toarray() if not isinstance(p.C, ndarray) else p.C if self.matrixSLEsolver == 'autoselect': self.matrixSLEsolver = linalg.solve xf = solver(C, p.d) istop, msg = 10, 'solved' p.xf = xf p.ff = norm(dot(C, xf)-p.d, inf) except linalg.LinAlgError: istop, msg = -10, 'singular matrix' else: # is sparse #p.debugmsg('sparse SLE solver') try: if not hasattr(p, 'C_as_csc'):p.C_as_csc = scipy.sparse.csc_matrix(p.C) xf = solver(p.C_as_csc, p.d)#, maxiter=10000) solver_istop = 0 if solver_istop == 0: istop, msg = 10, 'solved' else: istop, msg = -104, 'the solver involved failed to solve the SLE' if solver_istop < 0: msg += ', matter: illegal input or breakdown' else: msg += ', matter: convergence to tolerance not achieved, number of iterations: %d' % solver_istop p.xf = xf p.ff = norm(p.C_as_csc._mul_sparse_matrix(scipy.sparse.csr_matrix(xf.reshape(-1, 1))).toarray().flatten()-p.d, inf) except: istop, msg = -100, 'unimplemented exception while solving sparse SLE' p.istop, p.msg = istop, msg openopt-0.38+svn1589/openopt/solvers/Standalone/galileo_oo.py000066400000000000000000000406521175775750500242470ustar00rootroot00000000000000#from numpy import asfarray, argmax, sign, inf, log10 from openopt.kernel.baseSolver import baseSolver from numpy import asfarray, inf, atleast_1d from openopt.kernel.setDefaultIterFuncs import SMALL_DELTA_X, SMALL_DELTA_F class galileo(baseSolver): __name__ = 'galileo' __license__ = "GPL" __authors__ = 'Donald Goodman, dgoodman-at-cs.msstate.edu, connected to OO by Dmitrey' __alg__ = "Genetic Algorithm, same as ga2, the C++ canonical genetic algorithm lib, also by Donald Goodman" iterfcnConnected = True __homepage__ = 'http://www.cs.msstate.edu/~dgoodman' __info__ = """ requires finite lb, ub: lb <= x <= ub """ __optionalDataThatCanBeHandled__ = ['lb', 'ub'] __isIterPointAlwaysFeasible__ = lambda self, p: True population = 15 crossoverRate = 1.0 # 1.0 means always mutationRate = 0.05 # not very often useInteger = False # use float by default _requiresFiniteBoxBounds = True def __init__(self):pass def __solver__(self, p): p.kernelIterFuncs.pop(SMALL_DELTA_X) p.kernelIterFuncs.pop(SMALL_DELTA_F) p.ff = inf #create an initial population of 10 chromosomes P = Population(self.population)# CHECKME! is the Population size optimal? #use fitness as our evaluation function P.evalFunc = lambda x: -p.f(x) # fitness #minimum values the genes can take P.chromoMinValues = p.lb.tolist() #maximum values the genes can take P.chromoMaxValues = p.ub.tolist() #use integers instead of floats P.useInteger = self.useInteger #crossover P.crossoverRate = self.crossoverRate #mutate, but not very often P.mutationRate = self.mutationRate #use roulette (monte carlo) selection P.selectFunc = P.select_Roulette #use a full replacement size P.replacementSize = P.numChromosomes #use one point crossover P.crossoverFunc = P.crossover_OnePoint #use the default mutation routines P.mutateFunc = P.mutate_Default #use steady-state replacement with no duplication P.replaceFunc = P.replace_SteadyStateNoDuplicates #finish initializing the population. THIS MUST BE CALLED after settings the #variables above, but before actually running the GA! P.prepPopulation() #for 50 epochs for itn in range(p.maxIter+1): #evaluate each chromosomes P.evaluate() #apply selection P.select() #apply crossover P.crossover() #apply mutation P.mutate() #apply replacement P.replace() #print the best fit individual, and its fitness fval = asfarray(-P.maxFitness) if p.ff > fval: p.xf, p.ff = asfarray(P.bestFitIndividual.genes), fval p.iterfcn(asfarray(P.bestFitIndividual.genes), fval) if p.istop: #p.xk, p.fk = p.xf, p.ff return from random import Random class Chromosome: """The Chromosome class represents a single chromosome in a population. A Chromosome contains some number of genes (Python objects), and can be treated as a list, with indices and slices and all that good stuff """ def __init__(self): """Constructs a new Chromosome instance""" self.genes = [] self.geneMaxValues = [] self.geneMinValues = [] self.fitness = None self.evalFunc = None self.parent = None def __str__(self): return self.genes.__str__() def randomInit(self, generator, intValues = 1): """Randomly initializes all genes within the ranges set with setMinValues and setMaxValues. generator should be an instance of Random from the random module. Doing things this way allows for thread safety. If intValues is set to 1, random integers will be created, else random floating point values will be generated. """ #first, are the lists empty? minlen = len(self.geneMinValues) maxlen = len(self.geneMaxValues) if (minlen == 0) or (minlen != maxlen): return randFunc = None if intValues == 1: randFunc = generator.randint else: randFunc = generator.uniform self.genes = [] for i in range(minlen): self.genes.append(randFunc(self.geneMinValues[i], self.geneMaxValues[i])) self.fitness = None def evaluate(self): """Calls evalFunc for this chromosome, and caches the fitness value returned. Returns None if evalFunc is not yet defined. """ if self.evalFunc != None: self.fitness = self.evalFunc(self.genes) return self.fitness else: return None def getFitness(self): """Calls evaluate if there is no cached value, otherwise returns the cached fitness value. """ if self.fitness != None: return self.fitness else: return self.evaluate() def copy(self): """Duplicates the chromosome. """ retval = Chromosome() for item in self.__dict__: retval.__dict__[item] = self.__dict__[item] return retval def __len__(self): return len(self.genes) def __getitem__(self, key): retval = self.copy() retval.genes = [self.genes[key]] retval.geneMinValues = [self.geneMinValues[key]] retval.geneMaxValues = [self.geneMaxValues[key]] retval.fitness = None return retval def __setitem__(self, key, value): return self.genes.__setitem__(key, value) def __getslice__(self, i, j): retval = self.copy() retval.genes = self.genes[i:j] retval.geneMinValues = self.geneMinValues[i:j] retval.geneMaxValues = self.geneMaxValues[i:j] retval.fitness = None return retval return self.genes.__getslice__(i, j) def __contains__(self, item): return self.genes.__contains__(item) def __add__(self, other): retval = self.copy() retval.genes = self.genes + other.genes retval.geneMinValues = self.geneMinValues + other.geneMinValues retval.geneMaxValues = self.geneMaxValues + other.geneMaxValues retval.fitness = None return retval def __cmp__(self, other): s1 = self.getFitness() s2 = other.getFitness() return s1-s2 def isIdentical(self, other): """If the genes in self and other are identical, returns 0 """ return (self.genes == other.genes) class Population: """The Population class represents an entire population of a single generation of Chromosomes. This population is replaced with each iteration of the algorithm. Functions are provided for storing generations for later analysis or retrieval, or for reloading the population from some point. All of the high level functionality is in this class: generally speaking, you will almost never call a function from any of the other classes. """ def __init__(self, numChromosomes): """Constructs a population of chromosomes, with numChromosomes as the size of the population. Note that prepPopulation must also be called after all user defined variables have been set, to finish initialization. """ self.numChromosomes = numChromosomes self.currentGeneration = [] self.nextGeneration = [] self.chromoMaxValues = [] self.chromoMinValues = [] self.mutationRate = 0.0 self.crossoverRate = 0.0 self.replacementSize = 0 self.useInteger = 0 self.isSorted = 0 self.crossoverCount = 0 self.mutationCount = 0 self.evalFunc = None self.mutateFunc = None self.selectFunc = None self.crossoverFunc = None self.replaceFunc = None self.generator = Random() self.minFitness = None self.maxFitness = None self.avgFitness = None self.sumFitness = None self.bestFitIndividual = None def prepPopulation(self): """Radnomly initializes each chromosome according to the values in chromosMinValues and chromosMaxValues. """ if (len(self.chromoMinValues) != len(self.chromoMaxValues)) or (len(self.chromoMinValues) == 0): return None self.currentGeneration = [] for i in range(self.numChromosomes): c = Chromosome() c.geneMinValues = self.chromoMinValues c.geneMaxValues = self.chromoMaxValues c.randomInit(self.generator, self.useInteger) c.evalFunc = self.evalFunc self.currentGeneration.append(c) return 1 def evaluate(self): """Evaluates each chromosome. Since fitness values are cached, don't hesistate to call many times. Also calculates sumFitness, avgFitness, maxFitness, minFitness, and finds bestFitIndividual, for your convienence. Be sure to assign an evalFunc """ self.sumFitness = 0.0 self.avgFitness = 0.0 self.maxFitness = self.currentGeneration[0].getFitness() self.minFitness = self.currentGeneration[0].getFitness() self.bestFitIndividual = self.currentGeneration[0] for chromo in self.currentGeneration: f = chromo.getFitness() self.sumFitness = self.sumFitness + f if f > self.maxFitness: self.maxFitness = f self.bestFitIndividual = chromo elif f < self.minFitness: self.minFitness = f self.avgFitness = self.sumFitness/len(self.currentGeneration) def mutate(self): """At probability mutationRate, mutates each gene of each chromosome. That is, each gene has a mutationRate chance of being randomly re-initialized. Right now, only mutate_Default is available for assignment to mutateFunc. """ self.mutationCount = 0 for i in range(self.replacementSize): self.nextGeneration[i] = self.mutateFunc(self.nextGeneration[i]) def select(self): """Selects chromosomes from currentGeneration for placement into nextGeneration based on selectFunc. """ self.nextGeneration = [] for i in range(0, self.replacementSize, 2): s1 = self.selectFunc() s2 = self.selectFunc() s1.parent = (s1, s1) s2.parent = (s2, s2) self.nextGeneration.append(s1) self.nextGeneration.append(s2) def crossover(self): """Performs crossover on pairs of chromos in nextGeneration with probability crossoverRate. Calls crossoverFunc, which must be set; current choices are crossover_OnePoint, crossover_TwoPoint and crossover_Uniform. """ self.crossCount = 0 for i in range(0, self.replacementSize, 2): (a,b) = self.crossoverFunc(self.nextGeneration[i], self.nextGeneration[i+1]) (self.nextGeneration[i],self.nextGeneration[i+1]) = (a,b) def replace(self): """Replaces currentGeneration with nextGeneration according to the rules set forth in replaceFunc. Right now, replaceFunc can take the values of replace_SteadyState, replace_SteadyStateNoDuplicates and replace_Generational. """ return self.replaceFunc() def select_Roulette(self): """Perform Roulette (Monte Carlo) selection. Assign this function to selectFunc to use. In essence, we construct a big roulette wheel, with a slot for each individual. The size of each slot is proportional to the relative fitness of that individual. The wheel is then spun! whee! The more fit individuals have a greater chance of landing under the pointer. The individual that lands under the pointer is returned. """ partialSum = 0.0 #spin the wheel!! wheelPosition = self.generator.uniform(0, self.sumFitness) i = 0 for chromo in self.currentGeneration: partialSum = partialSum + chromo.getFitness() if partialSum >= wheelPosition: return chromo i = i + 1 return self.currentGeneration[-1] def select_Ranked(self): """Currently does nothing. Hrm. """ return None def crossover_OnePoint(self, chromo1, chromo2): """A crossover function that can be assigned to crossoverFunc. This one takes two chromosomes, cuts them at some random point, and swaps the parts creating two new chromosomes, which are returned in a tuple. Note that there is only a crossoverRate chance of crossover happening. """ prob = self.generator.random() if prob <= self.crossoverRate: self.crossoverCount = self.crossoverCount + 1 cutPoint = self.generator.randint(0, len(chromo1)-1) newchromo1 = chromo1[:cutPoint]+chromo2[cutPoint:] newchromo2 = chromo2[:cutPoint]+chromo1[cutPoint:] return (newchromo1, newchromo2) else: return (chromo1, chromo2) """A crossover function that can be assigned to crossoverFunc. This one takes two chromosomes, cuts them at two random points (creating three parts for each chromosomes), and swaps the parts around, creating two new chromosomes, which are returned in a tuple. Note that there is only a crossoverRate chance of crossover happening. """ prob = self.generator.random() if prob <= self.crossoverRate: self.crossoverCount = self.crossoverCount + 1 cutPoint1 = self.generator.randint(0, len(chromo1)-1) cutPoint2 = self.generator.randint(1, len(chromo1)) if cutPoint2 < cutPoint1: temp = cutPoint1 cutPoint1 = cutPoint2 cutPoint2 = temp newchromo1 = chromo1[:cutPoint1]+chromo2[cutPoint1:cutPoint2]+chromo1[cutPoint2:] newchromo2 = chromo2[:cutPoint1]+chromo1[cutPoint1:cutPoint2]+chromo2[cutPoint2:] return (newchromo1, newchromo2) else: return (chromo1, chromo2) def crossover_Uniform(self, chromo1, chromo2): """A crossover function that can be assigned to crossoverFunc. Creates two new chromosomes by flippinng a coin for each gene. If the coin is heads, the gene values in chromo1 and chromo2 are swapped (otherwise they are left alone). The two new chromosomes are returned in a tuple. Note that there is only a crossoverRate chance of crossover happening. """ prob = self.generator.random() if prob <= self.crossoverRate: self.crossoverCount = self.crossoverCount + 1 newchromo1 = chromo1.copy() newchromo2 = chromo2.copy() for i in range(len(chromo1)): #flip a coin...1 we switch, 0 we do nothing coin = self.generator.randint(0,1) if coin == 1: temp = newchromo1.genes[i] newchromo1.genes[i] = newchromo2.genes[i] newchromo2.genes[i] = temp return (newchromo1, newchromo2) else: return (chromo1, chromo2) def mutate_Default(self, chromo): """Mutation function that can be assigned to mutateFunc. For each gene on each chromosome, there is a mutationRate chance that it will be randomly re-initialized. The chromosome is returned. """ for i in range(len(chromo.genes)): prob = self.generator.random() if prob <= self.mutationRate: #then we mutate! self.mutationCount = self.mutationCount + 1 f = 0 if self.useInteger: f = self.generator.randint(self.chromoMinValues[i], self.chromoMaxValues[i]) else: f = self.generator.uniform(self.chromoMinValues[i], self.chromoMaxValues[i]) chromo.genes[i] = f return chromo def replace_SteadyState(self): """Replacement function that can be assigned to replaceFunc. Takes the values in nextGeneration, sticks them into currentGeneration, sorts currentGeneration, and lops off enough of the least fit individuals to reduce the size of currentGeneration back to numChromosomes. """ for chromo in self.nextGeneration: self.currentGeneration.append(chromo) self.currentGeneration.sort() self.currentGeneration.reverse() self.currentGeneration = self.currentGeneration[:self.numChromosomes] self.nextGeneration = [] def replace_SteadyStateNoDuplicates(self): """Replacement function that can be assigned to replaceFunc. Same as replace_SteadyState, exccept that duplicate chromosomes are not inserted back into the currentGeneration. """ #this one is like above, but no duplicates are allowed! for chromo in self.nextGeneration: flag = 0 for chromo2 in self.currentGeneration: if chromo.isIdentical(chromo2): flag = 1 if flag == 0: self.currentGeneration.append(chromo) self.currentGeneration.sort() self.currentGeneration.reverse() self.currentGeneration = self.currentGeneration[:self.numChromosomes] self.nextGeneration = [] def replace_Generational(self): """Replacement function that can be assigned to replaceFunc. Wholesale replacement of currentGeneration with nextGeneration. assumes that replacementSize is equal to numChromosomes; otherwise, the currentGeneration will shrink in size to replacementSize in size. """ self.currentGeneration = self.nextGeneration[:] self.nextGeneration = [] openopt-0.38+svn1589/openopt/solvers/Standalone/lsqr.py000066400000000000000000000275001175775750500231140ustar00rootroot00000000000000""" Solve the least-squares problem minimize ||Ax-b|| using LSQR. This is a line-by-line translation from Matlab code available at http://www.stanford.edu/~saunders/lsqr. Michael P. Friedlander, University of British Columbia Dominique Orban, Ecole Polytechnique de Montreal $Id$ """ from numpy import zeros, dot from openopt.kernel.ooMisc import norm from math import sqrt # Simple shortcuts---linalg.norm is too slow for small vectors def normof2(x,y): return sqrt(x**2 + y**2) def normof4(x1,x2,x3,x4): return sqrt(x1**2 + x2**2 + x3**2 + x4**2) def lsqr( m, n, aprod, b, damp, atol, btol, conlim, itnlim, show, wantvar = False, callback = lambda x: None): """ [ x, istop, itn, r1norm, r2norm, anorm, acond, arnorm, xnorm, var ]... = lsqr( m, n, @aprod, b, damp, atol, btol, conlim, itnlim, show ); LSQR solves Ax = b or min ||b - Ax||_2 if damp = 0, or min || [ b ] - [ A ] x || otherwise. || [ 0 ] [ damp I ] ||2 A is an m by n matrix defined by y = aprod(mode, m, n, x), where aprod refers to a function that performs the matrix-vector operations. If mode = 1, aprod must return y = Ax without altering x. If mode = 2, aprod must return y = A'x without altering x. ---------------------------------------------------------------------- LSQR uses an iterative (conjugate-gradient-like) method. For further information, see 1. C. C. Paige and M. A. Saunders (1982a). LSQR: An algorithm for sparse linear equations and sparse least squares, ACM TOMS 8(1), 43-71. 2. C. C. Paige and M. A. Saunders (1982b). Algorithm 583. LSQR: Sparse linear equations and least squares problems, ACM TOMS 8(2), 195-209. 3. M. A. Saunders (1995). Solution of sparse rectangular systems using LSQR and CRAIG, BIT 35, 588-604. Input parameters: atol, btol are stopping tolerances. If both are 1.0e-9 (say), the final residual norm should be accurate to about 9 digits. (The final x will usually have fewer correct digits, depending on cond(A) and the size of damp.) conlim is also a stopping tolerance. lsqr terminates if an estimate of cond(A) exceeds conlim. For compatible systems Ax = b, conlim could be as large as 1.0e+12 (say). For least-squares problems, conlim should be less than 1.0e+8. Maximum precision can be obtained by setting atol = btol = conlim = zero, but the number of iterations may then be excessive. itnlim is an explicit limit on iterations (for safety). show if set to 1, gives an iteration log. If set to 0, suppresses output. Output parameters: x is the final solution. istop gives the reason for termination. istop = 1 means x is an approximate solution to Ax = b. = 2 means x approximately solves the least-squares problem. r1norm = norm(r), where r = b - Ax. r2norm = sqrt( norm(r)^2 + damp^2 * norm(x)^2 ) = r1norm if damp = 0. anorm = estimate of Frobenius norm of Abar = [ A ]. [damp*I] acond = estimate of cond(Abar). arnorm = estimate of norm(A'*r - damp^2*x). xnorm = norm(x). var (if present) estimates all diagonals of (A'A)^{-1} (if damp=0) or more generally (A'A + damp^2*I)^{-1}. This is well defined if A has full column rank or damp > 0. (Not sure what var means if rank(A) < n and damp = 0.) ---------------------------------------------------------------------- """ # Initialize. msg=['The exact solution is x = 0 ', 'Ax - b is small enough, given atol, btol ', 'The least-squares solution is good enough, given atol ', 'The estimate of cond(Abar) has exceeded conlim ', 'Ax - b is small enough for this machine ', 'The least-squares solution is good enough for this machine', 'Cond(Abar) seems to be too large for this machine ', 'The iteration limit has been reached '] if wantvar: var = zeros(n,1) else: var = None # if show: # print ' ' # print 'LSQR Least-squares solution of Ax = b' # str1 = 'The matrix A has %8g rows and %8g cols' % (m, n) # str2 = 'damp = %20.14e wantvar = %-5s' % (damp, repr(wantvar)) # str3 = 'atol = %8.2e conlim = %8.2e' % (atol, conlim) # str4 = 'btol = %8.2e itnlim = %8g' % (btol, itnlim) # print str1; print str2; print str3; print str4; itn = 0; istop = 0; nstop = 0 ctol = 0.0 if conlim > 0.0: ctol = 1.0/conlim anorm = 0.; acond = 0. dampsq = damp**2; ddnorm = 0.; res2 = 0. xnorm = 0.; xxnorm = 0.; z = 0. cs2 = -1.; sn2 = 0. # Set up the first vectors u and v for the bidiagonalization. # These satisfy beta*u = b, alfa*v = A'u. u = b[:m]; x = zeros(n) alfa = 0.; beta = norm( u ) if beta > 0: u = (1.0/beta) * u; v = aprod(2, m, n, u) alfa = norm( v ); if alfa > 0: v = (1.0/alfa) * v; w = v.copy(); arnorm = alfa * beta; if arnorm == 0: # print(msg[0]) return (x, istop, itn, r1norm, r2norm, anorm, acond, arnorm, xnorm, var) rhobar = alfa; phibar = beta; bnorm = beta; rnorm = beta r1norm = rnorm r2norm = rnorm head1 = ' Itn x(1) r1norm r2norm ' head2 = ' Compatible LS Norm A Cond A' if show: # print ' ' # print head1+head2 test1 = 1.0; test2 = alfa / beta str1 = '%6g %12.5e' % (itn, x[0]) str2 = ' %10.3e %10.3e' % (r1norm, r2norm) str3 = ' %8.1e %8.1e' % (test1, test2) # print str1+str2+str3 # ------------------------------------------------------------------ # Main iteration loop. # ------------------------------------------------------------------ while itn < itnlim: itn = itn + 1 # Perform the next step of the bidiagonalization to obtain the # next beta, u, alfa, v. These satisfy the relations # beta*u = a*v - alfa*u, # alfa*v = A'*u - beta*v. u = aprod(1, m, n, v) - alfa*u beta = norm( u ); if beta > 0: u = (1.0/beta) * u anorm = normof4(anorm, alfa, beta, damp) v = aprod(2, m, n, u) - beta*v alfa = norm( v ) if alfa > 0: v = (1.0/alfa) * v # Use a plane rotation to eliminate the damping parameter. # This alters the diagonal (rhobar) of the lower-bidiagonal matrix. rhobar1 = normof2(rhobar, damp) cs1 = rhobar / rhobar1 sn1 = damp / rhobar1 psi = sn1 * phibar phibar = cs1 * phibar # Use a plane rotation to eliminate the subdiagonal element (beta) # of the lower-bidiagonal matrix, giving an upper-bidiagonal matrix. rho = normof2(rhobar1, beta) cs = rhobar1/ rho sn = beta / rho theta = sn * alfa rhobar = - cs * alfa phi = cs * phibar phibar = sn * phibar tau = sn * phi # Update x and w. t1 = phi /rho; t2 = - theta/rho; dk = (1.0/rho)*w; x = x + t1*w w = v + t2*w ddnorm = ddnorm + norm(dk)**2 if wantvar: var = var + dk*dk # Use a plane rotation on the right to eliminate the # super-diagonal element (theta) of the upper-bidiagonal matrix. # Then use the result to estimate norm(x). delta = sn2 * rho gambar = - cs2 * rho rhs = phi - delta * z zbar = rhs / gambar xnorm = sqrt(xxnorm + zbar**2) gamma = normof2(gambar, theta) cs2 = gambar / gamma sn2 = theta / gamma z = rhs / gamma xxnorm = xxnorm + z**2 # Test for convergence. # First, estimate the condition of the matrix Abar, # and the norms of rbar and Abar'rbar. acond = anorm * sqrt( ddnorm ) res1 = phibar**2 res2 = res2 + psi**2 rnorm = sqrt( res1 + res2 ) arnorm = alfa * abs( tau ) # 07 Aug 2002: # Distinguish between # r1norm = ||b - Ax|| and # r2norm = rnorm in current code # = sqrt(r1norm^2 + damp^2*||x||^2). # Estimate r1norm from # r1norm = sqrt(r2norm^2 - damp^2*||x||^2). # Although there is cancellation, it might be accurate enough. r1sq = rnorm**2 - dampsq * xxnorm r1norm = sqrt( abs(r1sq) ) if r1sq < 0: r1norm = - r1norm r2norm = rnorm # Now use these norms to estimate certain other quantities, # some of which will be small near a solution. test1 = rnorm / bnorm test2 = arnorm/( anorm * rnorm ) test3 = 1.0 / acond t1 = test1 / (1 + anorm * xnorm / bnorm) rtol = btol + atol * anorm * xnorm / bnorm # The following tests guard against extremely small values of # atol, btol or ctol. (The user may have set any or all of # the parameters atol, btol, conlim to 0.) # The effect is equivalent to the normal tests using # atol = eps, btol = eps, conlim = 1/eps. if itn >= itnlim: istop = 7 if 1 + test3 <= 1: istop = 6 if 1 + test2 <= 1: istop = 5 if 1 + t1 <= 1: istop = 4 # Allow for tolerances set by the user. if test3 <= ctol: istop = 3 if test2 <= atol: istop = 2 if test1 <= rtol: istop = 1 # See if it is time to print something. prnt = False; if n <= 40 : prnt = True if itn <= 10 : prnt = True if itn >= itnlim-10: prnt = True if itn % 10 == 0 : prnt = True if test3 <= 2*ctol : prnt = True if test2 <= 10*atol : prnt = True if test1 <= 10*rtol : prnt = True if istop != 0 : prnt = True if prnt and show: str1 = '%6g %12.5e' %( itn, x[0] ) str2 = ' %10.3e %10.3e' %(r1norm, r2norm ) str3 = ' %8.1e %8.1e' %( test1, test2 ) str4 = ' %8.1e %8.1e' %( anorm, acond ) # print str1+str2+str3+str4 if istop > 0: break callback(x) # added for OpenOpt kernel # End of iteration loop. # Print the stopping condition. # if show: # print ' ' # print 'LSQR finished' # print msg[istop] # print ' ' # str1 = 'istop =%8g r1norm =%8.1e' %(istop, r1norm ) # str2 = 'anorm =%8.1e arnorm =%8.1e' %(anorm, arnorm ) # str3 = 'itn =%8g r2norm =%8.1e' %( itn, r2norm ) # str4 = 'acond =%8.1e xnorm =%8.1e' %(acond, xnorm ) # str5 = ' bnorm =%8.1e' % bnorm # print str1 + ' ' + str2 # print str3 + ' ' + str4 # print str5 # print ' ' return ( x, istop, itn, r1norm, r2norm, anorm, acond, arnorm, xnorm, var ) openopt-0.38+svn1589/openopt/solvers/Standalone/lsqr_oo.py000066400000000000000000000070061175775750500236100ustar00rootroot00000000000000from openopt.kernel.ooMisc import norm from numpy import dot, asfarray, atleast_1d, zeros, ones, float64, where, inf, ndarray, flatnonzero from openopt.kernel.baseSolver import baseSolver from openopt.kernel.nonOptMisc import isspmatrix, scipyInstalled, scipyAbsentMsg, isPyPy from lsqr import lsqr as LSQR try: from scipy.sparse import csc_matrix, csr_matrix except: pass class lsqr(baseSolver): __name__ = 'lsqr' __license__ = "GPL?" __authors__ = 'Michael P. Friedlander (University of British Columbia), Dominique Orban (Ecole Polytechnique de Montreal)' __alg__ = 'an iterative (conjugate-gradient-like) method' __info__ = """ Parameters: atol (default 1e-9), btol (1e-9), conlim ('autoselect', default 1e8 for LLSP and 1e12 for SLE) For further information, see 1. C. C. Paige and M. A. Saunders (1982a). LSQR: An algorithm for sparse linear equations and sparse least squares, ACM TOMS 8(1), 43-71. 2. C. C. Paige and M. A. Saunders (1982b). Algorithm 583. LSQR: Sparse linear equations and least squares problems, ACM TOMS 8(2), 195-209. 3. M. A. Saunders (1995). Solution of sparse rectangular systems using LSQR and CRAIG, BIT 35, 588-604.""" __optionalDataThatCanBeHandled__ = ['damp', 'X'] _canHandleScipySparse = True atol = 1e-9 btol = 1e-9 conlim = 'autoselect' def __init__(self): pass def __solver__(self, p): condX = hasattr(p, 'X') and any(p.X) if condX: p.err("sorry, the solver can't handle non-zero X data yet, but you can easily handle it by yourself") C, d = p.C, p.d m, n = C.shape[0], p.n if scipyInstalled: if isspmatrix(C) or 0.25* C.size > flatnonzero(C).size: C = csc_matrix(C) elif not isPyPy and 0.25* C.size > flatnonzero(C).size: p.pWarn(scipyAbsentMsg) # if isinstance(C, ndarray) and 0.25* C.size > flatnonzero(C).size: # if not scipyInstalled: # p.pWarn(scipyAbsentMsg) # else: # C = csc_matrix(C) CT = C.T def aprod(mode, m, n, x): if mode == 1: r = dot(C, x).flatten() if not isspmatrix(C) else C._mul_sparse_matrix(csr_matrix(x.reshape(x.size, 1))).A.flatten() # It doesn't implemented properly yet # f = p.norm(r-d) # assert damp == 0 # if damp != 0: # assert not condX # p.iterfcn(x) # if p.istop: raise isSolved return r elif mode == 2: return dot(CT, x).flatten() if not isspmatrix(C) else CT._mul_sparse_matrix(csr_matrix(x.reshape(x.size, 1))).A.flatten() if self.conlim == 'autoselect': conlim = 1e12 if m == n else 1e8 damp = self.damp if hasattr(self, 'damp') and self.damp is not None else 0 show = False [ x, istop, itn, r1norm, r2norm, anorm, acond, arnorm, xnorm, var ] = \ LSQR(m, n, aprod, d, damp, 1e-9, 1e-9, conlim, p.maxIter, show, wantvar = False, callback = p.iterfcn) # ( m, n, aprod, b, damp, atol, btol, conlim, itnlim, show, wantvar = False ) #p.istop, p.msg, p.iter = istop, msg.rstrip(), iter p.istop = 1000 p.debugmsg('lsqr iterations elapsed: %d' % itn) #p.iter = 1 # itn p.xf = x #p.ff = p.fk = p.objFunc(x) openopt-0.38+svn1589/openopt/solvers/Standalone/pclp_oo.py000066400000000000000000000275451175775750500235770ustar00rootroot00000000000000''' Translated from Octave code at: http://www.ecs.shimane-u.ac.jp/~kyoshida/lpeng.htm and placed under MIT licence by Enzo Michelangeli with permission explicitly granted by the original author, Prof. Kazunobu Yoshida ----------------------------------------------------------------------------- Copyright (c) 2010, Kazunobu Yoshida, Shimane University, and Enzo Michelangeli, IT Vision Limited Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------------- Usage: optx,zmin,is_bounded,sol,basis = lp(c,A,b) This program finds a solution of the standard linear programming problem: minimize z = c'x subject to Ax = b, x >= 0 using the two phase method, where the simplex method is used at each stage. Returns the tuple: optx: an optimal solution. zmin: the optimal value. is_bounded: True if the solution is bounded; False if unbounded. sol: True if the problem is solvable; False if unsolvable. basis: indices of the basis of the solution. ''' from numpy import * #from numpy.linalg import norm #from numpy import dot, asfarray, atleast_1d, zeros, ones, int, float64, where, inf, ndarray from openopt.kernel.baseSolver import baseSolver from openopt.kernel.nonOptMisc import isspmatrix, scipyInstalled, scipyAbsentMsg try: from openopt.kernel.nonOptMisc import isPyPy except: pass from openopt.kernel.ooMisc import xBounds2Matrix from openopt.kernel.nonOptMisc import Hstack, Vstack, SparseMatrixConstructor, Eye, Diag, DenseMatrixConstructor #try: # from scipy.sparse import csc_matrix, csr_matrix #except: # pass class pclp(baseSolver): __name__ = 'pclp' __license__ = "MIT" __authors__ = '' __alg__ = 'a simplex method implementation' __info__ = """ """ __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub'] _canHandleScipySparse = True def __init__(self): pass def __solver__(self, p): xBounds2Matrix(p) n = p.n Ind_unbounded = logical_and(isinf(p.lb), isinf(p.ub)) ind_unbounded = where(Ind_unbounded)[0] n_unbounded = ind_unbounded.size # Cast linear inequality constraints into linear equality constraints using slack variables nLinInEq, nLinEq = p.b.size, p.beq.size #p.lb, p.ub = empty(n+nLinInEq+n_unbounded), empty(n+nLinInEq+n_unbounded) #p.lb.fill(-inf) #p.ub.fill(inf) # for fn in ['_A', '_Aeq']: # if hasattr(p, fn): delattr(p, fn) # TODO: handle p.useSparse parameter # if n_unbounded != 0: # R = SparseMatrixConstructor((n_unbounded, n)) # R[range(n_unbounded), ind_unbounded] = 1.0 # R2 = Diag([1]*nLinInEq+[-1]*n_unbounded) # _A = Hstack((Vstack((p.A, R)), R2)) # else: # _A = Hstack((p.A, Eye(nLinInEq))) _A = Hstack((p.A, Eye(nLinInEq), -Vstack([p.A[:, i] for i in ind_unbounded]).T if isPyPy else -p.A[:, ind_unbounded])) # if isspmatrix(_A): # _A = _A.A # add lin eq cons if nLinEq != 0: Constructor = SparseMatrixConstructor if scipyInstalled and nLinInEq > 100 else DenseMatrixConstructor _A = Vstack((_A, Hstack((p.Aeq, Constructor((nLinEq, nLinInEq)), \ -Vstack([p.Aeq[:, i] for i in ind_unbounded]).T if isPyPy else -p.Aeq[:, ind_unbounded])))) if isspmatrix(_A): if _A.size > 0.3 * prod(_A.shape): _A = _A.A else: _A = _A.tolil() #_A = _A.A #p.A, p.b = zeros((0, p.n)), array([]) #_f = hstack((p.f, zeros(nLinInEq+n_unbounded))) #_f = Hstack((p.f, zeros(nLinInEq), -p.f[ind_unbounded])) #_b = hstack((p.b, [0]*n_unbounded, p.beq)) _f = hstack((p.f, zeros(nLinInEq), -p.f[Ind_unbounded])) _b = hstack((p.b, p.beq)) if p.useSparse is False and isspmatrix(_A): _A = _A.A p.debugmsg('handling as sparse: ' + str(isspmatrix(_A))) optx,zmin,is_bounded,sol,basis = lp_engine(_f, _A, _b) p.xf = optx[:n] -optx[-n:] if len(optx) != 0 else nan p.istop = 1000 if p.xf is not nan else -1000 # from openopt import LP # p2 = LP(_f, Aeq=_A.copy(), beq=_b, lb=[0]*_f.size) # r=p2.solve('lpSolve', maxIter = 1e4) # x_opt_2= r.xf[:n] - r.xf[-n:] #assert len(optx)>0 #print linalg.norm(p.xf - x_opt_2) #raise 0 def lp_engine(c, A, b): # c = asarray(c) # A = asarray(A) # b = asarray(b) m,n = A.shape ind = b < 0 if any(ind): b = abs(b) #A[ind, :] = -A[ind, :] doesn't work for sparse if type(A) == ndarray and not isPyPy: A[ind] = -A[ind] else: for i in where(ind)[0]: A[i,:] = -A[i,:] d = -A.sum(axis=0) if not isscalar(d) and type(d) != ndarray: d = d.A.flatten() if not isinstance(d, ndarray): d = d.A.flatten() # d may be dense matrix w0 = sum(b) # H = [A b;c' 0;d -w0]; #H = bmat('A b; c 0; d -w0') '''''' H = Vstack([ # The initial _simplex table of phase one Hstack([A, atleast_2d(b).T]), # first m rows hstack([c, 0.]), # last-but-one hstack([d, -asfarray(w0)])]) # last #print sum(abs(Hstack([A, array([b]).T]))) if isspmatrix(H): H = H.tolil() '''''' indx = arange(n) basis = arange(n, n+m) #H, basis, is_bounded = _simplex(H, basis, indx, 1) is_bounded = _simplex(H, basis, indx, 1) if H[m+1,n] < -1e-10: # last row, last column sol = False #print('unsolvable') optx = [] zmin = [] is_bounded = False else: sol = True j = -1 #NEW tmp = H[m+1,:] if type(tmp) != ndarray: tmp = tmp.A.flatten() ind = tmp > 1e-10 if any(ind): j = where(logical_not(ind))[0] H = H[:, j] indx = indx[j] #Old # for i in range(n): # j = j+1 # if H[m+1,j] > 1e-10: # H[:,j] = [] # indx[j] = [] # j = j-1 #H(m+2,:) = [] % delete last row H = H[0:m+1,:] if size(indx) > 0: # Phase two #H, basis, is_bounded = _simplex(H,basis,indx,2); is_bounded = _simplex(H,basis,indx,2) if is_bounded: optx = zeros(n+m) n1,n2 = H.shape for i in range(m): optx[basis[i]] = H[i,n2-1] # optx(n+1:n+m,1) = []; % delete last m elements optx = optx[0:n] zmin = -H[n1-1,n2-1] # last row, last column else: optx = [] zmin = -Inf else: optx = zeros(n+m) zmin = 0 return (optx, zmin, is_bounded, sol, basis) def _simplex(H,basis,indx,s): ''' [H1,basis,is_bounded] = _simplex(H,basis,indx,s) H: simplex table (MODIFIED). basis: the indices of basis (MODIFIED). indx: the indices of x. s: 1 for phase one; 2 for phase two. H1: new simplex table. is_bounded: True if the solution is bounded; False if unbounded. ''' if s == 1: s0 = 2 elif s == 2: s0 = 1 n1, n2 = H.shape sol = False while not sol: #print 'new Iter' # [fm,jp] = min(H(n1,1:n2-1)); q = H[n1-1, 0:n2-1] # last row, all columns but last if type(q) != ndarray: q = q.toarray().flatten() jp = argmin(q) fm = q[jp] if fm >= 0: is_bounded = True # bounded solution sol = True else: # [hm,ip] = max(H(1:n1-s0,jp)); q = H[0:n1-s0,jp] if type(q) != ndarray: q = q.toarray().flatten() ip = argmax(q) hm = q[ip] if hm <= 0: is_bounded = False # unbounded solution sol = True else: h1 = empty(n1-s0) h1.fill(inf) # NEW tmp = H[:n1-s0,jp] if isspmatrix(tmp): tmp = tmp.A.flatten() ind = tmp>0 #tmp2 = H[ind,n2-1]/H[ind,jp] tmp2 = hstack([H[i,n2-1]/H[i, jp] for i in where(ind)[0]]) if 1 or isPyPy else H[ind,n2-1]/H[ind,jp] #assert hstack([H[i,n2-1]/H[i, jp] for i in where(ind)[0]]).shape == (H[ind,n2-1]/H[ind,jp]).shape if isspmatrix(tmp2): tmp2 = tmp2.A if isPyPy: for i, val in enumerate(where(ind)[0]): h1[val] = tmp2[i] else: h1[atleast_1d(ind)] = tmp2 #OLD # for i in range(n1-s0): # if H[i,jp] > 0: # h1[i] = H[i,n2-1]/H[i,jp] ip = argmin(h1) minh1 = h1[ip] basis[ip] = indx[jp] if not _pivot(H,ip,jp): raise ValueError("the first parameter is a Singular matrix") return is_bounded def _pivot(H,ip,jp): # H is MODIFIED n, m = H.shape piv = H[ip,jp] if piv == 0: #print('singular') return False else: #NEW H[ip,:] /= piv tmp2 = H[:,jp]*H[ip,:] if isspmatrix(H) else H[:,jp].reshape(-1, 1)*H[ip,:] if isspmatrix(tmp2): tmp2 = tmp2.tolil() tmp2[ip, :] = 0 H -= tmp2 #OLD # for i in range(n): # if i != ip: # H[i,:] -= H[i,jp]*H[ip,:] return True ######### Unit test section ######### # #from numpy.testing import * # #def test_lp(): # probs = [ # { # 'A': array([ # [2., 5., 3., -1., 0., 0.], # [3., 2.5, 8., 0., -1., 0.], # [8.,10., 4., 0., 0., -1.]]), # 'b': array([185., 155., 600.]), # 'c': array([4., 8., 3., 0., 0., 0.]), # 'result': [ # array([ 66.25, 0., 17.5, 0., 183.75, 0.]), # 317.5, # True, # True, # array([2, 0, 4]) # ] # }, # add other test cases here... # ] # # for prob in probs: # optx, zmin, bounded, solvable, basis = lp_engine(prob['c'],prob['A'],prob['b']) # expected_res = prob['result'] # assert_almost_equal(optx, expected_res[0]) # assert_almost_equal(zmin, expected_res[1]) # assert_equal(bounded, expected_res[2]) # assert_equal(solvable, expected_res[3]) # assert_equal(basis, expected_res[4]) # #if __name__ == "__main__": # run_module_suite() openopt-0.38+svn1589/openopt/solvers/Standalone/pointProjection.py000066400000000000000000000010201175775750500253060ustar00rootroot00000000000000from numpy import * from openopt import * def pointProjection(x, lb, ub, A, b, Aeq, beq): # projection of x to set of linear constraints n = x.size # TODO: INVOLVE SPARSE CVXOPT MATRICES p = QP(H = eye(n), f = -x, A = A, b=b, Aeq=Aeq, beq=beq, lb=lb, ub=ub) r = p.solve('cvxopt_qp') return r.xf if __name__ == '__main__': x = array((1, 2, 3)) lb, ub = None, None A = [3, 4, 5] b = -15 Aeq, beq = None, None proj = pointProjection(x, lb, ub, A, b, Aeq, beq) print(proj) openopt-0.38+svn1589/openopt/solvers/Standalone/pswarm_oo.py000066400000000000000000000071001175775750500241330ustar00rootroot00000000000000#from numpy import asfarray, argmax, sign, inf, log10 from openopt.kernel.baseSolver import baseSolver from numpy import isfinite, asscalar, array, asfarray, ravel #asfarray, inf, atleast_1d from pswarm_py import pswarm as PSWARM from openopt.kernel.setDefaultIterFuncs import SMALL_DELTA_X, SMALL_DELTA_F #from openopt.kernel.setDefaultIterFuncs import SMALL_DELTA_X, SMALL_DELTA_F class pswarm(baseSolver): __name__ = 'pswarm' __license__ = "LGPL" __authors__ = 'A. I. F. Vaz (http://www.norg.uminho.pt/aivaz), connected to OO by Dmitrey' __alg__ = "A. I. F. Vaz and L. N. Vicente, A particle swarm pattern search method for bound constrained global optimization, Journal of Global Optimization, 39 (2007) 197-219. The algorithm combines pattern search and particle swarm. Basically, it applies a directional direct search in the poll step (coordinate search in the pure simple bounds case) and particle swarm in the search step." iterfcnConnected = True __homepage__ = 'http://www.norg.uminho.pt/aivaz/pswarm/' __info__ = "parameters: social (default = 0.5), cognitial (0.5), fweight (0.4), iweight (0.9), size (42), tol (1e-5), ddelta (0.5), idelta (2.0). Can handle constraints lb <= x <= ub (values beyond 1e20 are treated as 1e20), A x <= b. Documentation says pswarm is capable of using parallel calculations (via MPI) but I don't know is it relevant to Python API." __optionalDataThatCanBeHandled__ = ['lb', 'ub', 'A', 'b'] __isIterPointAlwaysFeasible__ = lambda self, p: p.__isNoMoreThanBoxBounded__() social = 0.5 cognitial = 0.5 fweight = 0.4 iweight = 0.9 size = 42 tol = 1e-5 ddelta = 0.5 idelta = 2.0 def __init__(self):pass def __solver__(self, p): #if not p.__isFiniteBoxBounded__(): p.err('this solver requires finite lb, ub: lb <= x <= ub') p.kernelIterFuncs.pop(SMALL_DELTA_X) p.kernelIterFuncs.pop(SMALL_DELTA_F) lb, ub = p.lb, p.ub lb[lb < -1e20] = -1e20 ub[ub > 1e20] = 1e20 def f(x): if len(x) == 1: y = ravel(x) else: y = asfarray(x) return array(p.f(y), 'float') Problem = { 'Variables': p.n, 'objf': f, 'lb': lb.tolist(), 'ub': ub.tolist(), } if any(isfinite(p.b)): Problem['A'] = p.A.tolist() Problem['b'] = p.b.tolist() if hasattr(p,'x0') and p.x0 is not None: Problem['x0'] = p.x0.tolist() def pswarm_iterfcn(it, leader, fx, x): p.xk = array(x) p.fk = array(fx) #print x, fx p.iterfcn() if p.istop != 0: p.debugmsg('istop:'+str(p.istop)) return -1.0 else: return 1.0 Options = { 'maxf': 2*p.maxFunEvals, # to provide correct istop triggered from OO kernel 'maxit': p.maxIter+15, # to provide correct istop triggered from OO kernel 'social': self.social, 'cognitial': self.cognitial, 'fweight': self.fweight, 'iweight': self.iweight, 'size': self.size, 'tol': self.tol, 'ddelta': self.ddelta, 'idelta': self.idelta, 'iprint': 1, 'outputfcn': pswarm_iterfcn, 'vectorized': 1 } result = PSWARM(Problem,Options) #print 'results:', xf, ff p.xf, p.ff = result['x'], result['f'] if p.istop == 0: p.istop = 1000 #if p.istop == 0 : p.istop = 1000 openopt-0.38+svn1589/openopt/solvers/Standalone/pymls_oo.py000066400000000000000000000171401175775750500237730ustar00rootroot00000000000000# -*- coding: utf-8 -*- """ Created on Thu May 05 20:02:00 2011 @author: Tillsten """ #from numpy.linalg import norm #from numpy import dot, asfarray, atleast_1d, zeros, ones, int, float64, where, inf import numpy as np from openopt.kernel.baseSolver import baseSolver class pymls(baseSolver): __name__ = 'pymls' __license__ = "BSD" __authors__ = 'Till Stensitzki, based directly on code from qcat from Ola Harkegard (http://research.harkegard.se/)' __alg__ = '' __info__ = '' __optionalDataThatCanBeHandled__ = ['lb', 'ub'] #__bvls_inf__ = 1e100 T = np.float64 __pymls_inf__ = 1e9 def __init__(self): pass def __solver__(self, p): T = self.T A, b = T(p.C), T(p.d).copy().reshape(-1, 1) lb, ub = p.lb.copy().reshape(-1, 1), p.ub.copy().reshape(-1, 1) lb[lb==-np.inf] = -self.__pymls_inf__ ub[ub==np.inf] = self.__pymls_inf__ xf = bounded_lsq(A,b,lb,ub) p.xf = p.xk = xf.flatten() from scipy.linalg import qr eps=np.finfo(float).eps def mls(B,v,umin,umax,Wv=None,Wu=None,ud=None,u=None,W=None,imax=100): """ mls - Control allocation using minimal least squares. [u,W,iter] = mls_alloc(B,v,umin,umax,[Wv,Wu,ud,u0,W0,imax]) Solves the bounded sequential least-squares problem min ||Wu(u-ud)|| subj. to u in M where M is the set of control signals solving min ||Wv(Bu-v)|| subj. to umin <= u <= umax using a two stage active set method. Wu must be diagonal since the problem is reformulated as a minimal least squares problem. The implementation does not handle the case of coplanar controls. Inputs: ------- B control effectiveness matrix (k x m) v commanded virtual control (k x 1) umin lower position limits (m x 1) umax upper position limits (m x 1) Wv virtual control weighting matrix (k x k) [I] Wu control weighting matrix (m x m), diagonal [I] ud desired control (m x 1) [0] u0 initial point (m x 1) W0 initial working set (m x 1) [empty] imax max no. of iterations [100] Outputs: ------- u optimal control W optimal active set iter no. of iterations (= no. of changes in the working set + 1) 0 if u_i not saturated Active set syntax: W_i = -1 if u_i = umin_i +1 if u_i = umax_i Directly Based on the code from: Ola Härkegård, www.control.isy.liu.se/~ola see licsence. """ #k = number of virtual controls #m = number of variables (actuators) k,m=B.shape if u==None: u=np.mean(umin+umax,0)[:,None] if W==None: W=np.zeros((m,1)) if ud==None: ud=np.zeros((m,1)) if Wu==None: Wu=np.eye(m) if Wv==None: Wv=np.eye(k) phase=1 #Reformulate as a minimal least squares problem. See 2002-03-08 (1). A=Wv.dot(B).dot(np.linalg.pinv(Wu)) #print B, v #A=B b = Wv.dot(v-B.dot(ud)) #b=v #print b xmin = (umin-ud) xmax = (umax-ud) # Compute initial point and residual. x = Wu.dot(u-ud) #x#=umin-umax r = A.dot(x)-b # print x.shape, r.shape, b.shape,x,r #Determine indeces of free variables i_free = W==0 m_free = np.sum(i_free) for i in range(imax): #print 'Iter: ', i if phase==1: A_free = A[:,i_free.squeeze()] if m_free<=k: if m_free>0: p_free=np.linalg.lstsq(-A_free,r)[0] else: q1,r1=qr(A_free.T) p_free=-q1.dot(np.solve(r1.T,r)) p=np.zeros((m,1)) p[i_free.squeeze()]=p_free else: i_fixed=np.logical_not(i_free) m_fixed=m-m_free if m_fixed>0: HT=U[i_fixed.squeeze(),:].T V,Rtot= qr(np.atleast_2d(HT)) V1=V[:,:m_fixed] V2=V[:,m_fixed+1:] R=Rtot[:,m_fixed] else: V,Rtot=np.array([[]]),np.array([[]]) V1=V2=R=V.T s=-V2.T.dot(z) pz=V2.dot(s) p=U.dot(pz) x_opt=x+p infeasible=np.logical_or(x_optxmax) if not np.any(infeasible[i_free]): x=x_opt if phase==1: r=r+A.dot(p) else: z=z+pz if phase==1 and m_free>=k: phase=2 Utot, Stot=qr(A.T) U=Utot[:,k:] z=U.T.dot(x) else: lam=np.zeros((m,1)) if m_free= -eps): u=np.linalg.solve(Wu,x)+ud return u lambda_neg,i_neg=np.min(lam),np.argmin(lam) W[i_neg]=0 i_free[i_neg]=1 m_free+=1 else: dist=np.ones((m,1)) i_min=np.logical_and(i_free,p<0) i_max=np.logical_and(i_free,p>0) dist[i_min]=(xmin[i_min]-x[i_min])/p[i_min] dist[i_max]=(xmax[i_max]-x[i_max])/p[i_max] alpha,i_alpha=np.min(dist),np.argmin(dist) x = x + alpha*p if phase==1: r=r+A.dot(alpha*p) #!! else: z=z+alpha*pz W[i_alpha]=np.sign(p[i_alpha]) i_free[i_alpha]=0 m_free-=1 u=np.linalg.solve(Wu,x)+ud return u def bounded_lsq(A,b,lower_lim,upper_lim): """ Minimizes: |Ax-b|_2 for lower_lim", connectionstyle="arc3"), ) plt.annotate("Lsq Min", xy=np.linalg.lstsq(A,b)[0], xycoords='data', xytext=(20, 10), textcoords='offset points', arrowprops=dict(arrowstyle="->", connectionstyle="arc3"), ) plt.scatter(*x0) plt.scatter(*np.linalg.lstsq(A,b)[0]) plt.show() openopt-0.38+svn1589/openopt/solvers/Standalone/toms587.f000066400000000000000000006375671175775750500232020ustar00rootroot00000000000000C ALGORITHM 587, COLLECTED ALGORITHMS FROM ACM. C ALGORITHM APPEARED IN ACM-TRANS. MATH. SOFTWARE, VOL. 8, NO. 3, C SEP., 1982, P.323. SUBROUTINE LSEI(W, MDW, ME, MA, MG, N, PRGOPT, X, RNORME, RNORML, LSEI 10 * MODE, WS, IP) C C DIMENSION W(MDW,N+1),PRGOPT(*),X(N), C WS(2*(ME+N)+K+(MG+2)*(N+7)),IP(MG+2*N+2) C ABOVE, K=MAX(MA+MG,N). C C ABSTRACT C C THIS SUBPROGRAM SOLVES A LINEARLY CONSTRAINED LEAST SQUARES C PROBLEM WITH BOTH EQUALITY AND INEQUALITY CONSTRAINTS, AND, IF THE C USER REQUESTS, OBTAINS A COVARIANCE MATRIX OF THE SOLUTION C PARAMETERS. C C SUPPOSE THERE ARE GIVEN MATRICES E, A AND G OF RESPECTIVE C DIMENSIONS ME BY N, MA BY N AND MG BY N, AND VECTORS F, B AND H OF C RESPECTIVE LENGTHS ME, MA AND MG. THIS SUBROUTINE SOLVES THE C LINEARLY CONSTRAINED LEAST SQUARES PROBLEM C C EX = F, (E ME BY N) (EQUATIONS TO BE EXACTLY C SATISFIED) C AX = B, (A MA BY N) (EQUATIONS TO BE C APPROXIMATELY SATISFIED, C LEAST SQUARES SENSE) C GX.GE.H,(G MG BY N) (INEQUALITY CONSTRAINTS) C C THE INEQUALITIES GX.GE.H MEAN THAT EVERY COMPONENT OF THE PRODUCT C GX MUST BE .GE. THE CORRESPONDING COMPONENT OF H. C C IN CASE THE EQUALITY CONSTRAINTS CANNOT BE SATISFIED, A C GENERALIZED INVERSE SOLUTION RESIDUAL VECTOR LENGTH IS OBTAINED C FOR F-EX. THIS IS THE MINIMAL LENGTH POSSIBLE FOR F-EX. C C C ANY VALUES ME.GE.0, MA.GE.0, OR MG.GE.0 ARE PERMITTED. THE C RANK OF THE MATRIX E IS ESTIMATED DURING THE COMPUTATION. WE CALL C THIS VALUE KRANKE. IT IS AN OUTPUT PARAMETER IN IP(1) DEFINED C BELOW. USING A GENERALIZED INVERSE SOLUTION OF EX=F, A REDUCED C LEAST SQUARES PROBLEM WITH INEQUALITY CONSTRAINTS IS OBTAINED. C THE TOLERANCES USED IN THESE TESTS FOR DETERMINING THE RANK C OF E AND THE RANK OF THE REDUCED LEAST SQUARES PROBLEM ARE C GIVEN IN SANDIA TECH. REPT. SAND 78-1290. THEY CAN BE C MODIFIED BY THE USER IF NEW VALUES ARE PROVIDED IN C THE OPTION LIST OF THE ARRAY PRGOPT(*). C C THE EDITING REQUIRED TO CONVERT THIS SUBROUTINE FROM SINGLE TO C DOUBLE PRECISION INVOLVES THE FOLLOWING CHARACTER STRING CHANGES. C USE AN EDITING COMMAND (CHANGE) /STRING-1/(TO)STRING-2/. C (START EDITING AT LINE WITH C++ IN COLS. 1-3.) C /REAL (12 BLANKS)/DOUBLE PRECISION/,/SASUM/DASUM/,/SDOT/DDOT/, C /SNRM2/DNRM2/,/ SQRT/ DSQRT/,/ ABS/ DABS/,/AMAX1/DMAX1/, C /SCOPY/DCOPY/,/SSCAL/DSCAL/,/SAXPY/DAXPY/,/SSWAP/DSWAP/,/E0/D0/, C /, DUMMY/,SNGL(DUMMY)/,/SRELPR/DRELPR/ C C WRITTEN BY R. J. HANSON AND K. H. HASKELL. FOR FURTHER MATH. C AND ALGORITHMIC DETAILS SEE SANDIA LABORATORIES TECH. REPTS. C SAND 77-0552, (1978), SAND 78-1290, (1979), AND C MATH. PROGRAMMING, VOL. 21, (1981), P.98-118. C C THE USER MUST DIMENSION ALL ARRAYS APPEARING IN THE CALL LIST.. C W(MDW,N+1),PRGOPT(*),X(N),WS(2*(ME+N)+K+(MG+2)*(N+7)),IP(MG+2*N+2) C WHERE K=MAX(MA+MG,N). THIS ALLOWS FOR A SOLUTION OF A RANGE OF C PROBLEMS IN THE GIVEN WORKING SPACE. THE DIMENSION OF WS(*) C GIVEN IS A NECESSARY OVERESTIMATE. ONCE A PARTICULAR PROBLEM C HAS BEEN RUN, THE OUTPUT PARAMETER IP(3) GIVES THE ACTUAL C DIMENSION REQUIRED FOR THAT PROBLEM. C C THE PARAMETERS FOR LSEI( ) ARE C C INPUT.. C C W(*,*),MDW, THE ARRAY W(*,*) IS DOUBLY SUBSCRIPTED WITH C ME,MA,MG,N FIRST DIMENSIONING PARAMETER EQUAL TO MDW. C FOR THIS DISCUSSION LET US CALL M = ME+MA+MG. THEN C MDW MUST SATISFY MDW.GE.M. THE CONDITION C MDW.LT.M IS AN ERROR. C C THE ARRAY W(*,*) CONTAINS THE MATRICES AND VECTORS C C (E F) C (A B) C (G H) C C IN ROWS AND COLUMNS 1,...,M AND 1,...,N+1 C RESPECTIVELY. C C THE INTEGERS ME, MA, AND MG ARE THE C RESPECTIVE MATRIX ROW DIMENSIONS C OF E, A AND G. EACH MATRIX HAS N COLUMNS. C C PRGOPT(*) THIS ARRAY IS THE OPTION VECTOR. C IF THE USER IS SATISFIED WITH THE NOMINAL C SUBPROGRAM FEATURES SET C C PRGOPT(1)=1 (OR PRGOPT(1)=1.0) C C OTHERWISE PRGOPT(*) IS A LINKED LIST CONSISTING OF C GROUPS OF DATA OF THE FOLLOWING FORM C C LINK C KEY C DATA SET C C THE PARAMETERS LINK AND KEY ARE EACH ONE WORD. C THE DATA SET CAN BE COMPRISED OF SEVERAL WORDS. C THE NUMBER OF ITEMS DEPENDS ON THE VALUE OF KEY. C THE VALUE OF LINK POINTS TO THE FIRST C ENTRY OF THE NEXT GROUP OF DATA WITHIN C PRGOPT(*). THE EXCEPTION IS WHEN THERE ARE C NO MORE OPTIONS TO CHANGE. IN THAT C CASE LINK=1 AND THE VALUES KEY AND DATA SET C ARE NOT REFERENCED. THE GENERAL LAYOUT OF C PRGOPT(*) IS AS FOLLOWS. C C ...PRGOPT(1)=LINK1 (LINK TO FIRST ENTRY OF NEXT GROUP) C . PRGOPT(2)=KEY1 (KEY TO THE OPTION CHANGE) C . PRGOPT(3)=DATA VALUE (DATA VALUE FOR THIS CHANGE) C . . C . . C . . C ...PRGOPT(LINK1)=LINK2 (LINK TO THE FIRST ENTRY OF C . NEXT GROUP) C . PRGOPT(LINK1+1)=KEY2 (KEY TO THE OPTION CHANGE) C . PRGOPT(LINK1+2)=DATA VALUE C ... . C . . C . . C ...PRGOPT(LINK)=1 (NO MORE OPTIONS TO CHANGE) C C VALUES OF LINK THAT ARE NONPOSITIVE ARE ERRORS. C A VALUE OF LINK.GT.NLINK=100000 IS ALSO AN ERROR. C THIS HELPS PREVENT USING INVALID BUT POSITIVE C VALUES OF LINK THAT WILL PROBABLY EXTEND C BEYOND THE PROGRAM LIMITS OF PRGOPT(*). C UNRECOGNIZED VALUES OF KEY ARE IGNORED. THE C ORDER OF THE OPTIONS IS ARBITRARY AND ANY NUMBER C OF OPTIONS CAN BE CHANGED WITH THE FOLLOWING C RESTRICTION. TO PREVENT CYCLING IN THE C PROCESSING OF THE OPTION ARRAY A COUNT OF THE C NUMBER OF OPTIONS CHANGED IS MAINTAINED. C WHENEVER THIS COUNT EXCEEDS NOPT=1000 AN ERROR C MESSAGE IS PRINTED AND THE SUBPROGRAM RETURNS. C C OPTIONS.. C C KEY=1 C COMPUTE IN W(*,*) THE N BY N C COVARIANCE MATRIX OF THE SOLUTION VARIABLES C AS AN OUTPUT PARAMETER. NOMINALLY THE C COVARIANCE MATRIX WILL NOT BE COMPUTED. C (THIS REQUIRES NO USER INPUT.) C THE DATA SET FOR THIS OPTION IS A SINGLE VALUE. C IT MUST BE NONZERO WHEN THE COVARIANCE MATRIX C IS DESIRED. IF IT IS ZERO, THE COVARIANCE C MATRIX IS NOT COMPUTED. WHEN THE COVARIANCE MATRIX C IS COMPUTED, THE FIRST DIMENSIONING PARAMETER C OF THE ARRAY W(*,*) MUST SATISFY MDW.GE.MAX0(M,N). C C KEY=2 C SCALE THE NONZERO COLUMNS OF THE C ENTIRE DATA MATRIX. C (E) C (A) C (G) C C TO HAVE LENGTH ONE. THE DATA SET FOR THIS C OPTION IS A SINGLE VALUE. IT MUST BE C NONZERO IF UNIT LENGTH COLUMN SCALING C IS DESIRED. C C KEY=3 C SCALE COLUMNS OF THE ENTIRE DATA MATRIX C (E) C (A) C (G) C C WITH A USER-PROVIDED DIAGONAL MATRIX. C THE DATA SET FOR THIS OPTION CONSISTS C OF THE N DIAGONAL SCALING FACTORS, ONE FOR C EACH MATRIX COLUMN. C C KEY=4 C CHANGE THE RANK DETERMINATION TOLERANCE FOR C THE EQUALITY CONSTRAINT EQUATIONS FROM C THE NOMINAL VALUE OF SQRT(SRELPR). THIS QUANTITY CAN C BE NO SMALLER THAN SRELPR, THE ARITHMETIC- C STORAGE PRECISION. THE QUANTITY SRELPR IS THE C LARGEST POSITIVE NUMBER SUCH THAT T=1.+SRELPR C SATISFIES T.EQ.1. THE QUANTITY USED C HERE IS INTERNALLY RESTRICTED TO BE AT C LEAST SRELPR. THE DATA SET FOR THIS OPTION C IS THE NEW TOLERANCE. C C KEY=5 C CHANGE THE RANK DETERMINATION TOLERANCE FOR C THE REDUCED LEAST SQUARES EQUATIONS FROM C THE NOMINAL VALUE OF SQRT(SRELPR). THIS QUANTITY CAN C BE NO SMALLER THAN SRELPR, THE ARITHMETIC- C STORAGE PRECISION. THE QUANTITY USED C HERE IS INTERNALLY RESTRICTED TO BE AT C LEAST SRELPR. THE DATA SET FOR THIS OPTION C IS THE NEW TOLERANCE. C C FOR EXAMPLE, SUPPOSE WE WANT TO CHANGE C THE TOLERANCE FOR THE REDUCED LEAST SQUARES C PROBLEM, COMPUTE THE COVARIANCE MATRIX OF C THE SOLUTION PARAMETERS, AND PROVIDE C COLUMN SCALING FOR THE DATA MATRIX. FOR C THESE OPTIONS THE DIMENSION OF PRGOPT(*) C MUST BE AT LEAST N+9. THE FORTRAN STATEMENTS C DEFINING THESE OPTIONS WOULD BE AS FOLLOWS. C C PRGOPT(1)=4 (LINK TO ENTRY 4 IN PRGOPT(*)) C PRGOPT(2)=1 (COVARIANCE MATRIX KEY) C PRGOPT(3)=1 (COVARIANCE MATRIX WANTED) C C PRGOPT(4)=7 (LINK TO ENTRY 7 IN PRGOPT(*)) C PRGOPT(5)=5 (LEAST SQUARES EQUAS. TOLERANCE KEY) C PRGOPT(6)=... (NEW VALUE OF THE TOLERANCE) C C PRGOPT(7)=N+9 (LINK TO ENTRY N+9 IN PRGOPT(*)) C PRGOPT(8)=3 (USER-PROVIDED COLUMN SCALING KEY) C C CALL SCOPY(N,D,1,PRGOPT(9),1) (COPY THE N C SCALING FACTORS FROM THE USER ARRAY D(*) C TO PRGOPT(9)-PRGOPT(N+8)) C C PRGOPT(N+9)=1 (NO MORE OPTIONS TO CHANGE) C C THE CONTENTS OF PRGOPT(*) ARE NOT MODIFIED C BY THE SUBPROGRAM. C THE OPTIONS FOR WNNLS( ) CAN ALSO BE INCLUDED C IN THIS ARRAY. THE VALUES OF KEY RECOGNIZED C BY WNNLS( ) ARE 6, 7 AND 8. THEIR FUNCTIONS C ARE DOCUMENTED IN THE USAGE INSTRUCTIONS FOR C SUBROUTINE WNNLS( ). NORMALLY THESE OPTIONS C DO NOT NEED TO BE MODIFIED WHEN USING LSEI( ). C C IP(1), THE AMOUNTS OF WORKING STORAGE ACTUALLY C IP(2) ALLOCATED FOR THE WORKING ARRAYS WS(*) AND C IP(*), RESPECTIVELY. THESE QUANTITIES ARE C COMPARED WITH THE ACTUAL AMOUNTS OF STORAGE C NEEDED BY LSEI( ). INSUFFICIENT STORAGE C ALLOCATED FOR EITHER WS(*) OR IP(*) IS AN C ERROR. THIS FEATURE WAS INCLUDED IN LSEI( ) C BECAUSE MISCALCULATING THE STORAGE FORMULAS C FOR WS(*) AND IP(*) MIGHT VERY WELL LEAD TO C SUBTLE AND HARD-TO-FIND EXECUTION ERRORS. C C THE LENGTH OF WS(*) MUST BE AT LEAST C C LW = 2*(ME+N)+K+(MG+2)*(N+7) C C C WHERE K = MAX(MA+MG,N) C THIS TEST WILL NOT BE MADE IF IP(1).LE.0. C C THE LENGTH OF IP(*) MUST BE AT LEAST C C LIP = MG+2*N+2 C THIS TEST WILL NOT BE MADE IF IP(2).LE.0. C C OUTPUT.. C C X(*),RNORME, THE ARRAY X(*) CONTAINS THE SOLUTION PARAMETERS C RNORML IF THE INTEGER OUTPUT FLAG MODE = 0 OR 1. C THE DEFINITION OF MODE IS GIVEN DIRECTLY BELOW. C WHEN MODE = 0 OR 1, RNORME AND RNORML C RESPECTIVELY CONTAIN THE RESIDUAL VECTOR C EUCLIDEAN LENGTHS OF F - EX AND B - AX. WHEN C MODE=1 THE EQUALITY CONSTRAINT EQUATIONS EX=F C ARE CONTRADICTORY, SO RNORME.NE.0. THE RESIDUAL C VECTOR F-EX HAS MINIMAL EUCLIDEAN LENGTH. FOR C MODE.GE.2, NONE OF THESE PARAMETERS ARE C DEFINED. C C MODE INTEGER FLAG THAT INDICATES THE SUBPROGRAM C STATUS AFTER COMPLETION. IF MODE.GE.2, NO C SOLUTION HAS BEEN COMPUTED. C C MODE = C C 0 BOTH EQUALITY AND INEQUALITY CONSTRAINTS C ARE COMPATIBLE AND HAVE BEEN SATISFIED. C C 1 EQUALITY CONSTRAINTS ARE CONTRADICTORY. C A GENERALIZED INVERSE SOLUTION OF EX=F WAS USED C TO MINIMIZE THE RESIDUAL VECTOR LENGTH F-EX. C IN THIS SENSE, THE SOLUTION IS STILL MEANINGFUL. C C 2 INEQUALITY CONSTRAINTS ARE CONTRADICTORY. C C 3 BOTH EQUALITY AND INEQUALITY CONSTRAINTS C ARE CONTRADICTORY. C C THE FOLLOWING INTERPRETATION OF C MODE=1,2 OR 3 MUST BE MADE. THE C SETS CONSISTING OF ALL SOLUTIONS C OF THE EQUALITY CONSTRAINTS EX=F C AND ALL VECTORS SATISFYING GX.GE.H C HAVE NO POINTS ON COMMON. (IN C PARTICULAR THIS DOES NOT SAY THAT C EACH INDIVIDUAL SET HAS NO POINTS C AT ALL, ALTHOUGH THIS COULD BE THE C CASE.) C C 4 USAGE ERROR OCCURRED. THE VALUE C OF MDW IS .LT. ME+MA+MG, MDW IS C .LT. N AND A COVARIANCE MATRIX IS C REQUESTED, THE OPTION VECTOR C PRGOPT(*) IS NOT PROPERLY DEFINED, C OR THE LENGTHS OF THE WORKING ARRAYS C WS(*) AND IP(*), WHEN SPECIFIED IN C IP(1) AND IP(2) RESPECTIVELY, ARE NOT C LONG ENOUGH. C C W(*,*) THE ARRAY W(*,*) CONTAINS THE N BY N SYMMETRIC C COVARIANCE MATRIX OF THE SOLUTION PARAMETERS, C PROVIDED THIS WAS REQUESTED ON INPUT WITH C THE OPTION VECTOR PRGOPT(*) AND THE OUTPUT C FLAG IS RETURNED WITH MODE = 0 OR 1. C C IP(*) THE INTEGER WORKING ARRAY HAS THREE ENTRIES C THAT PROVIDE RANK AND WORKING ARRAY LENGTH C INFORMATION AFTER COMPLETION. C C IP(1) = RANK OF EQUALITY CONSTRAINT C MATRIX. DEFINE THIS QUANTITY C AS KRANKE. C C IP(2) = RANK OF REDUCED LEAST SQUARES C PROBLEM. C C IP(3) = THE AMOUNT OF STORAGE IN THE C WORKING ARRAY WS(*) THAT WAS C ACTUALLY USED BY THE SUBPROGRAM. C THE FORMULA GIVEN ABOVE FOR THE LENGTH C OF WS(*) IS A NECESSARY OVERESTIMATE. C USER DESIGNATED C WORKING ARRAYS.. C C WS(*),IP(*) THESE ARE RESP. TYPE FLOATING POINT C AND TYPE INTEGER WORKING ARRAYS. C THEIR REQUIRED MINIMAL LENGTHS ARE C GIVEN ABOVE. C C C SUBROUTINES CALLED C C LSI PART OF THIS PACKAGE. SOLVES A C CONSTRAINED LEAST SQUARES PROBLEM WITH C INEQUALITY CONSTRAINTS. C C++ C SDOT,SSCAL, SUBROUTINES FROM THE BLAS PACKAGE. C SAXPY,SASUM, SEE TRANS. MATH. SOFT., VOL. 5, NO. 3, P. 308. C SCOPY,SNRM2, C SSWAP C C H12 SUBROUTINE TO CONSTRUCT AND APPLY A C HOUSEHOLDER TRANSFORMATION. C C XERROR FROM SLATEC ERROR PROCESSING PACKAGE. C THIS IS DOCUMENTED IN SANDIA TECH. REPT., C SAND78-1189. C C SUBROUTINE LSEI(W,MDW,ME,MA,MG,N,PRGOPT,X,RNORME,RNORML,MODE,WS, C 1 IP) C C REVISED OCT. 1, 1981. C REAL W(MDW,1), PRGOPT(1), X(1), WS(1), RNORME, RNORML INTEGER IP(3) REAL DUMMY, ENORM, SRELPR, FNORM, GAM, HALF, ONE, RB, *RN, RNMAX, SIZE, SN, SNMAX, T, TAU, UJ, UP, VJ, XNORM, XNRME, ZERO REAL SASUM, SDOT, SNRM2, SQRT, ABS, AMAX1 LOGICAL COV DATA ZERO /0.E0/, SRELPR /0.E0/, HALF /0.5E0/, ONE /1.E0/ C C CHECK THAT ENOUGH STORAGE WAS ALLOCATED IN WS(*) AND IP(*). IF (.NOT.(IP(1).GT.0)) GO TO 20 LCHK = 2*(ME+N) + MAX0(MA+MG,N) + (MG+2)*(N+7) IF (.NOT.(IP(1).LT.LCHK)) GO TO 10 MODE = 4 NERR = 2 IOPT = 1 CALL XERRWV(67HLSEI( ), INSUFFICIENT STORAGE ALLOCATED FOR WS(*), *NEED LW=I1 BELOW, 67, NERR, IOPT, 1, LCHK, 0, * 0, DUMMY, DUMMY) RETURN 10 CONTINUE 20 IF (.NOT.(IP(2).GT.0)) GO TO 40 LCHK = MG + 2*N + 2 IF (.NOT.(IP(2).LT.LCHK)) GO TO 30 MODE = 4 NERR = 2 IOPT = 1 CALL XERRWV(68HLSEI( ), INSUFFICIENT STORAGE ALLOCATED FOR IP(*), *NEED LIP=I1 BELOW, 68, NERR, IOPT, 1, LCHK, 0, * 0, DUMMY, DUMMY) RETURN 30 CONTINUE C C COMPUTE MACHINE PRECISION=SRELPR ONLY WHEN NECESSARY. 40 IF (.NOT.(SRELPR.EQ.ZERO)) GO TO 70 SRELPR = ONE 50 IF (ONE+SRELPR.EQ.ONE) GO TO 60 SRELPR = SRELPR*HALF GO TO 50 60 SRELPR = SRELPR + SRELPR C C COMPUTE NUMBER OF POSSIBLE RIGHT MULTIPLYING HOUSEHOLDER C TRANSFORMATIONS. 70 M = ME + MA + MG MODE = 0 IF (N.LE.0 .OR. M.LE.0) RETURN IF (.NOT.(MDW.LT.M)) GO TO 80 NERR = 1 IOPT = 1 CALL XERROR(36HLSEI( ), MDW.LT.ME+MA+MG IS AN ERROR, 36, NERR, * IOPT) MODE = 4 RETURN 80 NP1 = N + 1 KRANKE = MIN0(ME,N) N1 = 2*KRANKE + 1 N2 = N1 + N C C PROCESS-OPTION-VECTOR ASSIGN 90 TO IGO990 GO TO 480 90 IF (.NOT.(COV .AND. MDW.LT.N)) GO TO 100 NERR = 2 IOPT = 1 CALL XERROR( * 54HLSEI( ), MDW.LT.N, WHEN COV MATRIX NEEDED, IS AN ERROR, 54, * NERR, IOPT) MODE = 4 RETURN 100 L = KRANKE C C COMPUTE NORM OF EQUALITY CONSTRAINT MATRIX AND RT SIDE. ENORM = ZERO DO 110 J=1,N ENORM = AMAX1(ENORM,SASUM(ME,W(1,J),1)) 110 CONTINUE FNORM = SASUM(ME,W(1,NP1),1) IF (.NOT.(L.GT.0)) GO TO 190 SNMAX = ZERO RNMAX = ZERO DO 180 I=1,L C C COMPUTE MAXIMUM RATIO OF VECTOR LENGTHS. PARTITION C IS AT COL. I. DO 150 K=I,ME SN = SDOT(N-I+1,W(K,I),MDW,W(K,I),MDW) RN = SDOT(I-1,W(K,1),MDW,W(K,1),MDW) IF (.NOT.(RN.EQ.ZERO .AND. SN.GT.SNMAX)) GO TO 120 SNMAX = SN IMAX = K GO TO 140 120 IF (.NOT.(K.EQ.I .OR. (SN*RNMAX.GT.RN*SNMAX))) GO TO 130 SNMAX = SN RNMAX = RN IMAX = K 130 CONTINUE 140 CONTINUE 150 CONTINUE C C INTERCHANGE ROWS IF NECESSARY. IF (I.NE.IMAX) CALL SSWAP(NP1, W(I,1), MDW, W(IMAX,1), MDW) IF (.NOT.(SNMAX.GT.TAU**2*RNMAX)) GO TO 160 C C ELIMINATE ELEMS I+1,...,N IN ROW I. CALL H12(1, I, I+1, N, W(I,1), MDW, WS(I), W(I+1,1), MDW, 1, * M-I) GO TO 170 160 KRANKE = I - 1 GO TO 200 170 CONTINUE 180 CONTINUE 190 CONTINUE 200 CONTINUE C C SAVE DIAG. TERMS OF LOWER TRAP. MATRIX. CALL SCOPY(KRANKE, W, MDW+1, WS(KRANKE+1), 1) C C USE HOUSEHOLDER TRANS FROM LEFT TO ACHIEVE KRANKE BY KRANKE UPPER C TRIANGULAR FORM. IF (.NOT.(KRANKE.GT.0 .AND. KRANKE.LT.ME)) GO TO 220 DO 210 KK=1,KRANKE K = KRANKE + 1 - KK C C APPLY TRANFORMATION TO MATRIX COLS. 1,...,K-1. CALL H12(1, K, KRANKE+1, ME, W(1,K), 1, UP, W, 1, MDW, K-1) C C APPLY TO RT SIDE VECTOR. CALL H12(2, K, KRANKE+1, ME, W(1,K), 1, UP, W(1,NP1), 1, 1, 1) 210 CONTINUE 220 IF (.NOT.(KRANKE.GT.0)) GO TO 240 C C SOLVE FOR VARIABLES 1,...,KRANKE IN NEW COORDINATES. CALL SCOPY(KRANKE, W(1,NP1), 1, X, 1) DO 230 I=1,KRANKE X(I) = (X(I)-SDOT(I-1,W(I,1),MDW,X,1))/W(I,I) 230 CONTINUE C C COMPUTE RESIDUALS FOR REDUCED PROBLEM. 240 MEP1 = ME + 1 RNORML = ZERO IF (.NOT.(ME.LT.M)) GO TO 270 DO 260 I=MEP1,M W(I,NP1) = W(I,NP1) - SDOT(KRANKE,W(I,1),MDW,X,1) SN = SDOT(KRANKE,W(I,1),MDW,W(I,1),MDW) RN = SDOT(N-KRANKE,W(I,KRANKE+1),MDW,W(I,KRANKE+1),MDW) IF (.NOT.(RN.LE.TAU**2*SN .AND. KRANKE.LT.N)) GO TO 250 W(I,KRANKE+1) = ZERO CALL SCOPY(N-KRANKE, W(I,KRANKE+1), 0, W(I,KRANKE+1), MDW) 250 CONTINUE 260 CONTINUE C C COMPUTE EQUAL. CONSTRAINT EQUAS. RESIDUAL LENGTH. 270 RNORME = SNRM2(ME-KRANKE,W(KRANKE+1,NP1),1) C C MOVE REDUCED PROBLEM DATA UPWARD IF KRANKE.LT.ME. IF (.NOT.(KRANKE.LT.ME)) GO TO 290 DO 280 J=1,NP1 CALL SCOPY(M-ME, W(ME+1,J), 1, W(KRANKE+1,J), 1) 280 CONTINUE C C COMPUTE SOLN OF REDUCED PROBLEM. 290 CALL LSI(W(KRANKE+1,KRANKE+1), MDW, MA, MG, N-KRANKE, PRGOPT, * X(KRANKE+1), RNORML, MODE, WS(N2), IP(2)) IF (.NOT.(ME.GT.0)) GO TO 330 C C TEST FOR CONSISTENCY OF EQUALITY CONSTRAINTS. MDEQC = 0 XNRME = SASUM(KRANKE,W(1,NP1),1) IF (RNORME.GT.TAU*(ENORM*XNRME+FNORM)) MDEQC = 1 MODE = MODE + MDEQC C C CHECK IF SOLN TO EQUAL. CONSTRAINTS SATISFIES INEQUAL. C CONSTRAINTS WHEN THERE ARE NO DEGREES OF FREEDOM LEFT. IF (.NOT.(KRANKE.EQ.N .AND. MG.GT.0)) GO TO 320 XNORM = SASUM(N,X,1) MAPKE1 = MA + KRANKE + 1 MEND = MA + KRANKE + MG DO 310 I=MAPKE1,MEND SIZE = SASUM(N,W(I,1),MDW)*XNORM + ABS(W(I,NP1)) IF (.NOT.(W(I,NP1).GT.TAU*SIZE)) GO TO 300 MODE = MODE + 2 GO TO 450 300 CONTINUE 310 CONTINUE 320 CONTINUE 330 IF (.NOT.(KRANKE.GT.0)) GO TO 420 C C REPLACE DIAG. TERMS OF LOWER TRAP. MATRIX. CALL SCOPY(KRANKE, WS(KRANKE+1), 1, W, MDW+1) C C REAPPLY TRANS TO PUT SOLN IN ORIGINAL COORDINATES. DO 340 II=1,KRANKE I = KRANKE + 1 - II CALL H12(2, I, I+1, N, W(I,1), MDW, WS(I), X, 1, 1, 1) 340 CONTINUE C C COMPUTE COV MATRIX OF EQUAL. CONSTRAINED PROBLEM. IF (.NOT.(COV)) GO TO 410 DO 400 JJ=1,KRANKE J = KRANKE + 1 - JJ IF (.NOT.(J.LT.N)) GO TO 390 RB = WS(J)*W(J,J) IF (RB.NE.ZERO) RB = ONE/RB JP1 = J + 1 DO 350 I=JP1,N W(I,J) = SDOT(N-J,W(I,JP1),MDW,W(J,JP1),MDW)*RB 350 CONTINUE GAM = SDOT(N-J,W(JP1,J),1,W(J,JP1),MDW)*RB GAM = HALF*GAM CALL SAXPY(N-J, GAM, W(J,JP1), MDW, W(JP1,J), 1) DO 370 I=JP1,N DO 360 K=I,N W(I,K) = W(I,K) + W(J,I)*W(K,J) + W(I,J)*W(J,K) W(K,I) = W(I,K) 360 CONTINUE 370 CONTINUE UJ = WS(J) VJ = GAM*UJ W(J,J) = UJ*VJ + UJ*VJ DO 380 I=JP1,N W(J,I) = UJ*W(I,J) + VJ*W(J,I) 380 CONTINUE CALL SCOPY(N-J, W(J,JP1), MDW, W(JP1,J), 1) 390 CONTINUE 400 CONTINUE 410 CONTINUE C C APPLY THE SCALING TO THE COVARIANCE MATRIX. 420 IF (.NOT.(COV)) GO TO 440 DO 430 I=1,N L = N1 + I CALL SSCAL(N, WS(L-1), W(I,1), MDW) CALL SSCAL(N, WS(L-1), W(1,I), 1) 430 CONTINUE 440 CONTINUE 450 CONTINUE C C RESCALE SOLN. VECTOR. IF (.NOT.(MODE.LE.1)) GO TO 470 DO 460 J=1,N L = N1 + J X(J) = X(J)*WS(L-1) 460 CONTINUE 470 IP(1) = KRANKE IP(3) = IP(3) + 2*KRANKE + N RETURN 480 CONTINUE C TO PROCESS-OPTION-VECTOR C C THE NOMINAL TOLERANCE USED IN THE CODE C FOR THE EQUALITY CONSTRAINT EQUATIONS. TAU = SQRT(SRELPR) C C THE NOMINAL COLUMN SCALING USED IN THE CODE IS C THE IDENTITY SCALING. WS(N1) = ONE CALL SCOPY(N, WS(N1), 0, WS(N1), 1) C C NO COVARIANCE MATRIX IS NOMINALLY COMPUTED. COV = .FALSE. C C DEFINE BOUND FOR NUMBER OF OPTIONS TO CHANGE. NOPT = 1000 NTIMES = 0 C C DEFINE BOUND FOR POSITIVE VALUES OF LINK. NLINK = 100000 LAST = 1 LINK = PRGOPT(1) IF (.NOT.(LINK.LE.0 .OR. LINK.GT.NLINK)) GO TO 490 NERR = 3 IOPT = 1 CALL XERROR(38HLSEI( ) THE OPTION VECTOR IS UNDEFINED, 38, NERR, * IOPT) MODE = 4 RETURN 490 IF (.NOT.(LINK.GT.1)) GO TO 540 NTIMES = NTIMES + 1 IF (.NOT.(NTIMES.GT.NOPT)) GO TO 500 NERR = 3 IOPT = 1 CALL XERROR( * 52HLSEI( ). THE LINKS IN THE OPTION VECTOR ARE CYCLING., 52, * NERR, IOPT) MODE = 4 RETURN 500 KEY = PRGOPT(LAST+1) IF (KEY.EQ.1) COV = PRGOPT(LAST+2).NE.ZERO IF (.NOT.(KEY.EQ.2 .AND. PRGOPT(LAST+2).NE.ZERO)) GO TO 520 DO 510 J=1,N T = SNRM2(M,W(1,J),1) IF (T.NE.ZERO) T = ONE/T L = N1 + J WS(L-1) = T 510 CONTINUE 520 IF (KEY.EQ.3) CALL SCOPY(N, PRGOPT(LAST+2), 1, WS(N1), 1) IF (KEY.EQ.4) TAU = AMAX1(SRELPR,PRGOPT(LAST+2)) NEXT = PRGOPT(LINK) IF (.NOT.(NEXT.LE.0 .OR. NEXT.GT.NLINK)) GO TO 530 NERR = 3 IOPT = 1 CALL XERROR(38HLSEI( ) THE OPTION VECTOR IS UNDEFINED, 38, NERR, * IOPT) MODE = 4 RETURN 530 LAST = LINK LINK = NEXT GO TO 490 540 DO 550 J=1,N L = N1 + J CALL SSCAL(M, WS(L-1), W(1,J), 1) 550 CONTINUE GO TO 560 560 GO TO IGO990, (90) END SUBROUTINE LSI(W, MDW, MA, MG, N, PRGOPT, X, RNORM, MODE, WS, IP) LSI 10 C C THE EDITING REQUIRED TO CONVERT THIS SUBROUTINE FROM SINGLE TO C DOUBLE PRECISION INVOLVES THE FOLLOWING CHARACTER STRING CHANGES. C USE AN EDITING COMMAND (CHANGE) /STRING-1/(TO)STRING-2/. C (START EDITING AT LINE WITH C++ IN COLS. 1-3.) C /REAL (12 BLANKS)/DOUBLE PRECISION/,/SASUM/DASUM/,/SDOT/DDOT/, C / SQRT/ DSQRT/,/AMAX1/DMAX1/,/SSWAP/DSWAP/, C /SCOPY/DCOPY/,/SSCAL/DSCAL/,/SAXPY/DAXPY/,/E0/D0/,/SRELPR/DRELPR/ C C THIS IS A COMPANION SUBPROGRAM TO LSEI( ). C THE DOCUMENTATION FOR LSEI( ) HAS MORE COMPLETE C USAGE INSTRUCTIONS. C WRITTEN BY R. J. HANSON, SLA. C C SOLVE.. C AX = B, A MA BY N (LEAST SQUARES EQUATIONS) C SUBJECT TO.. C C GX.GE.H, G MG BY N (INEQUALITY CONSTRAINTS) C C INPUT.. C C W(*,*) CONTAINS (A B) IN ROWS 1,...,MA+MG, COLS 1,...,N+1. C (G H) C C MDW,MA,MG,N C CONTAIN (RESP) VAR. DIMENSION OF W(*,*), C AND MATRIX DIMENSIONS. C C PRGOPT(*), C PROGRAM OPTION VECTOR. C C OUTPUT.. C C X(*),RNORM C C SOLUTION VECTOR(UNLESS MODE=2), LENGTH OF AX-B. C C MODE C =0 INEQUALITY CONSTRAINTS ARE COMPATIBLE. C =2 INEQUALITY CONSTRAINTS CONTRADICTORY. C C WS(*), C WORKING STORAGE OF DIMENSION K+N+(MG+2)*(N+7), C WHERE K=MAX(MA+MG,N). C IP(MG+2*N+1) C INTEGER WORKING STORAGE C REVISED OCT. 1, 1981. C C SUBROUTINES CALLED C C LPDP THIS SUBPROGRAM MINIMIZES A SUM OF SQUARES C OF UNKNOWNS SUBJECT TO LINEAR INEQUALITY C CONSTRAINTS. PART OF THIS PACKAGE. C C++ C SDOT,SSCAL SUBROUTINES FROM THE BLAS PACKAGE. C SAXPY,SASUM, SEE TRANS. MATH. SOFT., VOL. 5, NO. 3, P. 308. C SCOPY,SSWAP C C HFTI SOLVES AN UNCONSTRAINED LINEAR LEAST SQUARES C PROBLEM. PART OF THIS PACKAGE. C C H12 SUBROUTINE TO CONSTRUCT AND APPLY A HOUSEHOLDER C TRANSFORMATION. C C SUBROUTINE LSI(W,MDW,MA,MG,N,PRGOPT,X,RNORM,MODE,WS,IP) C REAL W(MDW,1), PRGOPT(1), RNORM, WS(1), X(1) INTEGER IP(1) REAL ANORM, SRELPR, FAC, GAM, HALF, ONE, RB, TAU, TOL, * XNORM, ZERO REAL SASUM, SDOT, SQRT, AMAX1 LOGICAL COV C DATA ZERO /0.E0/, SRELPR /0.E0/, ONE /1.E0/, HALF /.5E0/ C C COMPUTE MACHINE PRECISION=SRELPR ONLY WHEN NECESSARY. IF (.NOT.(SRELPR.EQ.ZERO)) GO TO 30 SRELPR = ONE 10 IF (ONE+SRELPR.EQ.ONE) GO TO 20 SRELPR = SRELPR*HALF GO TO 10 20 SRELPR = SRELPR + SRELPR 30 MODE = 0 RNORM = ZERO M = MA + MG NP1 = N + 1 KRANK = 0 IF (N.LE.0 .OR. M.LE.0) GO TO 70 ASSIGN 40 TO IGO994 GO TO 500 C C PROCESS-OPTION-VECTOR C C COMPUTE MATRIX NORM OF LEAST SQUARES EQUAS. 40 ANORM = ZERO DO 50 J=1,N ANORM = AMAX1(ANORM,SASUM(MA,W(1,J),1)) 50 CONTINUE C C SET TOL FOR HFTI( ) RANK TEST. TAU = TOL*ANORM C C COMPUTE HOUSEHOLDER ORTHOGONAL DECOMP OF MATRIX. IF (N.GT.0) WS(1) = ZERO CALL SCOPY(N, WS, 0, WS, 1) CALL SCOPY(MA, W(1,NP1), 1, WS, 1) K = MAX0(M,N) MINMAN = MIN0(MA,N) N1 = K + 1 N2 = N1 + N CALL HFTI(W, MDW, MA, N, WS, 1, 1, TAU, KRANK, RNORM, WS(N2), * WS(N1), IP) FAC = ONE GAM=MA-KRANK IF (KRANK.LT.MA) FAC = RNORM**2/GAM ASSIGN 60 TO IGO990 GO TO 80 C C REDUCE-TO-LPDP-AND-SOLVE 60 CONTINUE 70 IP(1) = KRANK IP(2) = N + MAX0(M,N) + (MG+2)*(N+7) RETURN 80 CONTINUE C C TO REDUCE-TO-LPDP-AND-SOLVE MAP1 = MA + 1 C C COMPUTE INEQ. RT-HAND SIDE FOR LPDP. IF (.NOT.(MA.LT.M)) GO TO 260 IF (.NOT.(MINMAN.GT.0)) GO TO 160 DO 90 I=MAP1,M W(I,NP1) = W(I,NP1) - SDOT(N,W(I,1),MDW,WS,1) 90 CONTINUE DO 100 I=1,MINMAN J = IP(I) C C APPLY PERMUTATIONS TO COLS OF INEQ. CONSTRAINT MATRIX. CALL SSWAP(MG, W(MAP1,I), 1, W(MAP1,J), 1) 100 CONTINUE C C APPLY HOUSEHOLDER TRANSFORMATIONS TO CONSTRAINT MATRIX. IF (.NOT.(0.LT.KRANK .AND. KRANK.LT.N)) GO TO 120 DO 110 II=1,KRANK I = KRANK + 1 - II L = N1 + I CALL H12(2, I, KRANK+1, N, W(I,1), MDW, WS(L-1), W(MAP1,1), * MDW, 1, MG) 110 CONTINUE C C COMPUTE PERMUTED INEQ. CONSTR. MATRIX TIMES R-INVERSE. 120 DO 150 I=MAP1,M IF (.NOT.(0.LT.KRANK)) GO TO 140 DO 130 J=1,KRANK W(I,J) = (W(I,J)-SDOT(J-1,W(1,J),1,W(I,1),MDW))/W(J,J) 130 CONTINUE 140 CONTINUE 150 CONTINUE C C SOLVE THE REDUCED PROBLEM WITH LPDP ALGORITHM, C THE LEAST PROJECTED DISTANCE PROBLEM. 160 CALL LPDP(W(MAP1,1), MDW, MG, KRANK, N-KRANK, PRGOPT, X, XNORM, * MDLPDP, WS(N2), IP(N+1)) IF (.NOT.(MDLPDP.EQ.1)) GO TO 240 IF (.NOT.(KRANK.GT.0)) GO TO 180 C C COMPUTE SOLN IN ORIGINAL COORDINATES. DO 170 II=1,KRANK I = KRANK + 1 - II X(I) = (X(I)-SDOT(II-1,W(I,I+1),MDW,X(I+1),1))/W(I,I) 170 CONTINUE C C APPLY HOUSEHOLDER TRANS. TO SOLN VECTOR. 180 IF (.NOT.(0.LT.KRANK .AND. KRANK.LT.N)) GO TO 200 DO 190 I=1,KRANK L = N1 + I CALL H12(2, I, KRANK+1, N, W(I,1), MDW, WS(L-1), X, 1, 1, 1) 190 CONTINUE 200 IF (.NOT.(MINMAN.GT.0)) GO TO 230 C C REPERMUTE VARIABLES TO THEIR INPUT ORDER. DO 210 II=1,MINMAN I = MINMAN + 1 - II J = IP(I) CALL SSWAP(1, X(I), 1, X(J), 1) 210 CONTINUE C C VARIABLES ARE NOW IN ORIG. COORDINATES. C ADD SOLN OF UNSCONSTRAINED PROB. DO 220 I=1,N X(I) = X(I) + WS(I) 220 CONTINUE C C COMPUTE THE RESIDUAL VECTOR NORM. RNORM = SQRT(RNORM**2+XNORM**2) 230 GO TO 250 240 MODE = 2 250 GO TO 270 260 CALL SCOPY(N, WS, 1, X, 1) 270 IF (.NOT.(COV .AND. KRANK.GT.0)) GO TO 490 C C COMPUTE COVARIANCE MATRIX BASED ON THE ORTHOGONAL DECOMP. C FROM HFTI( ). C KRM1 = KRANK - 1 KRP1 = KRANK + 1 C C COPY DIAG. TERMS TO WORKING ARRAY. CALL SCOPY(KRANK, W, MDW+1, WS(N2), 1) C C RECIPROCATE DIAG. TERMS. DO 280 J=1,KRANK W(J,J) = ONE/W(J,J) 280 CONTINUE IF (.NOT.(KRANK.GT.1)) GO TO 310 C C INVERT THE UPPER TRIANGULAR QR FACTOR ON ITSELF. DO 300 I=1,KRM1 IP1 = I + 1 DO 290 J=IP1,KRANK W(I,J) = -SDOT(J-I,W(I,I),MDW,W(I,J),1)*W(J,J) 290 CONTINUE 300 CONTINUE C C COMPUTE THE INVERTED FACTOR TIMES ITS TRANSPOSE. 310 DO 330 I=1,KRANK DO 320 J=I,KRANK W(I,J) = SDOT(KRANK+1-J,W(I,J),MDW,W(J,J),MDW) 320 CONTINUE 330 CONTINUE IF (.NOT.(KRANK.LT.N)) GO TO 450 C C ZERO OUT LOWER TRAPEZOIDAL PART. C COPY UPPER TRI. TO LOWER TRI. PART. DO 340 J=1,KRANK CALL SCOPY(J, W(1,J), 1, W(J,1), MDW) 340 CONTINUE DO 350 I=KRP1,N W(I,1) = ZERO CALL SCOPY(I, W(I,1), 0, W(I,1), MDW) 350 CONTINUE C C APPLY RIGHT SIDE TRANSFORMATIONS TO LOWER TRI. N3 = N2 + KRP1 DO 430 I=1,KRANK L = N1 + I K = N2 + I RB = WS(L-1)*WS(K-1) IF (.NOT.(RB.LT.ZERO)) GO TO 420 C C IF RB.GE.ZERO, TRANSFORMATION CAN BE REGARDED AS ZERO. RB = ONE/RB C C STORE UNSCALED RANK-ONE HOUSEHOLDER UPDATE IN WORK ARRAY. WS(N3) = ZERO CALL SCOPY(N, WS(N3), 0, WS(N3), 1) L = N1 + I K = N3 + I WS(K-1) = WS(L-1) DO 360 J=KRP1,N K = N3 + J WS(K-1) = W(I,J) 360 CONTINUE DO 370 J=1,N L = N3 + I K = N3 + J WS(J) = SDOT(J-I,W(J,I),MDW,WS(L-1),1) + SDOT(N-J+1,W(J,J),1, * WS(K-1),1) WS(J) = WS(J)*RB 370 CONTINUE L = N3 + I GAM = SDOT(N-I+1,WS(L-1),1,WS(I),1)*RB GAM = GAM*HALF CALL SAXPY(N-I+1, GAM, WS(L-1), 1, WS(I), 1) DO 410 J=I,N IF (.NOT.(I.GT.1)) GO TO 390 IM1 = I - 1 K = N3 + J DO 380 L=1,IM1 W(J,L) = W(J,L) + WS(K-1)*WS(L) 380 CONTINUE 390 K = N3 + J DO 400 L=I,J IL = N3 + L W(J,L) = W(J,L) + WS(J)*WS(IL-1) + WS(L)*WS(K-1) 400 CONTINUE 410 CONTINUE 420 CONTINUE 430 CONTINUE C C COPY LOWER TRI. TO UPPER TRI. TO SYMMETRIZE THE COVARIANCE MATRIX. DO 440 I=1,N CALL SCOPY(I, W(I,1), MDW, W(1,I), 1) 440 CONTINUE C C REPERMUTE ROWS AND COLS. 450 DO 470 II=1,MINMAN I = MINMAN + 1 - II K = IP(I) IF (.NOT.(I.NE.K)) GO TO 460 CALL SSWAP(1, W(I,I), 1, W(K,K), 1) CALL SSWAP(I-1, W(1,I), 1, W(1,K), 1) CALL SSWAP(K-I-1, W(I,I+1), MDW, W(I+1,K), 1) CALL SSWAP(N-K, W(I,K+1), MDW, W(K,K+1), MDW) 460 CONTINUE 470 CONTINUE C C PUT IN NORMALIZED RESIDUAL SUM OF SQUARES SCALE FACTOR C AND SYMMETRIZE THE RESULTING COVARIANCE MARIX. DO 480 J=1,N CALL SSCAL(J, FAC, W(1,J), 1) CALL SCOPY(J, W(1,J), 1, W(J,1), MDW) 480 CONTINUE 490 GO TO 540 500 CONTINUE C C TO PROCESS-OPTION-VECTOR C C THE NOMINAL TOLERANCE USED IN THE CODE, TOL = SQRT(SRELPR) COV = .FALSE. LAST = 1 LINK = PRGOPT(1) 510 IF (.NOT.(LINK.GT.1)) GO TO 520 KEY = PRGOPT(LAST+1) IF (KEY.EQ.1) COV = PRGOPT(LAST+2).NE.ZERO IF (KEY.EQ.5) TOL = AMAX1(SRELPR,PRGOPT(LAST+2)) NEXT = PRGOPT(LINK) LAST = LINK LINK = NEXT GO TO 510 520 GO TO 530 530 GO TO IGO994, (40) 540 GO TO IGO990, (60) END SUBROUTINE LPDP(A, MDA, M, N1, N2, PRGOPT, X, WNORM, MODE, WS, IS)LPDP 10 C C THE EDITING REQUIRED TO CONVERT THIS SUBROUTINE FROM SINGLE TO C DOUBLE PRECISION INVOLVES THE FOLLOWING CHARACTER STRING CHANGES. C USE AN EDITING COMMAND (CHANGE) /STRING-1/(TO)STRING-2/. C (START EDITING AT LINE WITH C++ IN COLS. 1-3.) C /REAL (12 BLANKS)/DOUBLE PRECISION/,/SNRM2/DNRM2/,/SDOT/DDOT/, C /SCOPY/DCOPY/,/SSCAL/DSCAL/,/ABS(/DABS(/, ABS/, DABS/,/E0/D0/ C C DIMENSION A(MDA,N+1),PRGOPT(*),X(N),WS((M+2)*(N+7)),IS(M+N+1), C WHERE N=N1+N2. THIS IS A SLIGHT OVERESTIMATE FOR WS(*). C C WRITTEN BY R. J. HANSON AND K. H. HASKELL, SANDIA LABS C REVISED OCT. 1, 1981. C C DETERMINE AN N1-VECTOR W, AND C AN N2-VECTOR Z C WHICH MINIMIZES THE EUCLIDEAN LENGTH OF W C SUBJECT TO G*W+H*Z .GE. Y. C THIS IS THE LEAST PROJECTED DISTANCE PROBLEM, LPDP. C THE MATRICES G AND H ARE OF RESPECTIVE C DIMENSIONS M BY N1 AND M BY N2. C C CALLED BY SUBPROGRAM LSI( ). C C THE MATRIX C (G H Y) C C OCCUPIES ROWS 1,...,M AND COLS 1,...,N1+N2+1 OF A(*,*). C C THE SOLUTION (W) IS RETURNED IN X(*). C (Z) C C THE VALUE OF MODE INDICATES THE STATUS OF C THE COMPUTATION AFTER RETURNING TO THE USER. C C MODE=1 THE SOLUTION WAS SUCCESSFULLY OBTAINED. C C MODE=2 THE INEQUALITIES ARE INCONSISTENT. C C SUBROUTINES CALLED C C WNNLS SOLVES A NONNEGATIVELY CONSTRAINED LINEAR LEAST C SQUARES PROBLEM WITH LINEAR EQUALITY CONSTRAINTS. C PART OF THIS PACKAGE. C C++ C SDOT, SUBROUTINES FROM THE BLAS PACKAGE. C SSCAL,SNRM2, SEE TRANS. MATH. SOFT., VOL. 5, NO. 3, P. 308. C SCOPY C REAL A(MDA,1), PRGOPT(1), WS(1), WNORM, X(1) INTEGER IS(1) REAL FAC, ONE, RNORM, SC, YNORM, ZERO REAL SDOT, SNRM2, ABS DATA ZERO, ONE /0.E0,1.E0/, FAC /0.1E0/ N = N1 + N2 MODE = 1 IF (.NOT.(M.LE.0)) GO TO 20 IF (.NOT.(N.GT.0)) GO TO 10 X(1) = ZERO CALL SCOPY(N, X, 0, X, 1) 10 WNORM = ZERO RETURN 20 NP1 = N + 1 C C SCALE NONZERO ROWS OF INEQUALITY MATRIX TO HAVE LENGTH ONE. DO 40 I=1,M SC = SNRM2(N,A(I,1),MDA) IF (.NOT.(SC.NE.ZERO)) GO TO 30 SC = ONE/SC CALL SSCAL(NP1, SC, A(I,1), MDA) 30 CONTINUE 40 CONTINUE C C SCALE RT.-SIDE VECTOR TO HAVE LENGTH ONE (OR ZERO). YNORM = SNRM2(M,A(1,NP1),1) IF (.NOT.(YNORM.NE.ZERO)) GO TO 50 SC = ONE/YNORM CALL SSCAL(M, SC, A(1,NP1), 1) C C SCALE COLS OF MATRIX H. 50 J = N1 + 1 60 IF (.NOT.(J.LE.N)) GO TO 70 SC = SNRM2(M,A(1,J),1) IF (SC.NE.ZERO) SC = ONE/SC CALL SSCAL(M, SC, A(1,J), 1) X(J) = SC J = J + 1 GO TO 60 70 IF (.NOT.(N1.GT.0)) GO TO 130 C C COPY TRANSPOSE OF (H G Y) TO WORK ARRAY WS(*). IW = 0 DO 80 I=1,M C C MOVE COL OF TRANSPOSE OF H INTO WORK ARRAY. CALL SCOPY(N2, A(I,N1+1), MDA, WS(IW+1), 1) IW = IW + N2 C C MOVE COL OF TRANSPOSE OF G INTO WORK ARRAY. CALL SCOPY(N1, A(I,1), MDA, WS(IW+1), 1) IW = IW + N1 C C MOVE COMPONENT OF VECTOR Y INTO WORK ARRAY. WS(IW+1) = A(I,NP1) IW = IW + 1 80 CONTINUE WS(IW+1) = ZERO CALL SCOPY(N, WS(IW+1), 0, WS(IW+1), 1) IW = IW + N WS(IW+1) = ONE IW = IW + 1 C C SOLVE EU=F SUBJECT TO (TRANSPOSE OF H)U=0, U.GE.0. THE C MATRIX E = TRANSPOSE OF (G Y), AND THE (N+1)-VECTOR C F = TRANSPOSE OF (0,...,0,1). IX = IW + 1 IW = IW + M C C DO NOT CHECK LENGTHS OF WORK ARRAYS IN THIS USAGE OF WNNLS( ). IS(1) = 0 IS(2) = 0 CALL WNNLS(WS, NP1, N2, NP1-N2, M, 0, PRGOPT, WS(IX), RNORM, * MODEW, IS, WS(IW+1)) C C COMPUTE THE COMPONENTS OF THE SOLN DENOTED ABOVE BY W. SC = ONE - SDOT(M,A(1,NP1),1,WS(IX),1) IF (.NOT.(ONE+FAC*ABS(SC).NE.ONE .AND. RNORM.GT.ZERO)) GO TO 110 SC = ONE/SC DO 90 J=1,N1 X(J) = SC*SDOT(M,A(1,J),1,WS(IX),1) 90 CONTINUE C C COMPUTE THE VECTOR Q=Y-GW. OVERWRITE Y WITH THIS VECTOR. DO 100 I=1,M A(I,NP1) = A(I,NP1) - SDOT(N1,A(I,1),MDA,X,1) 100 CONTINUE GO TO 120 110 MODE = 2 RETURN 120 CONTINUE 130 IF (.NOT.(N2.GT.0)) GO TO 180 C C COPY TRANSPOSE OF (H Q) TO WORK ARRAY WS(*). IW = 0 DO 140 I=1,M CALL SCOPY(N2, A(I,N1+1), MDA, WS(IW+1), 1) IW = IW + N2 WS(IW+1) = A(I,NP1) IW = IW + 1 140 CONTINUE WS(IW+1) = ZERO CALL SCOPY(N2, WS(IW+1), 0, WS(IW+1), 1) IW = IW + N2 WS(IW+1) = ONE IW = IW + 1 IX = IW + 1 IW = IW + M C C SOLVE RV=S SUBJECT TO V.GE.0. THE MATRIX R =(TRANSPOSE C OF (H Q)), WHERE Q=Y-GW. THE (N2+1)-VECTOR S =(TRANSPOSE C OF (0,...,0,1)). C C DO NOT CHECK LENGTHS OF WORK ARRAYS IN THIS USAGE OF WNNLS( ). IS(1) = 0 IS(2) = 0 CALL WNNLS(WS, N2+1, 0, N2+1, M, 0, PRGOPT, WS(IX), RNORM, MODEW, * IS, WS(IW+1)) C C COMPUTE THE COMPONENTS OF THE SOLN DENOTED ABOVE BY Z. SC = ONE - SDOT(M,A(1,NP1),1,WS(IX),1) IF (.NOT.(ONE+FAC*ABS(SC).NE.ONE .AND. RNORM.GT.ZERO)) GO TO 160 SC = ONE/SC DO 150 J=1,N2 L = N1 + J X(L) = SC*SDOT(M,A(1,L),1,WS(IX),1)*X(L) 150 CONTINUE GO TO 170 160 MODE = 2 RETURN 170 CONTINUE C C ACCOUNT FOR SCALING OF RT.-SIDE VECTOR IN SOLUTION. 180 CALL SSCAL(N, YNORM, X, 1) WNORM = SNRM2(N1,X,1) RETURN END SUBROUTINE WNNLS(W, MDW, ME, MA, N, L, PRGOPT, X, RNORM, MODE, WNN 10 * IWORK, WORK) C C DIMENSION W(MDW,N+1),PRGOPT(*),X(N),IWORK(M+N),WORK(M+5*N) C C ABSTRACT C C THIS SUBPROGRAM SOLVES A LINEARLY CONSTRAINED LEAST SQUARES C PROBLEM. SUPPOSE THERE ARE GIVEN MATRICES E AND A OF C RESPECTIVE DIMENSIONS ME BY N AND MA BY N, AND VECTORS F C AND B OF RESPECTIVE LENGTHS ME AND MA. THIS SUBROUTINE C SOLVES THE PROBLEM C C EX = F, (EQUATIONS TO BE EXACTLY SATISFIED) C C AX = B, (EQUATIONS TO BE APPROXIMATELY SATISFIED, C IN THE LEAST SQUARES SENSE) C C SUBJECT TO COMPONENTS L+1,...,N NONNEGATIVE C C ANY VALUES ME.GE.0, MA.GE.0 AND 0.LE. L .LE.N ARE PERMITTED. C C THE PROBLEM IS REPOSED AS PROBLEM WNNLS C C (WT*E)X = (WT*F) C ( A) ( B), (LEAST SQUARES) C SUBJECT TO COMPONENTS L+1,...,N NONNEGATIVE. C C THE SUBPROGRAM CHOOSES THE HEAVY WEIGHT (OR PENALTY PARAMETER) WT. C C THE PARAMETERS FOR WNNLS ARE C C INPUT.. C C W(*,*),MDW, THE ARRAY W(*,*) IS DOUBLE SUBSCRIPTED WITH FIRST C ME,MA,N,L DIMENSIONING PARAMETER EQUAL TO MDW. FOR THIS C DISCUSSION LET US CALL M = ME + MA. THEN MDW C MUST SATISFY MDW.GE.M. THE CONDITION MDW.LT.M C IS AN ERROR. C C THE ARRAY W(*,*) CONTAINS THE MATRICES AND VECTORS C C (E F) C (A B) C C IN ROWS AND COLUMNS 1,...,M AND 1,...,N+1 C RESPECTIVELY. COLUMNS 1,...,L CORRESPOND TO C UNCONSTRAINED VARIABLES X(1),...,X(L). THE C REMAINING VARIABLES ARE CONSTRAINED TO BE C NONNEGATIVE. THE CONDITION L.LT.0 .OR. L.GT.N IS C AN ERROR. C C PRGOPT(*) THIS ARRAY IS THE OPTION VECTOR. C IF THE USER IS SATISFIED WITH THE NOMINAL C SUBPROGRAM FEATURES SET C C PRGOPT(1)=1 (OR PRGOPT(1)=1.0) C C OTHERWISE PRGOPT(*) IS A LINKED LIST CONSISTING OF C GROUPS OF DATA OF THE FOLLOWING FORM C C LINK C KEY C DATA SET C C THE PARAMETERS LINK AND KEY ARE EACH ONE WORD. C THE DATA SET CAN BE COMPRISED OF SEVERAL WORDS. C THE NUMBER OF ITEMS DEPENDS ON THE VALUE OF KEY. C THE VALUE OF LINK POINTS TO THE FIRST C ENTRY OF THE NEXT GROUP OF DATA WITHIN C PRGOPT(*). THE EXCEPTION IS WHEN THERE ARE C NO MORE OPTIONS TO CHANGE. IN THAT C CASE LINK=1 AND THE VALUES KEY AND DATA SET C ARE NOT REFERENCED. THE GENERAL LAYOUT OF C PRGOPT(*) IS AS FOLLOWS. C C ...PRGOPT(1)=LINK1 (LINK TO FIRST ENTRY OF NEXT GROUP) C . PRGOPT(2)=KEY1 (KEY TO THE OPTION CHANGE) C . PRGOPT(3)=DATA VALUE (DATA VALUE FOR THIS CHANGE) C . . C . . C . . C ...PRGOPT(LINK1)=LINK2 (LINK TO THE FIRST ENTRY OF C . NEXT GROUP) C . PRGOPT(LINK1+1)=KEY2 (KEY TO THE OPTION CHANGE) C . PRGOPT(LINK1+2)=DATA VALUE C ... . C . . C . . C ...PRGOPT(LINK)=1 (NO MORE OPTIONS TO CHANGE) C C VALUES OF LINK THAT ARE NONPOSITIVE ARE ERRORS. C A VALUE OF LINK.GT.NLINK=100000 IS ALSO AN ERROR. C THIS HELPS PREVENT USING INVALID BUT POSITIVE C VALUES OF LINK THAT WILL PROBABLY EXTEND C BEYOND THE PROGRAM LIMITS OF PRGOPT(*). C UNRECOGNIZED VALUES OF KEY ARE IGNORED. THE C ORDER OF THE OPTIONS IS ARBITRARY AND ANY NUMBER C OF OPTIONS CAN BE CHANGED WITH THE FOLLOWING C RESTRICTION. TO PREVENT CYCLING IN THE C PROCESSING OF THE OPTION ARRAY A COUNT OF THE C NUMBER OF OPTIONS CHANGED IS MAINTAINED. C WHENEVER THIS COUNT EXCEEDS NOPT=1000 AN ERROR C MESSAGE IS PRINTED AND THE SUBPROGRAM RETURNS. C C OPTIONS.. C C KEY=6 C SCALE THE NONZERO COLUMNS OF THE C ENTIRE DATA MATRIX C (E) C (A) C TO HAVE LENGTH ONE. THE DATA SET FOR C THIS OPTION IS A SINGLE VALUE. IT MUST C BE NONZERO IF UNIT LENGTH COLUMN SCALING IS C DESIRED. C C KEY=7 C SCALE COLUMNS OF THE ENTIRE DATA MATRIX C (E) C (A) C WITH A USER-PROVIDED DIAGONAL MATRIX. C THE DATA SET FOR THIS OPTION CONSISTS C OF THE N DIAGONAL SCALING FACTORS, ONE FOR C EACH MATRIX COLUMN. C C KEY=8 C CHANGE THE RANK DETERMINATION TOLERANCE FROM C THE NOMINAL VALUE OF SQRT(EPS). THIS QUANTITY CAN C BE NO SMALLER THAN EPS, THE ARITHMETIC- C STORAGE PRECISION. THE QUANTITY USED C HERE IS INTERNALLY RESTRICTED TO BE AT C LEAST EPS. THE DATA SET FOR THIS OPTION C IS THE NEW TOLERANCE. C C KEY=9 C CHANGE THE BLOW-UP PARAMETER FROM THE C NOMINAL VALUE OF SQRT(EPS). THE RECIPROCAL OF C THIS PARAMETER IS USED IN REJECTING SOLUTION C COMPONENTS AS TOO LARGE WHEN A VARIABLE IS C FIRST BROUGHT INTO THE ACTIVE SET. TOO LARGE C MEANS THAT THE PROPOSED COMPONENT TIMES THE C RECIPROCAL OF THE PARAMETERIS NOT LESS THAN C THE RATIO OF THE NORMS OF THE RIGHT-SIDE C VECTOR AND THE DATA MATRIX. C THIS PARAMETER CAN BE NO SMALLER THAN EPS, C THE ARITHMETIC-STORAGE PRECISION. C C FOR EXAMPLE, SUPPOSE WE WANT TO PROVIDE C A DIAGONAL MATRIX TO SCALE THE PROBLEM C MATRIX AND CHANGE THE TOLERANCE USED FOR C DETERMINING LINEAR DEPENDENCE OF DROPPED COL C VECTORS. FOR THESE OPTIONS THE DIMENSIONS OF C PRGOPT(*) MUST BE AT LEAST N+6. THE FORTRAN C STATEMENTS DEFINING THESE OPTIONS WOULD C BE AS FOLLOWS. C C PRGOPT(1)=N+3 (LINK TO ENTRY N+3 IN PRGOPT(*)) C PRGOPT(2)=7 (USER-PROVIDED SCALING KEY) C C CALL SCOPY(N,D,1,PRGOPT(3),1) (COPY THE N C SCALING FACTORS FROM A USER ARRAY CALLED D(*) C INTO PRGOPT(3)-PRGOPT(N+2)) C C PRGOPT(N+3)=N+6 (LINK TO ENTRY N+6 OF PRGOPT(*)) C PRGOPT(N+4)=8 (LINEAR DEPENDENCE TOLERANCE KEY) C PRGOPT(N+5)=... (NEW VALUE OF THE TOLERANCE) C C PRGOPT(N+6)=1 (NO MORE OPTIONS TO CHANGE) C C IWORK(1), THE AMOUNTS OF WORKING STORAGE ACTUALLY ALLOCATED C IWORK(2) FOR THE WORKING ARRAYS WORK(*) AND IWORK(*), C RESPECTIVELY. THESE QUANTITIES ARE COMPARED WITH C THE ACTUAL AMOUNTS OF STORAGE NEEDED FOR WNNLS( ). C INSUFFICIENT STORAGE ALLOCATED FOR EITHER WORK(*) C OR IWORK(*) IS CONSIDERED AN ERROR. THIS FEATURE C WAS INCLUDED IN WNNLS( ) BECAUSE MISCALCULATING C THE STORAGE FORMULAS FOR WORK(*) AND IWORK(*) C MIGHT VERY WELL LEAD TO SUBTLE AND HARD-TO-FIND C EXECUTION ERRORS. C C THE LENGTH OF WORK(*) MUST BE AT LEAST C C LW = ME+MA+5*N C THIS TEST WILL NOT BE MADE IF IWORK(1).LE.0. C C THE LENGTH OF IWORK(*) MUST BE AT LEAST C C LIW = ME+MA+N C THIS TEST WILL NOT BE MADE IF IWORK(2).LE.0. C C OUTPUT.. C C X(*) AN ARRAY DIMENSIONED AT LEAST N, WHICH WILL C CONTAIN THE N COMPONENTS OF THE SOLUTION VECTOR C ON OUTPUT. C C RNORM THE RESIDUAL NORM OF THE SOLUTION. THE VALUE OF C RNORM CONTAINS THE RESIDUAL VECTOR LENGTH OF THE C EQUALITY CONSTRAINTS AND LEAST SQUARES EQUATIONS. C C MODE THE VALUE OF MODE INDICATES THE SUCCESS OR FAILURE C OF THE SUBPROGRAM. C C MODE = 0 SUBPROGRAM COMPLETED SUCCESSFULLY. C C = 1 MAX. NUMBER OF ITERATIONS (EQUAL TO C 3*(N-L)) EXCEEDED. NEARLY ALL PROBLEMS C SHOULD COMPLETE IN FEWER THAN THIS C NUMBER OF ITERATIONS. AN APPROXIMATE C SOLUTION AND ITS CORRESPONDING RESIDUAL C VECTOR LENGTH ARE IN X(*) AND RNORM. C C = 2 USAGE ERROR OCCURRED. THE OFFENDING C CONDITION IS NOTED WITH THE ERROR C PROCESSING SUBPROGRAM, XERROR( ). C C USER-DESIGNATED C WORKING ARRAYS.. C C WORK(*) A WORKING ARRAY OF LENGTH AT LEAST C M + 5*N. C C IWORK(*) AN INTEGER-VALUED WORKING ARRAY OF LENGTH AT LEAST C M+N. C C THE EDITING REQUIRED TO CONVERT THIS SUBROUTINE FROM SINGLE TO C DOUBLE PRECISION INVOLVES THE FOLLOWING CHARACTER STRING CHANGES. C USE AN EDITING COMMAND (CHANGE) /STRING-1/(TO)STRING-2/. C (START AT LINE WITH C++ IN COLS. 1-3.) C /REAL (12 BLANKS)/DOUBLE PRECISION/,/, DUMMY/,SNGL(DUMMY)/ C C WRITTEN BY KAREN H. HASKELL, SANDIA LABORATORIES, C AND R.J. HANSON, SANDIA LABORATORIES. C REVISED FEB.25, 1982. C C SUBROUTINES CALLED BY WNNLS( ) C C++ C WNLSM COMPANION SUBROUTINE TO WNNLS( ), WHERE C MOST OF THE COMPUTATION TAKES PLACE. C C XERROR,XERRWV FROM SLATEC ERROR PROCESSING PACKAGE. C THIS IS DOCUMENTED IN SANDIA TECH. REPT., C SAND78-1189. C C REFERENCES C C 1. SOLVING LEAST SQUARES PROBLEMS, BY C.L. LAWSON C AND R.J. HANSON. PRENTICE-HALL, INC. (1974). C C 2. BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE, BY C C.L. LAWSON, R.J. HANSON, D.R. KINCAID, AND F.T. KROGH. C TOMS, V. 5, NO. 3, P. 308. ALSO AVAILABLE AS C SANDIA TECHNICAL REPORT NO. SAND77-0898. C C 3. AN ALGORITHM FOR LINEAR LEAST SQUARES WITH EQUALITY C AND NONNEGATIVITY CONSTRAINTS, BY K.H. HASKELL AND C R.J. HANSON. AVAILABLE AS SANDIA TECHNICAL REPORT NO. C SAND77-0552, AND MATH. PROGRAMMING, VOL. 21, (1981), P. 98-118. C C 4. SLATEC COMMON MATH. LIBRARY ERROR HANDLING C PACKAGE. BY R. E. JONES. AVAILABLE AS SANDIA C TECHNICAL REPORT SAND78-1189. C REAL DUMMY, W(MDW,1), PRGOPT(1), X(1), WORK(1), RNORM INTEGER IWORK(1) C C MODE = 0 IF (MA+ME.LE.0 .OR. N.LE.0) RETURN IF (.NOT.(IWORK(1).GT.0)) GO TO 20 LW = ME + MA + 5*N IF (.NOT.(IWORK(1).LT.LW)) GO TO 10 NERR = 2 IOPT = 1 CALL XERRWV(70HWNNLS( ), INSUFFICIENT STORAGE ALLOCATED FOR WORK(* *), NEED LW=I1 BELOW, 70, NERR, IOPT, 1, LW, 0, 0, DUMMY, DUMMY) MODE = 2 RETURN 10 CONTINUE 20 IF (.NOT.(IWORK(2).GT.0)) GO TO 40 LIW = ME + MA + N IF (.NOT.(IWORK(2).LT.LIW)) GO TO 30 NERR = 2 IOPT = 1 CALL XERRWV(72HWNNLS( ), INSUFFICIENT STORAGE ALLOCATED FOR IWORK( **), NEED LIW=I1 BELOW, 72, NERR, IOPT, 1, LIW, 0, 0, DUMMY, DUMMY) MODE = 2 RETURN 30 CONTINUE 40 IF (.NOT.(MDW.LT.ME+MA)) GO TO 50 NERR = 1 IOPT = 1 CALL XERROR(44HWNNLS( ), THE VALUE MDW.LT.ME+MA IS AN ERROR, 44, * NERR, IOPT) MODE = 2 RETURN 50 IF (0.LE.L .AND. L.LE.N) GO TO 60 NERR = 2 IOPT = 1 CALL XERROR(39HWNNLS( ), L.LE.0.AND.L.LE.N IS REQUIRED, 39, NERR, * IOPT) MODE = 2 RETURN C C THE PURPOSE OF THIS SUBROUTINE IS TO BREAK UP THE ARRAYS C WORK(*) AND IWORK(*) INTO SEPARATE WORK ARRAYS C REQUIRED BY THE MAIN SUBROUTINE WNLSM( ). C 60 L1 = N + 1 L2 = L1 + N L3 = L2 + ME + MA L4 = L3 + N L5 = L4 + N C CALL WNLSM(W, MDW, ME, MA, N, L, PRGOPT, X, RNORM, MODE, IWORK, * IWORK(L1), WORK(1), WORK(L1), WORK(L2), WORK(L3), WORK(L4), * WORK(L5)) RETURN END SUBROUTINE WNLSM(W, MDW, MME, MA, N, L, PRGOPT, X, RNORM, MODE, WNL 10 * IPIVOT, ITYPE, WD, H, SCALE, Z, TEMP, D) C C C THE EDITING REQUIRED TO CONVERT THIS SUBROUTINE FROM SINGLE TO C DOUBLE PRECISION INVOLVES THE FOLLOWING CHARACTER STRING CHANGES. C USE AN EDITING COMMAND (CHANGE) /STRING-1/(TO)STRING-2/. C (START CHANGES AT LINE WITH C++ IN COLS. 1-3.) C /REAL (12 BLANKS)/DOUBLE PRECISION/,/SASUM/DASUM/,/SROTMG/DROTMG/, C /SNRM2/DNRM2/,/ SQRT/ DSQRT/,/SROTM/DROTM/,/AMAX1/DMAX1/, C /SCOPY/DCOPY/,/SSCAL/DSCAL/,/SAXPY/DAXPY/,/E0/D0/,/SSWAP/DSWAP/, C /ISAMAX/IDAMAX/,/SRELPR/DRELPR/,/.E-/.D-/ REMK C C THIS IS A COMPANION SUBPROGRAM TO WNNLS( ). C THE DOCUMENTATION FOR WNNLS( ) HAS MORE COMPLETE C USAGE INSTRUCTIONS. C C WRITTEN BY KAREN H. HASKELL, SANDIA LABORATORIES, C WITH THE HELP OF R.J. HANSON, SANDIA LABORATORIES, C DECEMBER 1976 - JANUARY 1978. C REVISED MAR. 4, 1982. C C IN ADDITION TO THE PARAMETERS DISCUSSED IN THE PROLOGUE TO C SUBROUTINE WNNLS, THE FOLLOWING WORK ARRAYS ARE USED IN C SUBROUTINE WNLSM (THEY ARE PASSED THROUGH THE CALLING C SEQUENCE FROM WNNLS FOR PURPOSES OF VARIABLE DIMENSIONING). C THEIR CONTENTS WILL IN GENERAL BE OF NO INTEREST TO THE USER. C C IPIVOT(*) C AN ARRAY OF LENGTH N. UPON COMPLETION IT CONTAINS THE C PIVOTING INFORMATION FOR THE COLS OF W(*,*). C C ITYPE(*) C AN ARRAY OF LENGTH M WHICH IS USED TO KEEP TRACK C OF THE CLASSIFICATION OF THE EQUATIONS. ITYPE(I)=0 C DENOTES EQUATION I AS AN EQUALITY CONSTRAINT. C ITYPE(I)=1 DENOTES EQUATION I AS A LEAST SQUARES C EQUATION. C C WD(*) C AN ARRAY OF LENGTH N. UPON COMPLETION IT CONTAINS THE C DUAL SOLUTION VECTOR. C C H(*) C AN ARRAY OF LENGTH N. UPON COMPLETION IT CONTAINS THE C PIVOT SCALARS OF THE HOUSEHOLDER TRANSFORMATIONS PERFORMED C IN THE CASE KRANK.LT.L. C C SCALE(*) C AN ARRAY OF LENGTH M WHICH IS USED BY THE SUBROUTINE C TO STORE THE DIAGONAL MATRIX OF WEIGHTS. C THESE ARE USED TO APPLY THE MODIFIED GIVENS C TRANSFORMATIONS. C C Z(*),TEMP(*) C WORKING ARRAYS OF LENGTH N. C C D(*) C AN ARRAY OF LENGTH N THAT CONTAINS THE C COLUMN SCALING FOR THE MATRIX (E). C (A) C C SUBROUTINE WNLSM (W,MDW,MME,MA,N,L,PRGOPT,X,RNORM,MODE, C 1 IPIVOT,ITYPE,WD,H,SCALE,Z,TEMP,D) C++ REAL W(MDW,1), X(1), WD(1), H(1), SCALE(1), DOPE(4) REAL Z(1), TEMP(1), PRGOPT(1), D(1), SPARAM(5) REAL ALAMDA, ALPHA, ALSQ, AMAX, BNORM, EANORM REAL SRELPR, FAC, ONE, BLOWUP REAL RNORM, SM, T, TAU, TWO, WMAX, ZERO, ZZ, Z2 REAL AMAX1, SQRT, SNRM2, SASUM INTEGER IPIVOT(1), ITYPE(1), ISAMAX, IDOPE(8) LOGICAL HITCON, FEASBL, DONE, POS DATA ZERO /0.E0/, ONE /1.E0/, TWO /2.E0/, SRELPR /0.E0/ C C INITIALIZE-VARIABLES ASSIGN 10 TO IGO998 GO TO 180 C C PERFORM INITIAL TRIANGULARIZATION IN THE SUBMATRIX C CORRESPONDING TO THE UNCONSTRAINED VARIABLES USING C THE PROCEDURE INITIALLY-TRIANGULARIZE. 10 ASSIGN 20 TO IGO995 GO TO 280 C C PERFORM WNNLS ALGORITHM USING THE FOLLOWING STEPS. C C UNTIL(DONE) C C COMPUTE-SEARCH-DIRECTION-AND-FEASIBLE-POINT C C WHEN (HITCON) ADD-CONSTRAINTS C C ELSE PERFORM-MULTIPLIER-TEST-AND-DROP-A-CONSTRAINT C C FIN C C COMPUTE-FINAL-SOLUTION C 20 IF (DONE) GO TO 80 C ASSIGN 30 TO IGO991 GO TO 300 C C COMPUTE-SEARCH-DIRECTION-AND-FEASIBLE-POINT C 30 IF (.NOT.(HITCON)) GO TO 50 ASSIGN 40 TO IGO986 GO TO 370 40 GO TO 70 C C WHEN (HITCON) ADD-CONSTRAINTS C 50 ASSIGN 60 TO IGO983 GO TO 640 60 CONTINUE C C ELSE PERFORM-MULTIPLIER-TEST-AND-DROP-A-CONSTRAINT C 70 GO TO 20 C 80 ASSIGN 90 TO IGO980 GO TO 1000 C C COMPUTE-FINAL-SOLUTION C 90 RETURN 100 CONTINUE C C TO PROCESS-OPTION-VECTOR FAC = 1.E-4 C C THE NOMINAL TOLERANCE USED IN THE CODE, TAU = SQRT(SRELPR) C C THE NOMINAL BLOW-UP FACTOR USED IN THE CODE. BLOWUP = TAU C C THE NOMINAL COLUMN SCALING USED IN THE CODE IS C THE IDENTITY SCALING. D(1) = ONE CALL SCOPY(N, D, 0, D, 1) C C DEFINE BOUND FOR NUMBER OF OPTIONS TO CHANGE. NOPT = 1000 C C DEFINE BOUND FOR POSITIVE VALUE OF LINK. NLINK = 100000 NTIMES = 0 LAST = 1 LINK = PRGOPT(1) IF (.NOT.(LINK.LE.0 .OR. LINK.GT.NLINK)) GO TO 110 NERR = 3 IOPT = 1 CALL XERROR(39HWNNLS( ) THE OPTION VECTOR IS UNDEFINED, 39, NERR, * IOPT) MODE = 2 RETURN 110 IF (.NOT.(LINK.GT.1)) GO TO 160 NTIMES = NTIMES + 1 IF (.NOT.(NTIMES.GT.NOPT)) GO TO 120 NERR = 3 IOPT = 1 CALL XERROR( * 53HWNNLS( ). THE LINKS IN THE OPTION VECTOR ARE CYCLING., 53, * NERR, IOPT) MODE = 2 RETURN 120 KEY = PRGOPT(LAST+1) IF (.NOT.(KEY.EQ.6 .AND. PRGOPT(LAST+2).NE.ZERO)) GO TO 140 DO 130 J=1,N T = SNRM2(M,W(1,J),1) IF (T.NE.ZERO) T = ONE/T D(J) = T 130 CONTINUE 140 IF (KEY.EQ.7) CALL SCOPY(N, PRGOPT(LAST+2), 1, D, 1) IF (KEY.EQ.8) TAU = AMAX1(SRELPR,PRGOPT(LAST+2)) IF (KEY.EQ.9) BLOWUP = AMAX1(SRELPR,PRGOPT(LAST+2)) NEXT = PRGOPT(LINK) IF (.NOT.(NEXT.LE.0 .OR. NEXT.GT.NLINK)) GO TO 150 NERR = 3 IOPT = 1 CALL XERROR(39HWNNLS( ) THE OPTION VECTOR IS UNDEFINED, 39, NERR, * IOPT) MODE = 2 RETURN 150 LAST = LINK LINK = NEXT GO TO 110 160 DO 170 J=1,N CALL SSCAL(M, D(J), W(1,J), 1) 170 CONTINUE GO TO 1260 180 CONTINUE C C TO INITIALIZE-VARIABLES C C SRELPR IS THE PRECISION FOR THE PARTICULAR MACHINE C BEING USED. THIS LOGIC AVOIDS RECOMPUTING IT EVERY ENTRY. IF (.NOT.(SRELPR.EQ.ZERO)) GO TO 210 SRELPR = ONE 190 IF (ONE+SRELPR.EQ.ONE) GO TO 200 SRELPR = SRELPR/TWO GO TO 190 200 SRELPR = SRELPR*TWO 210 M = MA + MME ME = MME MEP1 = ME + 1 ASSIGN 220 TO IGO977 GO TO 100 C C PROCESS-OPTION-VECTOR 220 DONE = .FALSE. ITER = 0 ITMAX = 3*(N-L) MODE = 0 LP1 = L + 1 NSOLN = L NSP1 = NSOLN + 1 NP1 = N + 1 NM1 = N - 1 L1 = MIN0(M,L) C C COMPUTE SCALE FACTOR TO APPLY TO EQUAL. CONSTRAINT EQUAS. DO 230 J=1,N WD(J) = SASUM(M,W(1,J),1) 230 CONTINUE IMAX = ISAMAX(N,WD,1) EANORM = WD(IMAX) BNORM = SASUM(M,W(1,NP1),1) ALAMDA = EANORM/(SRELPR*FAC) C C DEFINE SCALING DIAG MATRIX FOR MOD GIVENS USAGE AND C CLASSIFY EQUATION TYPES. ALSQ = ALAMDA**2 DO 260 I=1,M C C WHEN EQU I IS HEAVILY WEIGHTED ITYPE(I)=0, ELSE ITYPE(I)=1. IF (.NOT.(I.LE.ME)) GO TO 240 T = ALSQ ITEMP = 0 GO TO 250 240 T = ONE ITEMP = 1 250 SCALE(I) = T ITYPE(I) = ITEMP 260 CONTINUE C C SET THE SOLN VECTOR X(*) TO ZERO AND THE COL INTERCHANGE C MATRIX TO THE IDENTITY. X(1) = ZERO CALL SCOPY(N, X, 0, X, 1) DO 270 I=1,N IPIVOT(I) = I 270 CONTINUE GO TO 1230 280 CONTINUE C C TO INITIALLY-TRIANGULARIZE C C SET FIRST L COMPS. OF DUAL VECTOR TO ZERO BECAUSE C THESE CORRESPOND TO THE UNCONSTRAINED VARIABLES. IF (.NOT.(L.GT.0)) GO TO 290 WD(1) = ZERO CALL SCOPY(L, WD, 0, WD, 1) C C THE ARRAYS IDOPE(*) AND DOPE(*) ARE USED TO PASS C INFORMATION TO WNLIT(). THIS WAS DONE TO AVOID C A LONG CALLING SEQUENCE OR THE USE OF COMMON. 290 IDOPE(1) = ME IDOPE(2) = MEP1 IDOPE(3) = 0 IDOPE(4) = 1 IDOPE(5) = NSOLN IDOPE(6) = 0 IDOPE(7) = 1 IDOPE(8) = L1 C DOPE(1) = ALSQ DOPE(2) = EANORM DOPE(3) = FAC DOPE(4) = TAU CALL WNLIT(W, MDW, M, N, L, IPIVOT, ITYPE, H, SCALE, RNORM, * IDOPE, DOPE, DONE) ME = IDOPE(1) MEP1 = IDOPE(2) KRANK = IDOPE(3) KRP1 = IDOPE(4) NSOLN = IDOPE(5) NIV = IDOPE(6) NIV1 = IDOPE(7) L1 = IDOPE(8) GO TO 1240 300 CONTINUE C C TO COMPUTE-SEARCH-DIRECTION-AND-FEASIBLE-POINT C C SOLVE THE TRIANGULAR SYSTEM OF CURRENTLY NON-ACTIVE C VARIABLES AND STORE THE SOLUTION IN Z(*). C C SOLVE-SYSTEM ASSIGN 310 TO IGO958 GO TO 1110 C C INCREMENT ITERATION COUNTER AND CHECK AGAINST MAX. NUMBER C OF ITERATIONS. 310 ITER = ITER + 1 IF (.NOT.(ITER.GT.ITMAX)) GO TO 320 MODE = 1 DONE = .TRUE. C C CHECK TO SEE IF ANY CONSTRAINTS HAVE BECOME ACTIVE. C IF SO, CALCULATE AN INTERPOLATION FACTOR SO THAT ALL C ACTIVE CONSTRAINTS ARE REMOVED FROM THE BASIS. 320 ALPHA = TWO HITCON = .FALSE. IF (.NOT.(L.LT.NSOLN)) GO TO 360 DO 350 J=LP1,NSOLN ZZ = Z(J) IF (.NOT.(ZZ.LE.ZERO)) GO TO 340 T = X(J)/(X(J)-ZZ) IF (.NOT.(T.LT.ALPHA)) GO TO 330 ALPHA = T JCON = J 330 HITCON = .TRUE. 340 CONTINUE 350 CONTINUE 360 GO TO 1220 370 CONTINUE C C TO ADD-CONSTRAINTS C C USE COMPUTED ALPHA TO INTERPOLATE BETWEEN LAST C FEASIBLE SOLUTION X(*) AND CURRENT UNCONSTRAINED C (AND INFEASIBLE) SOLUTION Z(*). IF (.NOT.(LP1.LE.NSOLN)) GO TO 390 DO 380 J=LP1,NSOLN X(J) = X(J) + ALPHA*(Z(J)-X(J)) 380 CONTINUE 390 FEASBL = .FALSE. GO TO 410 400 IF (FEASBL) GO TO 610 C C REMOVE COL JCON AND SHIFT COLS JCON+1 THROUGH N TO THE C LEFT. SWAP COL JCON INTO THE N-TH POSITION. THIS ACHIEVES C UPPER HESSENBERG FORM FOR THE NONACTIVE CONSTRAINTS AND C LEAVES AN UPPER HESSENBERG MATRIX TO RETRIANGULARIZE. 410 DO 420 I=1,M T = W(I,JCON) CALL SCOPY(N-JCON, W(I,JCON+1), MDW, W(I,JCON), MDW) W(I,N) = T 420 CONTINUE C C UPDATE PERMUTED INDEX VECTOR TO REFLECT THIS SHIFT AND SWAP. ITEMP = IPIVOT(JCON) IF (.NOT.(JCON.LT.N)) GO TO 440 DO 430 I=JCON,NM1 IPIVOT(I) = IPIVOT(I+1) 430 CONTINUE 440 IPIVOT(N) = ITEMP C C SIMILARLY REPERMUTE X(*) VECTOR. CALL SCOPY(N-JCON, X(JCON+1), 1, X(JCON), 1) X(N) = ZERO NSP1 = NSOLN NSOLN = NSOLN - 1 NIV1 = NIV NIV = NIV - 1 C C RETRIANGULARIZE UPPER HESSENBERG MATRIX AFTER ADDING CONSTRAINTS. J = JCON I = KRANK + JCON - L 450 IF (.NOT.(J.LE.NSOLN)) GO TO 570 IF (.NOT.(ITYPE(I).EQ.0 .AND. ITYPE(I+1).EQ.0)) GO TO 470 ASSIGN 460 TO IGO938 GO TO 620 C C (ITYPE(I).EQ.0 .AND. ITYPE(I+1).EQ.0) ZERO-IP1-TO-I-IN-COL-J 460 GO TO 560 470 IF (.NOT.(ITYPE(I).EQ.1 .AND. ITYPE(I+1).EQ.1)) GO TO 490 ASSIGN 480 TO IGO938 GO TO 620 C C (ITYPE(I).EQ.1 .AND. ITYPE(I+1).EQ.1) ZERO-IP1-TO-I-IN-COL-J 480 GO TO 560 490 IF (.NOT.(ITYPE(I).EQ.1 .AND. ITYPE(I+1).EQ.0)) GO TO 510 CALL SSWAP(NP1, W(I,1), MDW, W(I+1,1), MDW) CALL SSWAP(1, SCALE(I), 1, SCALE(I+1), 1) ITEMP = ITYPE(I+1) ITYPE(I+1) = ITYPE(I) ITYPE(I) = ITEMP C C SWAPPED ROW WAS FORMERLY A PIVOT ELT., SO IT WILL C BE LARGE ENOUGH TO PERFORM ELIM. ASSIGN 500 TO IGO938 GO TO 620 C C ZERO-IP1-TO-I-IN-COL-J 500 GO TO 560 510 IF (.NOT.(ITYPE(I).EQ.0 .AND. ITYPE(I+1).EQ.1)) GO TO 550 T = SCALE(I)*W(I,J)**2/ALSQ IF (.NOT.(T.GT.TAU**2*EANORM**2)) GO TO 530 ASSIGN 520 TO IGO938 GO TO 620 520 GO TO 540 530 CALL SSWAP(NP1, W(I,1), MDW, W(I+1,1), MDW) CALL SSWAP(1, SCALE(I), 1, SCALE(I+1), 1) ITEMP = ITYPE(I+1) ITYPE(I+1) = ITYPE(I) ITYPE(I) = ITEMP W(I+1,J) = ZERO 540 CONTINUE 550 CONTINUE 560 I = I + 1 J = J + 1 GO TO 450 C C SEE IF THE REMAINING COEFFS IN THE SOLN SET ARE FEASIBLE. THEY C SHOULD BE BECAUSE OF THE WAY ALPHA WAS DETERMINED. IF ANY ARE C INFEASIBLE IT IS DUE TO ROUNDOFF ERROR. ANY THAT ARE NON- C POSITIVE WILL BE SET TO ZERO AND REMOVED FROM THE SOLN SET. 570 IF (.NOT.(LP1.LE.NSOLN)) GO TO 590 DO 580 JCON=LP1,NSOLN IF (X(JCON).LE.ZERO) GO TO 600 580 CONTINUE 590 FEASBL = .TRUE. 600 CONTINUE GO TO 400 610 GO TO 1200 620 CONTINUE C C TO ZERO-IP1-TO-I-IN-COL-J IF (.NOT.(W(I+1,J).NE.ZERO)) GO TO 630 CALL SROTMG(SCALE(I), SCALE(I+1), W(I,J), W(I+1,J), SPARAM) W(I+1,J) = ZERO CALL SROTM(NP1-J, W(I,J+1), MDW, W(I+1,J+1), MDW, SPARAM) 630 GO TO 1290 640 CONTINUE C C TO PERFORM-MULTIPLIER-TEST-AND-DROP-A-CONSTRAINT CALL SCOPY(NSOLN, Z, 1, X, 1) IF (.NOT.(NSOLN.LT.N)) GO TO 650 X(NSP1) = ZERO CALL SCOPY(N-NSOLN, X(NSP1), 0, X(NSP1), 1) 650 I = NIV1 660 IF (.NOT.(I.LE.ME)) GO TO 690 C C RECLASSIFY LEAST SQUARES EQATIONS AS EQUALITIES AS C NECESSARY. IF (.NOT.(ITYPE(I).EQ.0)) GO TO 670 I = I + 1 GO TO 680 670 CALL SSWAP(NP1, W(I,1), MDW, W(ME,1), MDW) CALL SSWAP(1, SCALE(I), 1, SCALE(ME), 1) ITEMP = ITYPE(I) ITYPE(I) = ITYPE(ME) ITYPE(ME) = ITEMP MEP1 = ME ME = ME - 1 680 GO TO 660 C C FORM INNER PRODUCT VECTOR WD(*) OF DUAL COEFFS. 690 IF (.NOT.(NSP1.LE.N)) GO TO 730 DO 720 J=NSP1,N SM = ZERO IF (.NOT.(NSOLN.LT.M)) GO TO 710 DO 700 I=NSP1,M SM = SM + SCALE(I)*W(I,J)*W(I,NP1) 700 CONTINUE 710 WD(J) = SM 720 CONTINUE 730 GO TO 750 740 IF (POS .OR. DONE) GO TO 970 C C FIND J SUCH THAT WD(J)=WMAX IS MAXIMUM. THIS DETERMINES C THAT THE INCOMING COL J WILL REDUCE THE RESIDUAL VECTOR C AND BE POSITIVE. 750 WMAX = ZERO IWMAX = NSP1 IF (.NOT.(NSP1.LE.N)) GO TO 780 DO 770 J=NSP1,N IF (.NOT.(WD(J).GT.WMAX)) GO TO 760 WMAX = WD(J) IWMAX = J 760 CONTINUE 770 CONTINUE 780 IF (.NOT.(WMAX.LE.ZERO)) GO TO 790 DONE = .TRUE. GO TO 960 C C SET DUAL COEFF TO ZERO FOR INCOMING COL. 790 WD(IWMAX) = ZERO C C WMAX .GT. ZERO, SO OKAY TO MOVE COL IWMAX TO SOLN SET. C PERFORM TRANSFORMATION TO RETRIANGULARIZE, AND TEST C FOR NEAR LINEAR DEPENDENCE. C SWAP COL IWMAX INTO NSOLN-TH POSITION TO MAINTAIN UPPER C HESSENBERG FORM OF ADJACENT COLS, AND ADD NEW COL TO C TRIANGULAR DECOMPOSITION. NSOLN = NSP1 NSP1 = NSOLN + 1 NIV = NIV1 NIV1 = NIV + 1 IF (.NOT.(NSOLN.NE.IWMAX)) GO TO 800 CALL SSWAP(M, W(1,NSOLN), 1, W(1,IWMAX), 1) WD(IWMAX) = WD(NSOLN) WD(NSOLN) = ZERO ITEMP = IPIVOT(NSOLN) IPIVOT(NSOLN) = IPIVOT(IWMAX) IPIVOT(IWMAX) = ITEMP C C REDUCE COL NSOLN SO THAT THE MATRIX OF NONACTIVE C CONSTRAINTS VARIABLES IS TRIANGULAR. 800 J = M 810 IF (.NOT.(J.GT.NIV)) GO TO 870 JM1 = J - 1 JP = JM1 C C WHEN OPERATING NEAR THE ME LINE, TEST TO SEE IF THE PIVOT ELT. C IS NEAR ZERO. IF SO, USE THE LARGEST ELT. ABOVE IT AS THE PIVOT. C THIS IS TO MAINTAIN THE SHARP INTERFACE BETWEEN WEIGHTED AND C NON-WEIGHTED ROWS IN ALL CASES. IF (.NOT.(J.EQ.MEP1)) GO TO 850 IMAX = ME AMAX = SCALE(ME)*W(ME,NSOLN)**2 820 IF (.NOT.(JP.GE.NIV)) GO TO 840 T = SCALE(JP)*W(JP,NSOLN)**2 IF (.NOT.(T.GT.AMAX)) GO TO 830 IMAX = JP AMAX = T 830 JP = JP - 1 GO TO 820 840 JP = IMAX 850 IF (.NOT.(W(J,NSOLN).NE.ZERO)) GO TO 860 CALL SROTMG(SCALE(JP), SCALE(J), W(JP,NSOLN), W(J,NSOLN), SPARAM) W(J,NSOLN) = ZERO CALL SROTM(NP1-NSOLN, W(JP,NSP1), MDW, W(J,NSP1), MDW, SPARAM) 860 J = JM1 GO TO 810 C C SOLVE FOR Z(NSOLN)=PROPOSED NEW VALUE FOR X(NSOLN). C TEST IF THIS IS NONPOSITIVE OR TOO LARGE. C IF THIS WAS TRUE OR IF THE PIVOT TERM WAS ZERO REJECT C THE COL AS DEPENDENT. 870 IF (.NOT.(W(NIV,NSOLN).NE.ZERO)) GO TO 890 ISOL = NIV ASSIGN 880 TO IGO897 GO TO 980 C C TEST-PROPOSED-NEW-COMPONENT 880 GO TO 940 890 IF (.NOT.(NIV.LE.ME .AND. W(MEP1,NSOLN).NE.ZERO)) GO TO 920 C C TRY TO ADD ROW MEP1 AS AN ADDITIONAL EQUALITY CONSTRAINT. C CHECK SIZE OF PROPOSED NEW SOLN COMPONENT. C REJECT IT IF IT IS TOO LARGE. ISOL = MEP1 ASSIGN 900 TO IGO897 GO TO 980 C C TEST-PROPOSED-NEW-COMPONENT 900 IF (.NOT.(POS)) GO TO 910 C C SWAP ROWS MEP1 AND NIV, AND SCALE FACTORS FOR THESE ROWS. CALL SSWAP(NP1, W(MEP1,1), MDW, W(NIV,1), MDW) CALL SSWAP(1, SCALE(MEP1), 1, SCALE(NIV), 1) ITEMP = ITYPE(MEP1) ITYPE(MEP1) = ITYPE(NIV) ITYPE(NIV) = ITEMP ME = MEP1 MEP1 = ME + 1 910 GO TO 930 920 POS = .FALSE. 930 CONTINUE 940 IF (POS) GO TO 950 NSP1 = NSOLN NSOLN = NSOLN - 1 NIV1 = NIV NIV = NIV - 1 950 CONTINUE 960 GO TO 740 970 GO TO 1250 980 CONTINUE C C TO TEST-PROPOSED-NEW-COMPONENT Z2 = W(ISOL,NP1)/W(ISOL,NSOLN) Z(NSOLN) = Z2 POS = Z2.GT.ZERO IF (.NOT.(Z2*EANORM.GE.BNORM .AND. POS)) GO TO 990 POS = .NOT.(BLOWUP*Z2*EANORM.GE.BNORM) 990 GO TO 1280 1000 CONTINUE C TO COMPUTE-FINAL-SOLUTION C C SOLVE SYSTEM, STORE RESULTS IN X(*). C ASSIGN 1010 TO IGO958 GO TO 1110 C SOLVE-SYSTEM 1010 CALL SCOPY(NSOLN, Z, 1, X, 1) C C APPLY HOUSEHOLDER TRANSFORMATIONS TO X(*) IF KRANK.LT.L IF (.NOT.(0.LT.KRANK .AND. KRANK.LT.L)) GO TO 1030 DO 1020 I=1,KRANK CALL H12(2, I, KRP1, L, W(I,1), MDW, H(I), X, 1, 1, 1) 1020 CONTINUE C C FILL IN TRAILING ZEROES FOR CONSTRAINED VARIABLES NOT IN SOLN. 1030 IF (.NOT.(NSOLN.LT.N)) GO TO 1040 X(NSP1) = ZERO CALL SCOPY(N-NSOLN, X(NSP1), 0, X(NSP1), 1) C C REPERMUTE SOLN VECTOR TO NATURAL ORDER. 1040 DO 1070 I=1,N J = I 1050 IF (IPIVOT(J).EQ.I) GO TO 1060 J = J + 1 GO TO 1050 1060 IPIVOT(J) = IPIVOT(I) IPIVOT(I) = J CALL SSWAP(1, X(J), 1, X(I), 1) 1070 CONTINUE C C RESCALE THE SOLN USING THE COL SCALING. DO 1080 J=1,N X(J) = X(J)*D(J) 1080 CONTINUE C IF (.NOT.(NSOLN.LT.M)) GO TO 1100 REMK C DO 1090 I=NSP1,M REMK IF (.NOT.(NIV.LT.M)) GO TO 1100 DO 1090 I = NIV1,M T = W(I,NP1) IF (I.LE.ME) T = T/ALAMDA T = (SCALE(I)*T)*T RNORM = RNORM + T 1090 CONTINUE 1100 RNORM = SQRT(RNORM) GO TO 1210 C C TO SOLVE-SYSTEM C 1110 CONTINUE IF (.NOT.(DONE)) GO TO 1120 ISOL = 1 GO TO 1130 1120 ISOL = LP1 1130 IF (.NOT.(NSOLN.GE.ISOL)) GO TO 1190 C C COPY RT. HAND SIDE INTO TEMP VECTOR TO USE OVERWRITING METHOD. CALL SCOPY(NIV, W(1,NP1), 1, TEMP, 1) DO 1180 JJ=ISOL,NSOLN J = NSOLN - JJ + ISOL IF (.NOT.(J.GT.KRANK)) GO TO 1140 I = NIV - JJ + ISOL GO TO 1150 1140 I = J 1150 IF (.NOT.(J.GT.KRANK .AND. J.LE.L)) GO TO 1160 Z(J) = ZERO GO TO 1170 1160 Z(J) = TEMP(I)/W(I,J) CALL SAXPY(I-1, -Z(J), W(1,J), 1, TEMP, 1) 1170 CONTINUE 1180 CONTINUE 1190 GO TO 1270 1200 GO TO IGO986, (40) 1210 GO TO IGO980, (90) 1220 GO TO IGO991, (30) 1230 GO TO IGO998, (10) 1240 GO TO IGO995, (20) 1250 GO TO IGO983, (60) 1260 GO TO IGO977, (220) 1270 GO TO IGO958, (310, 1010) 1280 GO TO IGO897, (880, 900) 1290 GO TO IGO938, (460, 480, 500, 520) END SUBROUTINE WNLIT(W, MDW, M, N, L, IPIVOT, ITYPE, H, SCALE, RNORM, WNL 10 * IDOPE, DOPE, DONE) C C THE EDITING REQUIRED TO CONVERT THIS SUBROUTINE FROM SINGLE TO C DOUBLE PRECISION INVOLVES THE FOLLOWING CHARACTER STRING CHANGES. C USE AN EDITING COMMAND (CHANGE) /STRING-1/(TO)STRING-2/. C (BEGIN CHANGES AT LINE WITH C++ IN COLS. 1-3.) C /REAL (12 BLANKS)/DOUBLE PRECISION/,/SCOPY/DCOPY/,/SROTM/DROTM/, C /SSCAL/DSCAL/,/SQRT/DSQRT/, REMK C /SSWAP/DSWAP/,/AMAX1/DMAX1/,/ISAMAX/IDAMAX/,/.E-/.D-/,/E0/D0/ C C THIS IS A COMPANION SUBPROGRAM TO WNNLS( ). C THE DOCUMENTATION FOR WNNLS( ) HAS MORE COMPLETE C USAGE INSTRUCTIONS. C C NOTE THE M BY (N+1) MATRIX W( , ) CONTAINS THE RT. HAND SIDE C B AS THE (N+1)ST COL. C C C TRIANGULARIZE L1 BY L1 SUBSYSTEM, WHERE L1=MIN(M,L), WITH C COL INTERCHANGES. C REVISED MARCH 4, 1982 C C++ REAL W(MDW,1), H(1), SCALE(1), DOPE(4), SPARAM(5) C REAL ALSQ, AMAX, EANORM, FAC, FACTOR, HBAR, ONE, RN REAL ALSQ, EANORM, FACTOR, HBAR, ONE, RN REAL RNORM, SN, T, TAU, TENM3, ZERO REAL AMAX1 INTEGER ITYPE(1), IPIVOT(1), IDOPE(8) INTEGER ISAMAX LOGICAL INDEP, DONE, RECALC DATA TENM3 /1.E-3/, ZERO /0.E0/, ONE /1.E0/ C ME = IDOPE(1) MEP1 = IDOPE(2) KRANK = IDOPE(3) KRP1 = IDOPE(4) NSOLN = IDOPE(5) NIV = IDOPE(6) NIV1 = IDOPE(7) L1 = IDOPE(8) C ALSQ = DOPE(1) EANORM = DOPE(2) C FAC = DOPE(3) REMK TAU = DOPE(4) NP1 = N + 1 LB = MIN0(M-1,L) RECALC = .TRUE. RNORM = ZERO KRANK = 0 C WE SET FACTOR=1.E0 SO THAT THE HEAVY WEIGHT ALAMDA WILL BE C INCLUDED IN THE TEST FOR COL INDEPENDENCE. FACTOR = 1.E0 I = 1 IP1 = 2 LEND = L 10 IF (.NOT.(I.LE.LB)) GO TO 150 IF (.NOT.(I.LE.ME)) GO TO 130 C C SET IR TO POINT TO THE I-TH ROW. IR = I MEND = M ASSIGN 20 TO IGO996 GO TO 460 C C UPDATE-COL-SS-AND-FIND-PIVOT-COL 20 ASSIGN 30 TO IGO993 GO TO 560 C C PERFORM-COL-INTERCHANGE C C SET IC TO POINT TO I-TH COL. 30 IC = I ASSIGN 40 TO IGO990 GO TO 520 C C TEST-INDEP-OF-INCOMING-COL 40 IF (.NOT.(INDEP)) GO TO 110 C C ELIMINATE I-TH COL BELOW DIAG. USING MOD. GIVENS TRANSFORMATIONS C APPLIED TO (A B). J = M DO 100 JJ=IP1,M JM1 = J - 1 JP = JM1 C WHEN OPERATING NEAR THE ME LINE, USE THE LARGEST ELT. REMK C ABOVE IT AS THE PIVOT. REMK C IF (.NOT.(J.EQ.MEP1)) GO TO 80 REMK C IMAX = ME REMK C AMAX = SCALE(ME)*W(ME,I)**2 REMK C 50 IF (.NOT.(JP.GE.I)) GO TO 70 REMK C T = SCALE(JP)*W(JP,I)**2 REMK C IF (.NOT.(T.GT.AMAX)) GO TO 60 REMK C IMAX = JP REMK C AMAX = T REMK C 60 JP = JP - 1 REMK C GO TO 50 REMK C 70 JP = IMAX REMK IF (.NOT. (JJ.EQ.M)) GO TO 70 IF (.NOT. (I.LT.MEP1)) GO TO 80 J = MEP1 JP = I T = SCALE(JP)*W(JP,I)**2*TAU**2 IF (.NOT.(T.GT.SCALE(J)*W(J,I)**2)) GO TO 130 GO TO 80 70 IF (.NOT.(J.EQ.MEP1)) GO TO 80 J = JM1 JM1 = J - 1 JP = JM1 80 IF (.NOT.(W(J,I).NE.ZERO)) GO TO 90 CALL SROTMG(SCALE(JP), SCALE(J), W(JP,I), W(J,I), SPARAM) W(J,I) = ZERO CALL SROTM(NP1-I, W(JP,IP1), MDW, W(J,IP1), MDW, SPARAM) 90 J = JM1 100 CONTINUE GO TO 140 110 CONTINUE IF (.NOT.(LEND.GT.I)) GO TO 130 C C COL I IS DEPENDENT. SWAP WITH COL LEND. MAX = LEND C C PERFORM-COL-INTERCHANGE ASSIGN 120 TO IGO993 GO TO 560 120 CONTINUE LEND = LEND - 1 C C FIND COL IN REMAINING SET WITH LARGEST SS. MAX = ISAMAX(LEND-I+1,H(I),1) + I - 1 HBAR = H(MAX) GO TO 30 130 CONTINUE KRANK = I - 1 GO TO 160 140 I = IP1 IP1 = IP1 + 1 GO TO 10 150 KRANK = L1 160 CONTINUE KRP1 = KRANK + 1 IF (.NOT.(KRANK.LT.ME)) GO TO 290 FACTOR = ALSQ DO 170 I=KRP1,ME IF (L.GT.0) W(I,1) = ZERO CALL SCOPY(L, W(I,1), 0, W(I,1), MDW) 170 CONTINUE C C DETERMINE THE RANK OF THE REMAINING EQUALITY CONSTRAINT C EQUATIONS BY ELIMINATING WITHIN THE BLOCK OF CONSTRAINED C VARIABLES. REMOVE ANY REDUNDANT CONSTRAINTS. IR = KRP1 IF (.NOT. (L.LT.N)) GO TO 245 LP1 = L + 1 RECALC = .TRUE. LB = MIN0(L+ME-KRANK,N) I = LP1 IP1 = I + 1 180 IF (.NOT.(I.LE.LB)) GO TO 280 IR = KRANK + I - L LEND = N MEND = ME ASSIGN 190 TO IGO996 GO TO 460 C C UPDATE-COL-SS-AND-FIND-PIVOT-COL 190 ASSIGN 200 TO IGO993 GO TO 560 C C PERFORM-COL-INTERCHANGE C C ELIMINATE ELEMENTS IN THE I-TH COL. 200 J = ME 210 IF (.NOT.(J.GT.IR)) GO TO 230 JM1 = J - 1 IF (.NOT.(W(J,I).NE.ZERO)) GO TO 220 CALL SROTMG(SCALE(JM1), SCALE(J), W(JM1,I), W(J,I), SPARAM) W(J,I) = ZERO CALL SROTM(NP1-I, W(JM1,IP1), MDW, W(J,IP1), MDW, SPARAM) 220 J = JM1 GO TO 210 C C SET IC=I=COL BEING ELIMINATED 230 IC = I ASSIGN 240 TO IGO990 GO TO 520 C C TEST-INDEP-OF-INCOMING-COL 240 IF (INDEP) GO TO 270 C C REMOVE ANY REDUNDANT OR DEPENDENT EQUALITY CONSTRAINTS. 245 CONTINUE JJ = IR 250 IF (.NOT.(IR.LE.ME)) GO TO 260 W(IR,1) = ZERO CALL SCOPY(N, W(IR,1), 0, W(IR,1), MDW) RNORM = RNORM + (SCALE(IR)*W(IR,NP1)/ALSQ)*W(IR,NP1) W(IR,NP1) = ZERO SCALE(IR) = ONE C RECLASSIFY THE ZEROED ROW AS A LEAST SQUARES EQUATION. ITYPE(IR) = 1 IR = IR + 1 GO TO 250 C C REDUCE ME TO REFLECT ANY DISCOVERED DEPENDENT EQUALITY C CONSTRAINTS. 260 CONTINUE ME = JJ - 1 MEP1 = ME + 1 GO TO 300 270 I = IP1 IP1 = IP1 + 1 GO TO 180 280 CONTINUE 290 CONTINUE 300 CONTINUE IF (.NOT.(KRANK.LT.L1)) GO TO 420 C C TRY TO DETERMINE THE VARIABLES KRANK+1 THROUGH L1 FROM THE C LEAST SQUARES EQUATIONS. CONTINUE THE TRIANGULARIZATION WITH C PIVOT ELEMENT W(MEP1,I). C RECALC = .TRUE. C C SET FACTOR=ALSQ TO REMOVE EFFECT OF HEAVY WEIGHT FROM C TEST FOR COL INDEPENDENCE. FACTOR = ALSQ KK = KRP1 I = KK IP1 = I + 1 310 IF (.NOT.(I.LE.L1)) GO TO 410 C C SET IR TO POINT TO THE MEP1-ST ROW. IR = MEP1 LEND = L MEND = M ASSIGN 320 TO IGO996 GO TO 460 C C UPDATE-COL-SS-AND-FIND-PIVOT-COL 320 ASSIGN 330 TO IGO993 GO TO 560 C C PERFORM-COL-INTERCHANGE C C ELIMINATE I-TH COL BELOW THE IR-TH ELEMENT. 330 IRP1 = IR + 1 IF (.NOT.(IRP1.LE.M)) GO TO 355 J = M DO 350 JJ=IRP1,M JM1 = J - 1 IF (.NOT.(W(J,I).NE.ZERO)) GO TO 340 CALL SROTMG(SCALE(JM1), SCALE(J), W(JM1,I), W(J,I), SPARAM) W(J,I) = ZERO CALL SROTM(NP1-I, W(JM1,IP1), MDW, W(J,IP1), MDW, SPARAM) 340 J = JM1 350 CONTINUE 355 CONTINUE C C TEST IF NEW PIVOT ELEMENT IS NEAR ZERO. IF SO, THE COL IS C DEPENDENT. T = SCALE(IR)*W(IR,I)**2 INDEP = T.GT.TAU**2*EANORM**2 IF (.NOT.INDEP) GO TO 380 C C COL TEST PASSED. NOW MUST PASS ROW NORM TEST TO BE CLASSIFIED C AS INDEPENDENT. RN = ZERO DO 370 I1=IR,M DO 360 J1=IP1,N RN = AMAX1(RN,SCALE(I1)*W(I1,J1)**2) 360 CONTINUE 370 CONTINUE INDEP = T.GT.TAU**2*RN C C IF INDEPENDENT, SWAP THE IR-TH AND KRP1-ST ROWS TO MAINTAIN THE C TRIANGULAR FORM. UPDATE THE RANK INDICATOR KRANK AND THE C EQUALITY CONSTRAINT POINTER ME. 380 IF (.NOT.(INDEP)) GO TO 390 CALL SSWAP(NP1, W(KRP1,1), MDW, W(IR,1), MDW) CALL SSWAP(1, SCALE(KRP1), 1, SCALE(IR), 1) C RECLASSIFY THE LEAST SQ. EQUATION AS AN EQUALITY CONSTRAINT AND C RESCALE IT. ITYPE(IR) = 0 T = SQRT(SCALE(KRP1)) CALL SSCAL(NP1, T, W(KRP1,1), MDW) SCALE(KRP1) = ALSQ ME = MEP1 MEP1 = ME + 1 KRANK = KRP1 KRP1 = KRANK + 1 GO TO 400 390 GO TO 430 400 I = IP1 IP1 = IP1 + 1 GO TO 310 410 CONTINUE 420 CONTINUE 430 CONTINUE C C IF PSEUDORANK IS LESS THAN L, APPLY HOUSEHOLDER TRANS. C FROM RIGHT. IF (.NOT.(KRANK.LT.L)) GO TO 450 DO 440 I=1,KRANK J = KRP1 - I CALL H12(1, J, KRP1, L, W(J,1), MDW, H(J), W, MDW, 1, J-1) 440 CONTINUE 450 NIV = KRANK + NSOLN - L NIV1 = NIV + 1 IF (L.EQ.N) DONE = .TRUE. C C END OF INITIAL TRIANGULARIZATION. IDOPE(1) = ME IDOPE(2) = MEP1 IDOPE(3) = KRANK IDOPE(4) = KRP1 IDOPE(5) = NSOLN IDOPE(6) = NIV IDOPE(7) = NIV1 IDOPE(8) = L1 RETURN 460 CONTINUE C C TO UPDATE-COL-SS-AND-FIND-PIVOT-COL C C THE COL SS VECTOR WILL BE UPDATED AT EACH STEP. WHEN C NUMERICALLY NECESSARY, THESE VALUES WILL BE RECOMPUTED. C IF (.NOT.(IR.NE.1 .AND. (.NOT.RECALC))) GO TO 480 C UPDATE COL SS =SUM OF SQUARES. DO 470 J=I,LEND H(J) = H(J) - SCALE(IR-1)*W(IR-1,J)**2 470 CONTINUE C C TEST FOR NUMERICAL ACCURACY. MAX = ISAMAX(LEND-I+1,H(I),1) + I - 1 RECALC = HBAR + TENM3*H(MAX).EQ.HBAR C C IF REQUIRED, RECALCULATE COL SS, USING ROWS IR THROUGH MEND. 480 IF (.NOT.(RECALC)) GO TO 510 DO 500 J=I,LEND H(J) = ZERO DO 490 K=IR,MEND H(J) = H(J) + SCALE(K)*W(K,J)**2 490 CONTINUE 500 CONTINUE C C FIND COL WITH LARGEST SS. MAX = ISAMAX(LEND-I+1,H(I),1) + I - 1 HBAR = H(MAX) 510 GO TO 600 520 CONTINUE C C TO TEST-INDEP-OF-INCOMING-COL C C TEST THE COL IC TO DETERMINE IF IT IS LINEARLY INDEPENDENT C OF THE COLS ALREADY IN THE BASIS. IN THE INIT TRI C STEP, WE USUALLY WANT THE HEAVY WEIGHT ALAMDA TO C BE INCLUDED IN THE TEST FOR INDEPENDENCE. IN THIS CASE THE C VALUE OF FACTOR WILL HAVE BEEN SET TO 1.E0 BEFORE THIS C PROCEDURE IS INVOKED. IN THE POTENTIALLY RANK DEFICIENT C PROBLEM, THE VALUE OF FACTOR WILL HAVE BEEN C SET TO ALSQ=ALAMDA**2 TO REMOVE THE EFFECT OF THE HEAVY WEIGHT C FROM THE TEST FOR INDEPENDENCE. C C WRITE NEW COL AS PARTITIONED VECTOR C (A1) NUMBER OF COMPONENTS IN SOLN SO FAR = NIV C (A2) M-NIV COMPONENTS C AND COMPUTE SN = INVERSE WEIGHTED LENGTH OF A1 C RN = INVERSE WEIGHTED LENGTH OF A2 C CALL THE COL INDEPENDENT WHEN RN .GT. TAU*SN SN = ZERO RN = ZERO DO 550 J=1,MEND T = SCALE(J) IF (J.LE.ME) T = T/FACTOR T = T*W(J,IC)**2 IF (.NOT.(J.LT.IR)) GO TO 530 SN = SN + T GO TO 540 530 RN = RN + T 540 CONTINUE 550 CONTINUE INDEP = RN.GT.TAU**2*SN GO TO 590 560 CONTINUE C C TO PERFORM-COL-INTERCHANGE C IF (.NOT.(MAX.NE.I)) GO TO 570 C EXCHANGE ELEMENTS OF PERMUTED INDEX VECTOR AND PERFORM COL C INTERCHANGES. ITEMP = IPIVOT(I) IPIVOT(I) = IPIVOT(MAX) IPIVOT(MAX) = ITEMP CALL SSWAP(M, W(1,MAX), 1, W(1,I), 1) T = H(MAX) H(MAX) = H(I) H(I) = T 570 GO TO 580 580 GO TO IGO993, (30, 200, 330, 120) 590 GO TO IGO990, (40, 240) 600 GO TO IGO996, (20, 190, 320) END SUBROUTINE HFTI(A, MDA, M, N, B, MDB, NB, TAU, KRANK, RNORM, H, HFTI 10 * G, IP) C C THE EDITING REQUIRED TO CONVERT THIS SUBROUTINE FROM SINGLE TO C DOUBLE PRECISION INVOLVES THE FOLLOWING CHARACTER STRING CHANGES. C USE AN EDITING COMMAND (CHANGE) /STRING-1/(TO)STRING-2/. C (BEGIN CHANGES AT LINE WITH C++ IN COLS. 1-3.) C /REAL (12 BLANKS)/DOUBLE PRECISION/,/ SQRT/ DSQRT/, C /, ABS/, DABS/,/ABS(/DABS(/,/E0/D0/ C C DIMENSION A(MDA,N),(B(MDB,NB) OR B(M)),RNORM(NB),H(N),G(N),IP(N) C C WRITTEN BY C. L. LAWSON AND R. J. HANSON. FROM THE BOOK SOLVING C LEAST SQUARES PROBLEMS, PRENTICE-HALL, INC. (1974). FOR FURTHER C ALGORITHMIC DETAILS SEE ALGORITHM HFTI IN CHAPTER 14. C C ABSTRACT C C THIS SUBROUTINE SOLVES A LINEAR LEAST SQUARES PROBLEM OR A SET OF C LINEAR LEAST SQUARES PROBLEMS HAVING THE SAME MATRIX BUT DIFFERENT C RIGHT-SIDE VECTORS. THE PROBLEM DATA CONSISTS OF AN M BY N MATRIX C A, AN M BY NB MATRIX B, AND AN ABSOLUTE TOLERANCE PARAMETER TAU C WHOSE USAGE IS DESCRIBED BELOW. THE NB COLUMN VECTORS OF B C REPRESENT RIGHT-SIDE VECTORS FOR NB DISTINCT LINEAR LEAST SQUARES C PROBLEMS. C C THIS SET OF PROBLEMS CAN ALSO BE WRITTEN AS THE MATRIX LEAST C SQUARES PROBLEM C C AX = B, C C WHERE X IS THE N BY NB SOLUTION MATRIX. C C NOTE THAT IF B IS THE M BY M IDENTITY MATRIX, THEN X WILL BE THE C PSEUDO-INVERSE OF A. C C THIS SUBROUTINE FIRST TRANSFORMS THE AUGMENTED MATRIX (A B) TO A C MATRIX (R C) USING PREMULTIPLYING HOUSEHOLDER TRANSFORMATIONS WITH C COLUMN INTERCHANGES. ALL SUBDIAGONAL ELEMENTS IN THE MATRIX R ARE C ZERO AND ITS DIAGONAL ELEMENTS SATISFY C C ABS(R(I,I)).GE.ABS(R(I+1,I+1)), C C I = 1,...,L-1, WHERE C C L = MIN(M,N). C C THE SUBROUTINE WILL COMPUTE AN INTEGER, KRANK, EQUAL TO THE NUMBER C OF DIAGONAL TERMS OF R THAT EXCEED TAU IN MAGNITUDE. THEN A C SOLUTION OF MINIMUM EUCLIDEAN LENGTH IS COMPUTED USING THE FIRST C KRANK ROWS OF (R C). C C TO BE SPECIFIC WE SUGGEST THAT THE USER CONSIDER AN EASILY C COMPUTABLE MATRIX NORM, SUCH AS, THE MAXIMUM OF ALL COLUMN SUMS OF C MAGNITUDES. C C NOW IF THE RELATIVE UNCERTAINTY OF B IS EPS, (NORM OF UNCERTAINTY/ C NORM OF B), IT IS SUGGESTED THAT TAU BE SET APPROXIMATELY EQUAL TO C EPS*(NORM OF A). C C THE USER MUST DIMENSION ALL ARRAYS APPEARING IN THE CALL LIST.. C A(MDA,N),(B(MDB,NB) OR B(M)),RNORM(NB),H(N),G(N),IP(N). THIS C PERMITS THE SOLUTION OF A RANGE OF PROBLEMS IN THE SAME ARRAY C SPACE. C C THE ENTIRE SET OF PARAMETERS FOR HFTI ARE C C INPUT.. C C A(*,*),MDA,M,N THE ARRAY A(*,*) INITIALLY CONTAINS THE M BY N C MATRIX A OF THE LEAST SQUARES PROBLEM AX = B. C THE FIRST DIMENSIONING PARAMETER OF THE ARRAY C A(*,*) IS MDA, WHICH MUST SATISFY MDA.GE.M C EITHER M.GE.N OR M.LT.N IS PERMITTED. THERE C IS NO RESTRICTION ON THE RANK OF A. THE C CONDITION MDA.LT.M IS CONSIDERED AN ERROR. C C B(*),MDB,NB IF NB = 0 THE SUBROUTINE WILL PERFORM THE C ORTHOGONAL DECOMPOSITION BUT WILL MAKE NO C REFERENCES TO THE ARRAY B(*). IF NB.GT.0 C THE ARRAY B(*) MUST INITIALLY CONTAIN THE M BY C NB MATRIX B OF THE LEAST SQUARES PROBLEM AX = C B. IF NB.GE.2 THE ARRAY B(*) MUST BE DOUBLY C SUBSCRIPTED WITH FIRST DIMENSIONING PARAMETER C MDB.GE.MAX(M,N). IF NB = 1 THE ARRAY B(*) MAY C BE EITHER DOUBLY OR SINGLY SUBSCRIPTED. IN C THE LATTER CASE THE VALUE OF MDB IS ARBITRARY C BUT IT SHOULD BE SET TO SOME VALID INTEGER C VALUE SUCH AS MDB = M. C C THE CONDITION OF NB.GT.1.AND.MDB.LT. MAX(M,N) C IS CONSIDERED AN ERROR. C C TAU ABSOLUTE TOLERANCE PARAMETER PROVIDED BY USER C FOR PSEUDORANK DETERMINATION. C C H(*),G(*),IP(*) ARRAYS OF WORKING SPACE USED BY HFTI. C C OUTPUT.. C C A(*,*) THE CONTENTS OF THE ARRAY A(*,*) WILL BE C MODIFIED BY THE SUBROUTINE. THESE CONTENTS C ARE NOT GENERALLY REQUIRED BY THE USER. C C B(*) ON RETURN THE ARRAY B(*) WILL CONTAIN THE N BY C NB SOLUTION MATRIX X. C C KRANK SET BY THE SUBROUTINE TO INDICATE THE C PSEUDORANK OF A. C C RNORM(*) ON RETURN, RNORM(J) WILL CONTAIN THE EUCLIDEAN C NORM OF THE RESIDUAL VECTOR FOR THE PROBLEM C DEFINED BY THE J-TH COLUMN VECTOR OF THE ARRAY C B(*,*) FOR J = 1,...,NB. C C H(*),G(*) ON RETURN THESE ARRAYS RESPECTIVELY CONTAIN C ELEMENTS OF THE PRE- AND POST-MULTIPLYING C HOUSEHOLDER TRANSFORMATIONS USED TO COMPUTE C THE MINIMUM EUCLIDEAN LENGTH SOLUTION. C C IP(*) ARRAY IN WHICH THE SUBROUTINE RECORDS INDICES C DESCRIBING THE PERMUTATION OF COLUMN VECTORS. C THE CONTENTS OF ARRAYS H(*),G(*) AND IP(*) C ARE NOT GENERALLY REQUIRED BY THE USER. C C++ REAL A(MDA,N), B(MDB,1), H(N), G(N), RNORM(NB), TAU REAL FACTOR, HMAX, SM1, ZERO, SM, TMP REAL DIFF, SQRT, ABS INTEGER IP(N) ZERO = 0.E0 FACTOR = 0.001E0 C K = 0 LDIAG = MIN0(M,N) IF (LDIAG.LE.0) GO TO 310 IF (.NOT.MDA.LT.M) GO TO 10 NERR = 2 IOPT = 2 CALL XERROR(31HHFTI MDA.LT.M.. PROBABLE ERROR., 31, NERR, IOPT) RETURN 10 CONTINUE C IF (.NOT.(NB.GT.1 .AND. MAX0(M,N).GT.MDB)) GO TO 20 NERR = 2 IOPT = 2 CALL XERROR(49HHFTI MDB.LT.MAX(M,N).AND.NB.GT.1. PROBABLE ERROR., * 49, NERR, IOPT) RETURN 20 CONTINUE C DO 100 J=1,LDIAG IF (J.EQ.1) GO TO 40 C C UPDATE SQUARED COLUMN LENGTHS AND FIND LMAX C .. LMAX = J DO 30 L=J,N H(L) = H(L) - A(J-1,L)**2 IF (H(L).GT.H(LMAX)) LMAX = L 30 CONTINUE IF (DIFF(HMAX+FACTOR*H(LMAX),HMAX)) 40, 40, 70 C C COMPUTE SQUARED COLUMN LENGTHS AND FIND LMAX C .. 40 LMAX = J DO 60 L=J,N H(L) = ZERO DO 50 I=J,M H(L) = H(L) + A(I,L)**2 50 CONTINUE IF (H(L).GT.H(LMAX)) LMAX = L 60 CONTINUE HMAX = H(LMAX) C .. C LMAX HAS BEEN DETERMINED C C DO COLUMN INTERCHANGES IF NEEDED. C .. 70 CONTINUE IP(J) = LMAX IF (IP(J).EQ.J) GO TO 90 DO 80 I=1,M TMP = A(I,J) A(I,J) = A(I,LMAX) A(I,LMAX) = TMP 80 CONTINUE H(LMAX) = H(J) 90 JCOL = MIN0(J+1,N) C C COMPUTE THE J-TH TRANSFORMATION AND APPLY IT TO A AND B. C .. CALL H12(1, J, J+1, M, A(1,J), 1, H(J), A(1,JCOL), 1, MDA, N-J) CALL H12(2, J, J+1, M, A(1,J), 1, H(J), B, 1, MDB, NB) 100 CONTINUE C C DETERMINE THE PSEUDORANK, K, USING THE TOLERANCE, TAU. C .. DO 110 J=1,LDIAG IF (ABS(A(J,J)).LE.TAU) GO TO 120 110 CONTINUE K = LDIAG GO TO 130 120 K = J - 1 130 KP1 = K + 1 C C COMPUTE THE NORMS OF THE RESIDUAL VECTORS. C IF (NB.LE.0) GO TO 170 DO 160 JB=1,NB TMP = ZERO IF (KP1.GT.M) GO TO 150 DO 140 I=KP1,M TMP = TMP + B(I,JB)**2 140 CONTINUE 150 RNORM(JB) = SQRT(TMP) 160 CONTINUE 170 CONTINUE C SPECIAL FOR PSEUDORANK = 0 IF (K.GT.0) GO TO 200 IF (NB.LE.0) GO TO 310 DO 190 JB=1,NB DO 180 I=1,N B(I,JB) = ZERO 180 CONTINUE 190 CONTINUE GO TO 310 C C IF THE PSEUDORANK IS LESS THAN N COMPUTE HOUSEHOLDER C DECOMPOSITION OF FIRST K ROWS. C .. 200 IF (K.EQ.N) GO TO 220 DO 210 II=1,K I = KP1 - II CALL H12(1, I, KP1, N, A(I,1), MDA, G(I), A, MDA, 1, I-1) 210 CONTINUE 220 CONTINUE C C IF (NB.LE.0) GO TO 310 DO 300 JB=1,NB C C SOLVE THE K BY K TRIANGULAR SYSTEM. C .. DO 250 L=1,K SM = ZERO I = KP1 - L IF (I.EQ.K) GO TO 240 IP1 = I + 1 DO 230 J=IP1,K SM = SM + A(I,J)*B(J,JB) 230 CONTINUE 240 SM1 = SM B(I,JB) = (B(I,JB)-SM1)/A(I,I) 250 CONTINUE C C COMPLETE COMPUTATION OF SOLUTION VECTOR. C .. IF (K.EQ.N) GO TO 280 DO 260 J=KP1,N B(J,JB) = ZERO 260 CONTINUE DO 270 I=1,K CALL H12(2, I, KP1, N, A(I,1), MDA, G(I), B(1,JB), 1, MDB, 1) 270 CONTINUE C C RE-ORDER THE SOLUTION VECTOR TO COMPENSATE FOR THE C COLUMN INTERCHANGES. C .. 280 DO 290 JJ=1,LDIAG J = LDIAG + 1 - JJ IF (IP(J).EQ.J) GO TO 290 L = IP(J) TMP = B(L,JB) B(L,JB) = B(J,JB) B(J,JB) = TMP 290 CONTINUE 300 CONTINUE C .. C THE SOLUTION VECTORS, X, ARE NOW C IN THE FIRST N ROWS OF THE ARRAY B(,). C 310 KRANK = K RETURN END SUBROUTINE H12 (MODE,LPIVOT,L1,M,U,IUE,UP,C,ICE,ICV,NCV) H 12 10 C C THE EDITING REQUIRED TO CONVERT THIS SUBROUTINE FROM SINGLE TO C DOUBLE PRECISION INVOLVES THE FOLLOWING CHARACTER STRING CHANGES. C USE AN EDITING COMMAND (CHANGE) /STRING-1/(TO)STRING-2/. C (START CHANGES AT LINE WITH C++ IN COLS. 1-3.) C /REAL (12 BLANKS)/DOUBLE PRECISION/,/SDOT/DDOT/,/ABS,/DABS,/, C /SSWAP/DSWAP/,/SQRT/DSQRT/,/ABS(/ DABS(/,/AMAX1/DMAX1/, C /SAXPY/DAXPY/,/E0/D0/ C C C C.L.LAWSON AND R.J.HANSON, JET PROPULSION LABORATORY, 1973 JUN 12 C TO APPEAR IN 'SOLVING LEAST SQUARES PROBLEMS', PRENTICE-HALL, 1974 C C MODIFIED AT SANDIA LABS., MAY 1977, TO -- C C 1) REMOVE DOUBLE PRECISION ACCUMULATION, AND C 2) INCLUDE USAGE OF THE BASIC LINEAR ALGEBRA PACKAGE FOR C VECTORS LONGER THAN A PARTICULAR THRESHOLD. C C CONSTRUCTION AND/OR APPLICATION OF A SINGLE C HOUSEHOLDER TRANSFORMATION.. Q = I + U*(U**T)/B C C MODE = 1 OR 2 TO SELECT ALGORITHM H1 OR H2 . C LPIVOT IS THE INDEX OF THE PIVOT ELEMENT. C L1,M IF L1 .LE. M THE TRANSFORMATION WILL BE CONSTRUCTED TO C ZERO ELEMENTS INDEXED FROM L1 THROUGH M. IF L1 GT. M C THE SUBROUTINE DOES AN IDENTITY TRANSFORMATION. C U(),IUE,UP ON ENTRY TO H1 U() CONTAINS THE PIVOT VECTOR. C IUE IS THE STORAGE INCREMENT BETWEEN ELEMENTS. C ON EXIT FROM H1 U() AND UP C CONTAIN QUANTITIES DEFINING THE VECTOR U OF THE C HOUSEHOLDER TRANSFORMATION. ON ENTRY TO H2 U() C AND UP SHOULD CONTAIN QUANTITIES PREVIOUSLY COMPUTED C BY H1. THESE WILL NOT BE MODIFIED BY H2. C C() ON ENTRY TO H1 OR H2 C() CONTAINS A MATRIX WHICH WILL BE C REGARDED AS A SET OF VECTORS TO WHICH THE HOUSEHOLDER C TRANSFORMATION IS TO BE APPLIED. ON EXIT C() CONTAINS THE C SET OF TRANSFORMED VECTORS. C ICE STORAGE INCREMENT BETWEEN ELEMENTS OF VECTORS IN C(). C ICV STORAGE INCREMENT BETWEEN VECTORS IN C(). C NCV NUMBER OF VECTORS IN C() TO BE TRANSFORMED. IF NCV .LE. 0 C NO OPERATIONS WILL BE DONE ON C(). C C SUBROUTINE H12 (MODE,LPIVOT,L1,M,U,IUE,UP,C,ICE,ICV,NCV) C++ REAL U(IUE,M), C(1), UP REAL B, CL, CLINV, ONE, SM, UL1M1 REAL ABS, AMAX1, SQRT, SDOT ONE=1.E0 C IF (0.GE.LPIVOT.OR.LPIVOT.GE.L1.OR.L1.GT.M) RETURN CL=ABS(U(1,LPIVOT)) IF (MODE.EQ.2) GO TO 60 C ****** CONSTRUCT THE TRANSFORMATION. ****** DO 10 J=L1,M 10 CL=AMAX1(ABS(U(1,J)),CL) IF (CL) 130,130,20 20 CLINV=ONE/CL SM=(U(1,LPIVOT)*CLINV)**2 DO 30 J=L1,M 30 SM=SM+(U(1,J)*CLINV)**2 CL=CL*SQRT(SM) IF (U(1,LPIVOT)) 50,50,40 40 CL=-CL 50 UP=U(1,LPIVOT)-CL U(1,LPIVOT)=CL GO TO 70 C ****** APPLY THE TRANSFORMATION I+U*(U**T)/B TO C. ****** C 60 IF (CL) 130,130,70 70 IF (NCV.LE.0) RETURN B=UP*U(1,LPIVOT) C B MUST BE NONPOSITIVE HERE. IF B = 0., RETURN. C IF (B) 80,130,130 80 B=ONE/B MML1P2=M-L1+2 IF (MML1P2.GT.20) GO TO 140 I2=1-ICV+ICE*(LPIVOT-1) INCR=ICE*(L1-LPIVOT) DO 120 J=1,NCV I2=I2+ICV I3=I2+INCR I4=I3 SM=C(I2)*UP DO 90 I=L1,M SM=SM+C(I3)*U(1,I) 90 I3=I3+ICE IF (SM) 100,120,100 100 SM=SM*B C(I2)=C(I2)+SM*UP DO 110 I=L1,M C(I4)=C(I4)+SM*U(1,I) 110 I4=I4+ICE 120 CONTINUE 130 RETURN 140 CONTINUE L1M1=L1-1 KL1=1+(L1M1-1)*ICE KL2=KL1 KLP=1+(LPIVOT-1)*ICE UL1M1=U(1,L1M1) U(1,L1M1)=UP IF (LPIVOT.EQ.L1M1) GO TO 150 CALL SSWAP(NCV,C(KL1),ICV,C(KLP),ICV) 150 CONTINUE DO 160 J=1,NCV SM=SDOT(MML1P2,U(1,L1M1),IUE,C(KL1),ICE) SM=SM*B CALL SAXPY (MML1P2,SM,U(1,L1M1),IUE,C(KL1),ICE) KL1=KL1+ICV 160 CONTINUE U(1,L1M1)=UL1M1 IF (LPIVOT.EQ.L1M1) RETURN KL1=KL2 CALL SSWAP(NCV,C(KL1),ICV,C(KLP),ICV) RETURN END REAL FUNCTION DIFF(X,Y) DIFF 10 C C THE EDITING REQUIRED TO CONVERT THIS SUBROUTINE FROM SINGLE TO C DOUBLE PRECISION INVOLVES THE FOLLOWING CHARACTER STRING CHANGES. C USE AN EDITING COMMAND (CHANGE) /STRING-1/(TO)STRING-2/. C (APPLY CHANGES TO ENTIRE PROGRAM UNIT.) C /REAL (12 BLANKS)/DOUBLE PRECISION/ C C C.L.LAWSON AND R.J.HANSON, JET PROPULSION LABORATORY, 1973 JUNE 7 C TO APPEAR IN 'SOLVING LEAST SQUARES PROBLEMS', PRENTICE-HALL, 1974 REAL X, Y DIFF=X-Y RETURN END SUBROUTINE SROTMG (SD1,SD2,SX1,SY1,SPARAM) SBLA 10 C C CONSTRUCT THE MODIFIED GIVENS TRANSFORMATION MATRIX H WHICH ZEROS C THE SECOND COMPONENT OF THE 2-VECTOR (SQRT(SD1)*SX1,SQRT(SD2)* C SY2)**T. C WITH SPARAM(1)=SFLAG, H HAS ONE OF THE FOLLOWING FORMS.. C C SFLAG=-1.E0 SFLAG=0.E0 SFLAG=1.E0 SFLAG=-2.E0 C C (SH11 SH12) (1.E0 SH12) (SH11 1.E0) (1.E0 0.E0) C H=( ) ( ) ( ) ( ) C (SH21 SH22), (SH21 1.E0), (-1.E0 SH22), (0.E0 1.E0). C C END OF ABSTRACT DIMENSION SPARAM(5) C DATA ZERO,ONE,TWO /0.E0,1.E0,2.E0/,IFLAG/1/ DATA GAM,GAMSQ,RGAM,RGAMSQ/4096.E0,1.678E7,2.441E-4,5.960E-8/ C IF(.NOT. SD1 .LT. ZERO) GO TO 10 C GO ZERO-H-D-AND-SX1.. GO TO 60 10 CONTINUE C CASE-SD1-NONNEGATIVE SP2=SD2*SY1 IF(.NOT. SP2 .EQ. ZERO) GO TO 20 SFLAG=-TWO GO TO 260 C REGULAR-CASE.. 20 CONTINUE SP1=SD1*SX1 SQ2=SP2*SY1 SQ1=SP1*SX1 C IF(.NOT. ABS(SQ1) .GT. ABS(SQ2)) GO TO 40 SH21=-SY1/SX1 SH12=SP2/SP1 C SU=ONE-SH12*SH21 C IF(.NOT. SU .LE. ZERO) GO TO 30 C GO ZERO-H-D-AND-SX1.. GO TO 60 30 CONTINUE SFLAG=ZERO SD1=SD1/SU SD2=SD2/SU SX1=SX1*SU C GO SCALE-CHECK.. GO TO 100 40 CONTINUE IF(.NOT. SQ2 .LT. ZERO) GO TO 50 C GO ZERO-H-D-AND-SX1.. GO TO 60 50 CONTINUE SFLAG=ONE SH11=SP1/SP2 SH22=SX1/SY1 SU=ONE+SH11*SH22 STEMP=SD2/SU SD2=SD1/SU SD1=STEMP SX1=SY1*SU C GO SCALE-CHECK GO TO 100 C PROCEDURE..ZERO-H-D-AND-SX1.. 60 CONTINUE SFLAG=-ONE SH11=ZERO SH12=ZERO SH21=ZERO SH22=ZERO C SD1=ZERO SD2=ZERO SX1=ZERO C RETURN.. GO TO 220 C PROCEDURE..FIX-H.. 70 CONTINUE IF(.NOT. SFLAG .GE. ZERO) GO TO 90 C IF(.NOT. SFLAG .EQ. ZERO) GO TO 80 SH11=ONE SH22=ONE SFLAG=-ONE GO TO 90 80 CONTINUE SH21=-ONE SH12=ONE SFLAG=-ONE 90 CONTINUE GO TO IGO,(120,150,180,210) C PROCEDURE..SCALE-CHECK 100 CONTINUE IF(.NOT. IFLAG.EQ.1) GO TO 105 C C RECOMPUTE RESCALING PARAMETERS C MORE ACCURATELY.. C RGAM = ONE/GAM GAMSQ = GAM**2 RGAMSQ = RGAM**2 IFLAG = 2 105 CONTINUE 110 CONTINUE IF(.NOT. SD1 .LE. RGAMSQ) GO TO 130 IF(SD1 .EQ. ZERO) GO TO 160 ASSIGN 120 TO IGO C FIX-H.. GO TO 70 120 CONTINUE SD1=SD1*GAMSQ SX1=SX1*RGAM SH11=SH11*RGAM SH12=SH12*RGAM GO TO 110 130 CONTINUE 140 CONTINUE IF(.NOT. SD1 .GE. GAMSQ) GO TO 160 ASSIGN 150 TO IGO C FIX-H.. GO TO 70 150 CONTINUE SD1=SD1*RGAMSQ SX1=SX1*GAM SH11=SH11*GAM SH12=SH12*GAM GO TO 140 160 CONTINUE 170 CONTINUE IF(.NOT. ABS(SD2) .LE. RGAMSQ) GO TO 190 IF(SD2 .EQ. ZERO) GO TO 220 ASSIGN 180 TO IGO C FIX-H.. GO TO 70 180 CONTINUE SD2=SD2*GAMSQ SH21=SH21*RGAM SH22=SH22*RGAM GO TO 170 190 CONTINUE 200 CONTINUE IF(.NOT. ABS(SD2) .GE. GAMSQ) GO TO 220 ASSIGN 210 TO IGO C FIX-H.. GO TO 70 210 CONTINUE SD2=SD2*RGAMSQ SH21=SH21*GAM SH22=SH22*GAM GO TO 200 220 CONTINUE IF(SFLAG)250,230,240 230 CONTINUE SPARAM(3)=SH21 SPARAM(4)=SH12 GO TO 260 240 CONTINUE SPARAM(2)=SH11 SPARAM(5)=SH22 GO TO 260 250 CONTINUE SPARAM(2)=SH11 SPARAM(3)=SH21 SPARAM(4)=SH12 SPARAM(5)=SH22 260 CONTINUE SPARAM(1)=SFLAG RETURN END SUBROUTINE SCOPY(N,SX,INCX,SY,INCY) SBLA 10 C C COPY SINGLE PRECISION SX TO SINGLE PRECISION SY. C C END OF ABSTRACT REAL SX(1),SY(1) C IF(N.LE.0)RETURN IF(INCX.EQ.INCY) IF(INCX-1) 5,20,60 5 CONTINUE C C CODE FOR UNEQUAL OR NONPOSITIVE INCREMENTS. C IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N SY(IY) = SX(IX) IX = IX + INCX IY = IY + INCY 10 CONTINUE RETURN C C CODE FOR BOTH INCREMENTS EQUAL TO 1 C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 7. C 20 M = N - (N/7)*7 IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M SY(I) = SX(I) 30 CONTINUE IF( N .LT. 7 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,7 SY(I) = SX(I) SY(I + 1) = SX(I + 1) SY(I + 2) = SX(I + 2) SY(I + 3) = SX(I + 3) SY(I + 4) = SX(I + 4) SY(I + 5) = SX(I + 5) SY(I + 6) = SX(I + 6) 50 CONTINUE RETURN C C CODE FOR EQUAL, POSITIVE, NONUNIT INCREMENTS. C 60 CONTINUE NS = N*INCX DO 70 I=1,NS,INCX SY(I) = SX(I) 70 CONTINUE RETURN END SUBROUTINE SSWAP (N,SX,INCX,SY,INCY) SBLA 10 C C INTERCHANGE SINGLE PRECISION SX AND SINGLE PRECISION SY. C C END OF ABSTRACT REAL SX(1),SY(1),STEMP1,STEMP2,STEMP3 C IF(N.LE.0)RETURN IF(INCX.EQ.INCY) IF(INCX-1) 5,20,60 5 CONTINUE C C CODE FOR UNEQUAL OR NONPOSITIVE INCREMENTS. C IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N STEMP1 = SX(IX) SX(IX) = SY(IY) SY(IY) = STEMP1 IX = IX + INCX IY = IY + INCY 10 CONTINUE RETURN C C CODE FOR BOTH INCREMENTS EQUAL TO 1 C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 3. C 20 M = N - (N/3)*3 IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M STEMP1 = SX(I) SX(I) = SY(I) SY(I) = STEMP1 30 CONTINUE IF( N .LT. 3 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,3 STEMP1 = SX(I) STEMP2 = SX(I+1) STEMP3 = SX(I+2) SX(I) = SY(I) SX(I+1) = SY(I+1) SX(I+2) = SY(I+2) SY(I) = STEMP1 SY(I+1) = STEMP2 SY(I+2) = STEMP3 50 CONTINUE RETURN 60 CONTINUE C C CODE FOR EQUAL, POSITIVE, NONUNIT INCREMENTS. C NS = N*INCX DO 70 I=1,NS,INCX STEMP1 = SX(I) SX(I) = SY(I) SY(I) = STEMP1 70 CONTINUE RETURN END REAL FUNCTION SNRM2 ( N, SX, INCX) SBLA 10 INTEGER NEXT REAL SX(1), CUTLO, CUTHI, HITEST, SUM, XMAX, ZERO, ONE DATA ZERO, ONE /0.0E0, 1.0E0/ C C EUCLIDEAN NORM OF THE N-VECTOR STORED IN SX() WITH STORAGE C INCREMENT INCX . C IF N .LE. 0 RETURN WITH RESULT = 0. C IF N .GE. 1 THEN INCX MUST BE .GE. 1 C C C.L.LAWSON, 1978 JAN 08 C C FOUR PHASE METHOD USING TWO BUILT-IN CONSTANTS THAT ARE C HOPEFULLY APPLICABLE TO ALL MACHINES. C CUTLO = MAXIMUM OF SQRT(U/EPS) OVER ALL KNOWN MACHINES. C CUTHI = MINIMUM OF SQRT(V) OVER ALL KNOWN MACHINES. C WHERE C EPS = SMALLEST NO. SUCH THAT EPS + 1. .GT. 1. C U = SMALLEST POSITIVE NO. (UNDERFLOW LIMIT) C V = LARGEST NO. (OVERFLOW LIMIT) C C BRIEF OUTLINE OF ALGORITHM.. C C PHASE 1 SCANS ZERO COMPONENTS. C MOVE TO PHASE 2 WHEN A COMPONENT IS NONZERO AND .LE. CUTLO C MOVE TO PHASE 3 WHEN A COMPONENT IS .GT. CUTLO C MOVE TO PHASE 4 WHEN A COMPONENT IS .GE. CUTHI/M C WHERE M = N FOR X() REAL AND M = 2*N FOR COMPLEX. C C VALUES FOR CUTLO AND CUTHI.. C FROM THE ENVIRONMENTAL PARAMETERS LISTED IN THE IMSL CONVERTER C DOCUMENT THE LIMITING VALUES ARE AS FOLLOWS.. C CUTLO, S.P. U/EPS = 2**(-102) FOR HONEYWELL. CLOSE SECONDS ARE C UNIVAC AND DEC AT 2**(-103) C THUS CUTLO = 2**(-51) = 4.44089E-16 C CUTHI, S.P. V = 2**127 FOR UNIVAC, HONEYWELL, AND DEC. C THUS CUTHI = 2**(63.5) = 1.30438E19 C CUTLO, D.P. U/EPS = 2**(-67) FOR HONEYWELL AND DEC. C THUS CUTLO = 2**(-33.5) = 8.23181D-11 C CUTHI, D.P. SAME AS S.P. CUTHI = 1.30438D19 C DATA CUTLO, CUTHI / 8.232D-11, 1.304D19 / C DATA CUTLO, CUTHI / 4.441E-16, 1.304E19 / C END OF ABSTRACT DATA CUTLO, CUTHI / 4.441E-16, 1.304E19 / C IF(N .GT. 0) GO TO 10 SNRM2 = ZERO GO TO 300 C 10 ASSIGN 30 TO NEXT SUM = ZERO NN = N * INCX C BEGIN MAIN LOOP I = 1 20 GO TO NEXT,(30, 50, 70, 110) 30 IF( ABS(SX(I)) .GT. CUTLO) GO TO 85 ASSIGN 50 TO NEXT XMAX = ZERO C C PHASE 1. SUM IS ZERO C 50 IF( SX(I) .EQ. ZERO) GO TO 200 IF( ABS(SX(I)) .GT. CUTLO) GO TO 85 C C PREPARE FOR PHASE 2. ASSIGN 70 TO NEXT GO TO 105 C C PREPARE FOR PHASE 4. C 100 I = J ASSIGN 110 TO NEXT SUM = (SUM / SX(I)) / SX(I) 105 XMAX = ABS(SX(I)) GO TO 115 C C PHASE 2. SUM IS SMALL. C SCALE TO AVOID DESTRUCTIVE UNDERFLOW. C 70 IF( ABS(SX(I)) .GT. CUTLO ) GO TO 75 C C COMMON CODE FOR PHASES 2 AND 4. C IN PHASE 4 SUM IS LARGE. SCALE TO AVOID OVERFLOW. C 110 IF( ABS(SX(I)) .LE. XMAX ) GO TO 115 SUM = ONE + SUM * (XMAX / SX(I))**2 XMAX = ABS(SX(I)) GO TO 200 C 115 SUM = SUM + (SX(I)/XMAX)**2 GO TO 200 C C C PREPARE FOR PHASE 3. C 75 SUM = (SUM * XMAX) * XMAX C C C FOR REAL OR D.P. SET HITEST = CUTHI/N C FOR COMPLEX SET HITEST = CUTHI/(2*N) C 85 HITEST = CUTHI/FLOAT( N ) C C PHASE 3. SUM IS MID-RANGE. NO SCALING. C DO 95 J =I,NN,INCX IF(ABS(SX(J)) .GE. HITEST) GO TO 100 95 SUM = SUM + SX(J)**2 SNRM2 = SQRT( SUM ) GO TO 300 C 200 CONTINUE I = I + INCX IF ( I .LE. NN ) GO TO 20 C C END OF MAIN LOOP. C C COMPUTE SQUARE ROOT AND ADJUST FOR SCALING. C SNRM2 = XMAX * SQRT(SUM) 300 CONTINUE RETURN END REAL FUNCTION SASUM(N,SX,INCX) SBLA 10 C C RETURNS SUM OF MAGNITUDES OF SINGLE PRECISION SX. C C END OF ABSTRACT REAL SX(1) C SASUM = 0.0E0 IF(N.LE.0)RETURN IF(INCX.EQ.1)GOTO 20 C C CODE FOR INCREMENTS NOT EQUAL TO 1. C NS = N*INCX DO 10 I=1,NS,INCX SASUM = SASUM + ABS(SX(I)) 10 CONTINUE RETURN C C CODE FOR INCREMENTS EQUAL TO 1. C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 6. C 20 M = N - (N/6)*6 IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M SASUM = SASUM + ABS(SX(I)) 30 CONTINUE IF( N .LT. 6 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,6 SASUM = SASUM + ABS(SX(I)) + ABS(SX(I + 1)) + ABS(SX(I + 2)) A + ABS(SX(I + 3)) + ABS(SX(I + 4)) + ABS(SX(I + 5)) 50 CONTINUE RETURN END SUBROUTINE SSCAL(N,SA,SX,INCX) SBLA 10 C C REPLACE SINGLE PRECISION SX BY SINGLE PRECISION SA*SX. C C END OF ABSTRACT REAL SA,SX(1) C IF(N.LE.0)RETURN IF(INCX.EQ.1)GOTO 20 C C CODE FOR INCREMENTS NOT EQUAL TO 1. C NS = N*INCX DO 10 I = 1,NS,INCX SX(I) = SA*SX(I) 10 CONTINUE RETURN C C CODE FOR INCREMENTS EQUAL TO 1. C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 5. C 20 M = N - (N/5)*5 IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M SX(I) = SA*SX(I) 30 CONTINUE IF( N .LT. 5 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,5 SX(I) = SA*SX(I) SX(I + 1) = SA*SX(I + 1) SX(I + 2) = SA*SX(I + 2) SX(I + 3) = SA*SX(I + 3) SX(I + 4) = SA*SX(I + 4) 50 CONTINUE RETURN END INTEGER FUNCTION ISAMAX(N,SX,INCX) SBLA 10 C C FIND SMALLEST INDEX OF MAXIMUM MAGNITUDE OF SINGLE PRECISION SX. C C END OF ABSTRACT REAL SX(1),SMAX,XMAG C ISAMAX = 0 IF(N.LE.0) RETURN ISAMAX = 1 IF(N.LE.1)RETURN IF(INCX.EQ.1)GOTO 20 C C CODE FOR INCREMENTS NOT EQUAL TO 1. C SMAX = ABS(SX(1)) NS = N*INCX II = 1 DO 10 I=1,NS,INCX XMAG = ABS(SX(I)) IF(XMAG.LE.SMAX) GO TO 5 ISAMAX = II SMAX = XMAG 5 II = II + 1 10 CONTINUE RETURN C C CODE FOR INCREMENTS EQUAL TO 1. C 20 SMAX = ABS(SX(1)) DO 30 I = 2,N XMAG = ABS(SX(I)) IF(XMAG.LE.SMAX) GO TO 30 ISAMAX = I SMAX = XMAG 30 CONTINUE RETURN END REAL FUNCTION SDOT(N,SX,INCX,SY,INCY) SBLA 10 C C RETURNS THE DOT PRODUCT OF SINGLE PRECISION SX AND SY. C REAL SX(1),SY(1) SDOT = 0.0E0 IF(N.LE.0)RETURN IF(INCX.EQ.INCY) IF(INCX-1)5,20,60 5 CONTINUE C C CODE FOR UNEQUAL INCREMENTS OR NONPOSITIVE INCREMENTS. C IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N SDOT = SDOT + SX(IX)*SY(IY) IX = IX + INCX IY = IY + INCY 10 CONTINUE RETURN C C CODE FOR BOTH INCREMENTS EQUAL TO 1 C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 5. C 20 M = N - (N/5)*5 IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M SDOT = SDOT + SX(I)*SY(I) 30 CONTINUE IF( N .LT. 5 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,5 SDOT = SDOT + SX(I)*SY(I) + SX(I + 1)*SY(I + 1) + * SX(I + 2)*SY(I + 2) + SX(I + 3)*SY(I + 3) + SX(I + 4)*SY(I + 4) 50 CONTINUE RETURN C C CODE FOR POSITIVE EQUAL INCREMENTS .NE.1. C 60 CONTINUE NS=N*INCX DO 70 I=1,NS,INCX SDOT = SDOT + SX(I)*SY(I) 70 CONTINUE RETURN END SUBROUTINE SAXPY(N,SA,SX,INCX,SY,INCY) SBLA 10 C C OVERWRITE SINGLE PRECISION SY WITH SINGLE PRECISION SA*SX +SY. C REAL SX(1),SY(1),SA IF(N.LE.0.OR.SA.EQ.0.E0) RETURN IF(INCX.EQ.INCY) IF(INCX-1) 5,20,60 5 CONTINUE C C CODE FOR NONEQUAL OR NONPOSITIVE INCREMENTS. C IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N SY(IY) = SY(IY) + SA*SX(IX) IX = IX + INCX IY = IY + INCY 10 CONTINUE RETURN C C CODE FOR BOTH INCREMENTS EQUAL TO 1 C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 4. C 20 M = N - (N/4)*4 IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M SY(I) = SY(I) + SA*SX(I) 30 CONTINUE IF( N .LT. 4 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,4 SY(I) = SY(I) + SA*SX(I) SY(I + 1) = SY(I + 1) + SA*SX(I + 1) SY(I + 2) = SY(I + 2) + SA*SX(I + 2) SY(I + 3) = SY(I + 3) + SA*SX(I + 3) 50 CONTINUE RETURN C C CODE FOR EQUAL, POSITIVE, NONUNIT INCREMENTS. C 60 CONTINUE NS = N*INCX DO 70 I=1,NS,INCX SY(I) = SA*SX(I) + SY(I) 70 CONTINUE RETURN END SUBROUTINE SROTM (N,SX,INCX,SY,INCY,SPARAM) SBLA 10 C C APPLY THE MODIFIED GIVENS TRANSFORMATION, H, TO THE 2 BY N MATRIX C C (SX(1) SX(N)) C ( ... ) C (SY(1) SY(N)) C C WITH SPARAM(1)=SFLAG, H HAS ONE OF THE FOLLOWING FORMS.. C C SFLAG=-1.E0 SFLAG=0.E0 SFLAG=1.E0 SFLAG=-2.E0 C C (SH11 SH12) (1.E0 SH12) (SH11 1.E0) (1.E0 0.E0) C H=( ) ( ) ( ) ( ) C (SH21 SH22), (SH21 1.E0), (-1.E0 SH22), (0.E0 1.E0). C DIMENSION SX(1),SY(1),SPARAM(5) DATA ZERO,TWO /0.E0,2.E0/ C SFLAG=SPARAM(1) IF(N .LE. 0 .OR.(SFLAG+TWO.EQ.ZERO)) GO TO 140 IF(.NOT.(INCX.EQ.INCY.AND. INCX .GT.0)) GO TO 70 C NSTEPS=N*INCX IF(SFLAG) 50,10,30 10 CONTINUE SH12=SPARAM(4) SH21=SPARAM(3) DO 20 I=1,NSTEPS,INCX W=SX(I) Z=SY(I) SX(I)=W+Z*SH12 SY(I)=W*SH21+Z 20 CONTINUE GO TO 140 30 CONTINUE SH11=SPARAM(2) SH22=SPARAM(5) DO 40 I=1,NSTEPS,INCX W=SX(I) Z=SY(I) SX(I)=W*SH11+Z SY(I)=-W+SH22*Z 40 CONTINUE GO TO 140 50 CONTINUE SH11=SPARAM(2) SH12=SPARAM(4) SH21=SPARAM(3) SH22=SPARAM(5) DO 60 I=1,NSTEPS,INCX W=SX(I) Z=SY(I) SX(I)=W*SH11+Z*SH12 SY(I)=W*SH21+Z*SH22 60 CONTINUE GO TO 140 70 CONTINUE KX=1 KY=1 IF(INCX .LT. 0) KX=1+(1-N)*INCX IF(INCY .LT. 0) KY=1+(1-N)*INCY C IF(SFLAG)120,80,100 80 CONTINUE SH12=SPARAM(4) SH21=SPARAM(3) DO 90 I=1,N W=SX(KX) Z=SY(KY) SX(KX)=W+Z*SH12 SY(KY)=W*SH21+Z KX=KX+INCX KY=KY+INCY 90 CONTINUE GO TO 140 100 CONTINUE SH11=SPARAM(2) SH22=SPARAM(5) DO 110 I=1,N W=SX(KX) Z=SY(KY) SX(KX)=W*SH11+Z SY(KY)=-W+SH22*Z KX=KX+INCX KY=KY+INCY 110 CONTINUE GO TO 140 120 CONTINUE SH11=SPARAM(2) SH12=SPARAM(4) SH21=SPARAM(3) SH22=SPARAM(5) DO 130 I=1,N W=SX(KX) Z=SY(KY) SX(KX)=W*SH11+Z*SH12 SY(KY)=W*SH21+Z*SH22 KX=KX+INCX KY=KY+INCY 130 CONTINUE 140 CONTINUE RETURN END SUBROUTINE DROTMG (DD1,DD2,DX1,DY1,DPARAM) DBLA 10 C***BEGIN PROLOGUE DROTMG C***REVISION 3/1/80 C***CATEGORY NO. C***KEYWORD(S) C***AUTHOR--DATE WRITTEN C***PURPOSE C CONSTRUCT D.P. MODIFIED GIVENS TRANSFORMATION C***DESCRIPTION C B L A S SUBPROGRAM C DESCRIPTION OF PARAMETERS C C --INPUT-- C DD1 DOUBLE PRECISION SCALAR C DD2 DOUBLE PRECISION SCALAR C DX1 DOUBLE PRECISION SCALAR C DX2 DOUBLE PRECISION SCALAR C DPARAM D.P. 5-VECTOR. DPARAM(1)=DFLAG DEFINED BELOW. C ELEMENTS 2-5 DEFINE THE TRANSFORMATION MATRIX H. C C --OUTPUT-- C DD1 CHANGED TO REPRESENT THE EFFECT OF THE TRANSFORMATION C DD2 CHANGED TO REFLECT THE TRANSFORMATION C DX1 CHANGED TO REFLECT THE TRANSFORMATION C DX2 UNCHANGED C C CONSTRUCT THE MODIFIED GIVENS TRANSFORMATION MATRIX H WHICH ZEROS C THE SECOND COMPONENT OF THE 2-VECTOR (DSQRT(DD1)*DX1,DSQRT(DD2)* C DY2)**T. C WITH DPARAM(1)=DFLAG, H HAS ONE OF THE FOLLOWING FORMS.. C C DFLAG=-1.D0 DFLAG=0.D0 DFLAG=1.D0 DFLAG=-2.D0 C C (DH11 DH12) (1.D0 DH12) (DH11 1.D0) (1.D0 0.D0) C H=( ) ( ) ( ) ( ) C (DH21 DH22), (DH21 1.D0), (-1.D0 DH22), (0.D0 1.D0). C LOCATIONS 2-5 OF DPARAM CONTAIN DH11, DH21, DH12, AND DH22 C RESPECTIVELY. (VALUES OF 1.D0, -1.D0, OR 0.D0 IMPLIED BY THE C VALUE OF DPARAM(1) ARE NOT STORED IN DPARAM.) C C***REFERENCE(S) C LAWSON C.L., HANSON R.J., KINCAID D.R., KROGH F.T., C *BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE*, C ALGORITHM NO. 539, TRANSACTIONS ON MATHEMATICAL SOFTWARE, C VOLUME 5, NUMBER 3, SEPTEMBER 1979, 308-323 C***ROUTINES CALLED NONE C***CARD COUNT IS 198 WITH 69 COMMENTS C***END PROLOGUE C DOUBLE PRECISION GAM,ONE,RGAMSQ,DD2,DH11,DH21,DPARAM,DP2, 1 DQ2,DU,DY1,ZERO,GAMSQ,DD1,DFLAG,DH12,DH22,DP1,DQ1, 2 DTEMP,DX1,TWO DIMENSION DPARAM(5) DATA ZERO,ONE,TWO /0.D0,1.D0,2.D0/ DATA GAM,GAMSQ,RGAMSQ/4096.D0,16777216.D0,5.9604645D-8/ C***FIRST EXECUTABLE STATEMENT IF(.NOT. DD1 .LT. ZERO) GO TO 10 C GO ZERO-H-D-AND-DX1.. GO TO 60 10 CONTINUE C CASE-DD1-NONNEGATIVE DP2=DD2*DY1 IF(.NOT. DP2 .EQ. ZERO) GO TO 20 DFLAG=-TWO GO TO 260 C REGULAR-CASE.. 20 CONTINUE DP1=DD1*DX1 DQ2=DP2*DY1 DQ1=DP1*DX1 C IF(.NOT. DABS(DQ1) .GT. DABS(DQ2)) GO TO 40 DH21=-DY1/DX1 DH12=DP2/DP1 C DU=ONE-DH12*DH21 C IF(.NOT. DU .LE. ZERO) GO TO 30 C GO ZERO-H-D-AND-DX1.. GO TO 60 30 CONTINUE DFLAG=ZERO DD1=DD1/DU DD2=DD2/DU DX1=DX1*DU C GO SCALE-CHECK.. GO TO 100 40 CONTINUE IF(.NOT. DQ2 .LT. ZERO) GO TO 50 C GO ZERO-H-D-AND-DX1.. GO TO 60 50 CONTINUE DFLAG=ONE DH11=DP1/DP2 DH22=DX1/DY1 DU=ONE+DH11*DH22 DTEMP=DD2/DU DD2=DD1/DU DD1=DTEMP DX1=DY1*DU C GO SCALE-CHECK GO TO 100 C PROCEDURE..ZERO-H-D-AND-DX1.. 60 CONTINUE DFLAG=-ONE DH11=ZERO DH12=ZERO DH21=ZERO DH22=ZERO C DD1=ZERO DD2=ZERO DX1=ZERO C RETURN.. GO TO 220 C PROCEDURE..FIX-H.. 70 CONTINUE IF(.NOT. DFLAG .GE. ZERO) GO TO 90 C IF(.NOT. DFLAG .EQ. ZERO) GO TO 80 DH11=ONE DH22=ONE DFLAG=-ONE GO TO 90 80 CONTINUE DH21=-ONE DH12=ONE DFLAG=-ONE 90 CONTINUE GO TO IGO,(120,150,180,210) C PROCEDURE..SCALE-CHECK 100 CONTINUE 110 CONTINUE IF(.NOT. DD1 .LE. RGAMSQ) GO TO 130 IF(DD1 .EQ. ZERO) GO TO 160 ASSIGN 120 TO IGO C FIX-H.. GO TO 70 120 CONTINUE DD1=DD1*GAM**2 DX1=DX1/GAM DH11=DH11/GAM DH12=DH12/GAM GO TO 110 130 CONTINUE 140 CONTINUE IF(.NOT. DD1 .GE. GAMSQ) GO TO 160 ASSIGN 150 TO IGO C FIX-H.. GO TO 70 150 CONTINUE DD1=DD1/GAM**2 DX1=DX1*GAM DH11=DH11*GAM DH12=DH12*GAM GO TO 140 160 CONTINUE 170 CONTINUE IF(.NOT. DABS(DD2) .LE. RGAMSQ) GO TO 190 IF(DD2 .EQ. ZERO) GO TO 220 ASSIGN 180 TO IGO C FIX-H.. GO TO 70 180 CONTINUE DD2=DD2*GAM**2 DH21=DH21/GAM DH22=DH22/GAM GO TO 170 190 CONTINUE 200 CONTINUE IF(.NOT. DABS(DD2) .GE. GAMSQ) GO TO 220 ASSIGN 210 TO IGO C FIX-H.. GO TO 70 210 CONTINUE DD2=DD2/GAM**2 DH21=DH21*GAM DH22=DH22*GAM GO TO 200 220 CONTINUE IF(DFLAG)250,230,240 230 CONTINUE DPARAM(3)=DH21 DPARAM(4)=DH12 GO TO 260 240 CONTINUE DPARAM(2)=DH11 DPARAM(5)=DH22 GO TO 260 250 CONTINUE DPARAM(2)=DH11 DPARAM(3)=DH21 DPARAM(4)=DH12 DPARAM(5)=DH22 260 CONTINUE DPARAM(1)=DFLAG RETURN END SUBROUTINE DCOPY(N,DX,INCX,DY,INCY) DBLA 10 C***BEGIN PROLOGUE DCOPY C***REVISION 3/1/80 C***CATEGORY NO. C***KEYWORD(S) C***AUTHOR--DATE WRITTEN 10/79,LAWSON C. (JPL),HANSON R. (SLA), C KINCAID D. (U TEXAS), KROGH F. (JPL) C***PURPOSE C D.P. VECTOR COPY Y = X C***DESCRIPTION C B L A S SUBPROGRAM C DESCRIPTION OF PARAMETERS C C --INPUT-- C N NUMBER OF ELEMENTS IN INPUT VECTOR(S) C DX DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCX STORAGE SPACING BETWEEN ELEMENTS OF DX C DY DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCY STORAGE SPACING BETWEEN ELEMENTS OF DY C C --OUTPUT-- C DY COPY OF VECTOR DX (UNCHANGED IF N.LE.0) C C COPY DOUBLE PRECISION DX TO DOUBLE PRECISION DY. C FOR I = 0 TO N-1, COPY DX(LX+I*INCX) TO DY(LY+I*INCY), C WHERE LX = 1 IF INCX .GE. 0, ELSE LX = (-INCX)*N, AND LY IS C DEFINED IN A SIMILAR WAY USING INCY. C C***REFERENCE(S) C LAWSON C.L., HANSON R.J., KINCAID D.R., KROGH F.T., C *BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE*, C ALGORITHM NO. 539, TRANSACTIONS ON MATHEMATICAL SOFTWARE, C VOLUME 5, NUMBER 3, SEPTEMBER 1979, 308-323 C***ROUTINES CALLED NONE C***CARD COUNT IS 88 WITH 49 COMMENTS C***END PROLOGUE C DOUBLE PRECISION DX(1),DY(1) C***FIRST EXECUTABLE STATEMENT IF(N.LE.0)RETURN IF(INCX.EQ.INCY) IF(INCX-1) 5,20,60 5 CONTINUE C C CODE FOR UNEQUAL OR NONPOSITIVE INCREMENTS. C IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N DY(IY) = DX(IX) IX = IX + INCX IY = IY + INCY 10 CONTINUE RETURN C C CODE FOR BOTH INCREMENTS EQUAL TO 1 C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 7. C 20 M = MOD(N,7) IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M DY(I) = DX(I) 30 CONTINUE IF( N .LT. 7 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,7 DY(I) = DX(I) DY(I + 1) = DX(I + 1) DY(I + 2) = DX(I + 2) DY(I + 3) = DX(I + 3) DY(I + 4) = DX(I + 4) DY(I + 5) = DX(I + 5) DY(I + 6) = DX(I + 6) 50 CONTINUE RETURN C C CODE FOR EQUAL, POSITIVE, NONUNIT INCREMENTS. C 60 CONTINUE NS=N*INCX DO 70 I=1,NS,INCX DY(I) = DX(I) 70 CONTINUE RETURN END SUBROUTINE DSWAP(N,DX,INCX,DY,INCY) DBLA 10 C***BEGIN PROLOGUE DSWAP C***REVISION 3/1/80 C***CATEGORY NO. C***KEYWORD(S) C***AUTHOR--DATE WRITTEN 10/79,LAWSON C. (JPL),HANSON R. (SLA), C KINCAID D. (U TEXAS), KROGH F. (JPL) C***PURPOSE C INTERCHANGE D.P. VECTORS C***DESCRIPTION C B L A S SUBPROGRAM C DESCRIPTION OF PARAMETERS C C --INPUT-- C N NUMBER OF ELEMENTS IN INPUT VECTOR(S) C DX DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCX STORAGE SPACING BETWEEN ELEMENTS OF DX C DY DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCY STORAGE SPACING BETWEEN ELEMENTS OF DY C C --OUTPUT-- C DX INPUT VECTOR DY (UNCHANGED IF N.LE.0) C DY INPUT VECTOR DX (UNCHANGED IF N.LE.0) C C INTERCHANGE DOUBLE PRECISION DX AND DOUBLE PRECISION DY. C FOR I = 0 TO N-1, INTERCHANGE DX(LX+I*INCX) AND DY(LY+I*INCY), C WHERE LX = 1 IF INCX .GE. 0, ELSE LX = (-INCX)*N, AND LY IS C DEFINED IN A SIMILAR WAY USING INCY. C C***REFERENCE(S) C LAWSON C.L., HANSON R.J., KINCAID D.R., KROGH F.T., C *BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE*, C ALGORITHM NO. 539, TRANSACTIONS ON MATHEMATICAL SOFTWARE, C VOLUME 5, NUMBER 3, SEPTEMBER 1979, 308-323 C***ROUTINES CALLED NONE C***CARD COUNT IS 97 WITH 50 COMMENTS C***END PROLOGUE C DOUBLE PRECISION DX(1),DY(1),DTEMP1,DTEMP2,DTEMP3 C***FIRST EXECUTABLE STATEMENT IF(N.LE.0)RETURN IF(INCX.EQ.INCY) IF(INCX-1) 5,20,60 5 CONTINUE C C CODE FOR UNEQUAL OR NONPOSITIVE INCREMENTS. C IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N DTEMP1 = DX(IX) DX(IX) = DY(IY) DY(IY) = DTEMP1 IX = IX + INCX IY = IY + INCY 10 CONTINUE RETURN C C CODE FOR BOTH INCREMENTS EQUAL TO 1 C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 3. C 20 M = MOD(N,3) IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M DTEMP1 = DX(I) DX(I) = DY(I) DY(I) = DTEMP1 30 CONTINUE IF( N .LT. 3 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,3 DTEMP1 = DX(I) DTEMP2 = DX(I+1) DTEMP3 = DX(I+2) DX(I) = DY(I) DX(I+1) = DY(I+1) DX(I+2) = DY(I+2) DY(I) = DTEMP1 DY(I+1) = DTEMP2 DY(I+2) = DTEMP3 50 CONTINUE RETURN 60 CONTINUE C C CODE FOR EQUAL, POSITIVE, NONUNIT INCREMENTS. C NS = N*INCX DO 70 I=1,NS,INCX DTEMP1 = DX(I) DX(I) = DY(I) DY(I) = DTEMP1 70 CONTINUE RETURN END DOUBLE PRECISION FUNCTION DNRM2 ( N, DX, INCX) DBLA 10 C***BEGIN PROLOGUE DNRM2 C***REVISION 3/1/80 C***CATEGORY NO. C***KEYWORD(S) C***AUTHOR--DATE WRITTEN 10/79,LAWSON C. (JPL),HANSON R. (SLA), C KINCAID D. (U TEXAS), KROGH F. (JPL) C***PURPOSE C EUCLIDEAN LENGTH (L2 NORM) OF D.P. VECTOR C***DESCRIPTION C B L A S SUBPROGRAM C DESCRIPTION OF PARAMETERS C C --INPUT-- C N NUMBER OF ELEMENTS IN INPUT VECTOR(S) C DX DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCX STORAGE SPACING BETWEEN ELEMENTS OF DX C C --OUTPUT-- C DNRM2 DOUBLE PRECISION RESULT (ZERO IF N.LE.0) C C EUCLIDEAN NORM OF THE N-VECTOR STORED IN DX() WITH STORAGE C INCREMENT INCX . C IF N .LE. 0 RETURN WITH RESULT = 0. C IF N .GE. 1 THEN INCX MUST BE .GE. 1 C C C.L.LAWSON, 1978 JAN 08 C C FOUR PHASE METHOD USING TWO BUILT-IN CONSTANTS THAT ARE C HOPEFULLY APPLICABLE TO ALL MACHINES. C CUTLO = MAXIMUM OF DSQRT(U/EPS) OVER ALL KNOWN MACHINES. C CUTHI = MINIMUM OF DSQRT(V) OVER ALL KNOWN MACHINES. C WHERE C EPS = SMALLEST NO. SUCH THAT EPS + 1. .GT. 1. C U = SMALLEST POSITIVE NO. (UNDERFLOW LIMIT) C V = LARGEST NO. (OVERFLOW LIMIT) C C BRIEF OUTLINE OF ALGORITHM.. C C PHASE 1 SCANS ZERO COMPONENTS. C MOVE TO PHASE 2 WHEN A COMPONENT IS NONZERO AND .LE. CUTLO C MOVE TO PHASE 3 WHEN A COMPONENT IS .GT. CUTLO C MOVE TO PHASE 4 WHEN A COMPONENT IS .GE. CUTHI/M C WHERE M = N FOR X() REAL AND M = 2*N FOR COMPLEX. C C VALUES FOR CUTLO AND CUTHI.. C FROM THE ENVIRONMENTAL PARAMETERS LISTED IN THE IMSL CONVERTER C DOCUMENT THE LIMITING VALUES ARE AS FOLLOWS.. C CUTLO, S.P. U/EPS = 2**(-102) FOR HONEYWELL. CLOSE SECONDS ARE C UNIVAC AND DEC AT 2**(-103) C THUS CUTLO = 2**(-51) = 4.44089E-16 C CUTHI, S.P. V = 2**127 FOR UNIVAC, HONEYWELL, AND DEC. C THUS CUTHI = 2**(63.5) = 1.30438E19 C CUTLO, D.P. U/EPS = 2**(-67) FOR HONEYWELL AND DEC. C THUS CUTLO = 2**(-33.5) = 8.23181D-11 C CUTHI, D.P. SAME AS S.P. CUTHI = 1.30438D19 C DATA CUTLO, CUTHI / 8.232D-11, 1.304D19 / C DATA CUTLO, CUTHI / 4.441E-16, 1.304E19 / C C***REFERENCE(S) C LAWSON C.L., HANSON R.J., KINCAID D.R., KROGH F.T., C *BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE*, C ALGORITHM NO. 539, TRANSACTIONS ON MATHEMATICAL SOFTWARE, C VOLUME 5, NUMBER 3, SEPTEMBER 1979, 308-323 C***ROUTINES CALLED NONE C***CARD COUNT IS 151 WITH 105 COMMENTS C***END PROLOGUE INTEGER NEXT DOUBLE PRECISION DX(1), CUTLO, CUTHI, HITEST, SUM, XMAX,ZERO,ONE DATA ZERO, ONE /0.0D0, 1.0D0/ C DATA CUTLO, CUTHI / 8.232D-11, 1.304D19 / C***FIRST EXECUTABLE STATEMENT IF(N .GT. 0) GO TO 10 DNRM2 = ZERO GO TO 300 C 10 ASSIGN 30 TO NEXT SUM = ZERO NN = N * INCX C BEGIN MAIN LOOP I = 1 20 GO TO NEXT,(30, 50, 70, 110) 30 IF( DABS(DX(I)) .GT. CUTLO) GO TO 85 ASSIGN 50 TO NEXT XMAX = ZERO C C PHASE 1. SUM IS ZERO C 50 IF( DX(I) .EQ. ZERO) GO TO 200 IF( DABS(DX(I)) .GT. CUTLO) GO TO 85 C C PREPARE FOR PHASE 2. ASSIGN 70 TO NEXT GO TO 105 C C PREPARE FOR PHASE 4. C 100 I = J ASSIGN 110 TO NEXT SUM = (SUM / DX(I)) / DX(I) 105 XMAX = DABS(DX(I)) GO TO 115 C C PHASE 2. SUM IS SMALL. C SCALE TO AVOID DESTRUCTIVE UNDERFLOW. C 70 IF( DABS(DX(I)) .GT. CUTLO ) GO TO 75 C C COMMON CODE FOR PHASES 2 AND 4. C IN PHASE 4 SUM IS LARGE. SCALE TO AVOID OVERFLOW. C 110 IF( DABS(DX(I)) .LE. XMAX ) GO TO 115 SUM = ONE + SUM * (XMAX / DX(I))**2 XMAX = DABS(DX(I)) GO TO 200 C 115 SUM = SUM + (DX(I)/XMAX)**2 GO TO 200 C C C PREPARE FOR PHASE 3. C 75 SUM = (SUM * XMAX) * XMAX C C C FOR REAL OR D.P. SET HITEST = CUTHI/N C FOR COMPLEX SET HITEST = CUTHI/(2*N) C 85 HITEST = CUTHI/FLOAT( N ) C C PHASE 3. SUM IS MID-RANGE. NO SCALING. C DO 95 J =I,NN,INCX IF(DABS(DX(J)) .GE. HITEST) GO TO 100 95 SUM = SUM + DX(J)**2 DNRM2 = DSQRT( SUM ) GO TO 300 C 200 CONTINUE I = I + INCX IF ( I .LE. NN ) GO TO 20 C C TERM. OF MAIN LOOP. C C COMPUTE SQUARE ROOT AND ADJUST FOR SCALING. C DNRM2 = XMAX * DSQRT(SUM) 300 CONTINUE RETURN END DOUBLE PRECISION FUNCTION DASUM(N,DX,INCX) DBLA 10 C***BEGIN PROLOGUE DASUM C***REVISION 3/1/80 C***CATEGORY NO. C***KEYWORD(S) C***AUTHOR--DATE WRITTEN 10/79,LAWSON C. (JPL),HANSON R. (SLA), C KINCAID D. (U TEXAS), KROGH F. (JPL) C***PURPOSE C SUM OF MAGNITUDES OF D.P. VECTOR COMPONENTS C***DESCRIPTION C B L A S SUBPROGRAM C DESCRIPTION OF PARAMETERS C C --INPUT-- C N NUMBER OF ELEMENTS IN INPUT VECTOR(S) C DX DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCX STORAGE SPACING BETWEEN ELEMENTS OF DX C C --OUTPUT-- C DASUM DOUBLE PRECISION RESULT (ZERO IF N.LE.0) C C RETURNS SUM OF MAGNITUDES OF DOUBLE PRECISION DX. C DASUM = SUM FROM 0 TO N-1 OF DABS(DX(1+I*INCX)) C C***REFERENCE(S) C LAWSON C.L., HANSON R.J., KINCAID D.R., KROGH F.T., C *BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE*, C ALGORITHM NO. 539, TRANSACTIONS ON MATHEMATICAL SOFTWARE, C VOLUME 5, NUMBER 3, SEPTEMBER 1979, 308-323 C***ROUTINES CALLED NONE C***CARD COUNT IS 65 WITH 42 COMMENTS C***END PROLOGUE C DOUBLE PRECISION DX(1) C***FIRST EXECUTABLE STATEMENT DASUM = 0.D0 IF(N.LE.0)RETURN IF(INCX.EQ.1)GOTO 20 C C CODE FOR INCREMENTS NOT EQUAL TO 1. C NS = N*INCX DO 10 I=1,NS,INCX DASUM = DASUM + DABS(DX(I)) 10 CONTINUE RETURN C C CODE FOR INCREMENTS EQUAL TO 1. C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 6. C 20 M = MOD(N,6) IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M DASUM = DASUM + DABS(DX(I)) 30 CONTINUE IF( N .LT. 6 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,6 DASUM = DASUM + DABS(DX(I)) + DABS(DX(I+1)) + DABS(DX(I+2)) $ + DABS(DX(I+3)) + DABS(DX(I+4)) + DABS(DX(I+5)) 50 CONTINUE RETURN END SUBROUTINE DSCAL(N,DA,DX,INCX) DBLA 10 C***BEGIN PROLOGUE DSCAL C***REVISION 3/1/80 C***CATEGORY NO. C***KEYWORD(S) C***AUTHOR--DATE WRITTEN 10/79,LAWSON C. (JPL),HANSON R. (SLA), C KINCAID D. (U TEXAS), KROGH F. (JPL) C***PURPOSE C D.P. VECTOR SCALE X = A*X C***DESCRIPTION C B L A S SUBPROGRAM C DESCRIPTION OF PARAMETERS C C --INPUT-- C N NUMBER OF ELEMENTS IN INPUT VECTOR(S) C DA DOUBLE PRECISION SCALE FACTOR C DX DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCX STORAGE SPACING BETWEEN ELEMENTS OF DX C C --OUTPUT-- C DX DOUBLE PRECISION RESULT (UNCHANGED IF N.LE.0) C C REPLACE DOUBLE PRECISION DX BY DOUBLE PRECISION DA*DX. C FOR I = 0 TO N-1, REPLACE DX(1+I*INCX) WITH DA * DX(1+I*INCX) C C***REFERENCE(S) C LAWSON C.L., HANSON R.J., KINCAID D.R., KROGH F.T., C *BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE*, C ALGORITHM NO. 539, TRANSACTIONS ON MATHEMATICAL SOFTWARE, C VOLUME 5, NUMBER 3, SEPTEMBER 1979, 308-323 C***ROUTINES CALLED NONE C***CARD COUNT IS 68 WITH 43 COMMENTS C***END PROLOGUE C DOUBLE PRECISION DA,DX(1) C***FIRST EXECUTABLE STATEMENT IF(N.LE.0)RETURN IF(INCX.EQ.1)GOTO 20 C C CODE FOR INCREMENTS NOT EQUAL TO 1. C NS = N*INCX DO 10 I = 1,NS,INCX DX(I) = DA*DX(I) 10 CONTINUE RETURN C C CODE FOR INCREMENTS EQUAL TO 1. C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 5. C 20 M = MOD(N,5) IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M DX(I) = DA*DX(I) 30 CONTINUE IF( N .LT. 5 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,5 DX(I) = DA*DX(I) DX(I + 1) = DA*DX(I + 1) DX(I + 2) = DA*DX(I + 2) DX(I + 3) = DA*DX(I + 3) DX(I + 4) = DA*DX(I + 4) 50 CONTINUE RETURN END INTEGER FUNCTION IDAMAX(N,DX,INCX) DBLA 10 C***BEGIN PROLOGUE IDAMAX C***REVISION 3/1/80 C***CATEGORY NO. C***KEYWORD(S) C***AUTHOR--DATE WRITTEN 10/79,LAWSON C. (JPL),HANSON R. (SLA), C KINCAID D. (U TEXAS), KROGH F. (JPL) C***PURPOSE C FIND LARGEST COMPONENT OF D.P. VECTOR C***DESCRIPTION C B L A S SUBPROGRAM C DESCRIPTION OF PARAMETERS C C --INPUT-- C N NUMBER OF ELEMENTS IN INPUT VECTOR(S) C DX DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCX STORAGE SPACING BETWEEN ELEMENTS OF DX C C --OUTPUT-- C IDAMAX SMALLEST INDEX (ZERO IF N.LE.0) C C FIND SMALLEST INDEX OF MAXIMUM MAGNITUDE OF DOUBLE PRECISION DX. C IDAMAX = FIRST I, I = 1 TO N, TO MINIMIZE ABS(DX(1-INCX+I*INCX) C C***REFERENCE(S) C LAWSON C.L., HANSON R.J., KINCAID D.R., KROGH F.T., C *BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE*, C ALGORITHM NO. 539, TRANSACTIONS ON MATHEMATICAL SOFTWARE, C VOLUME 5, NUMBER 3, SEPTEMBER 1979, 308-323 C***ROUTINES CALLED NONE C***CARD COUNT IS 66 WITH 39 COMMENTS C***END PROLOGUE C DOUBLE PRECISION DX(1),DMAX,XMAG C***FIRST EXECUTABLE STATEMENT IDAMAX = 0 IF(N.LE.0) RETURN IDAMAX = 1 IF(N.LE.1)RETURN IF(INCX.EQ.1)GOTO 20 C C CODE FOR INCREMENTS NOT EQUAL TO 1. C DMAX = DABS(DX(1)) NS = N*INCX II = 1 DO 10 I = 1,NS,INCX XMAG = DABS(DX(I)) IF(XMAG.LE.DMAX) GO TO 5 IDAMAX = II DMAX = XMAG 5 II = II + 1 10 CONTINUE RETURN C C CODE FOR INCREMENTS EQUAL TO 1. C 20 DMAX = DABS(DX(1)) DO 30 I = 2,N XMAG = DABS(DX(I)) IF(XMAG.LE.DMAX) GO TO 30 IDAMAX = I DMAX = XMAG 30 CONTINUE RETURN END DOUBLE PRECISION FUNCTION DDOT(N,DX,INCX,DY,INCY) DBLA 10 C***BEGIN PROLOGUE DDOT C***REVISION 3/1/80 C***CATEGORY NO. C***KEYWORD(S) C***AUTHOR--DATE WRITTEN 10/79,LAWSON C. (JPL),HANSON R. (SLA), C KINCAID D. (U TEXAS), KROGH F. (JPL) C***PURPOSE C D.P. INNER PRODUCT OF D.P. VECTORS C***DESCRIPTION C B L A S SUBPROGRAM C DESCRIPTION OF PARAMETERS C C --INPUT-- C N NUMBER OF ELEMENTS IN INPUT VECTOR(S) C DX DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCX STORAGE SPACING BETWEEN ELEMENTS OF DX C DY DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCY STORAGE SPACING BETWEEN ELEMENTS OF DY C C --OUTPUT-- C DDOT DOUBLE PRECISION DOT PRODUCT (ZERO IF N.LE.0) C C RETURNS THE DOT PRODUCT OF DOUBLE PRECISION DX AND DY. C DDOT = SUM FOR I = 0 TO N-1 OF DX(LX+I*INCX) * DY(LY+I*INCY) C WHERE LX = 1 IF INCX .GE. 0, ELSE LX = (-INCX)*N, AND LY IS C DEFINED IN A SIMILAR WAY USING INCY. C C***REFERENCE(S) C LAWSON C.L., HANSON R.J., KINCAID D.R., KROGH F.T., C *BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE*, C ALGORITHM NO. 539, TRANSACTIONS ON MATHEMATICAL SOFTWARE, C VOLUME 5, NUMBER 3, SEPTEMBER 1979, 308-323 C***ROUTINES CALLED NONE C***CARD COUNT IS 84 WITH 49 COMMENTS C***END PROLOGUE C DOUBLE PRECISION DX(1),DY(1) C***FIRST EXECUTABLE STATEMENT DDOT = 0.D0 IF(N.LE.0)RETURN IF(INCX.EQ.INCY) IF(INCX-1) 5,20,60 5 CONTINUE C C CODE FOR UNEQUAL OR NONPOSITIVE INCREMENTS. C IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N DDOT = DDOT + DX(IX)*DY(IY) IX = IX + INCX IY = IY + INCY 10 CONTINUE RETURN C C CODE FOR BOTH INCREMENTS EQUAL TO 1. C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 5. C 20 M = MOD(N,5) IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M DDOT = DDOT + DX(I)*DY(I) 30 CONTINUE IF( N .LT. 5 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,5 DDOT = DDOT + DX(I)*DY(I) + DX(I+1)*DY(I+1) + $ DX(I + 2)*DY(I + 2) + DX(I + 3)*DY(I + 3) + DX(I + 4)*DY(I + 4) 50 CONTINUE RETURN C C CODE FOR POSITIVE EQUAL INCREMENTS .NE.1. C 60 CONTINUE NS = N*INCX DO 70 I=1,NS,INCX DDOT = DDOT + DX(I)*DY(I) 70 CONTINUE RETURN END SUBROUTINE DAXPY(N,DA,DX,INCX,DY,INCY) DBLA 10 C***BEGIN PROLOGUE DAXPY C***REVISION 3/1/80 C***CATEGORY NO. C***KEYWORD(S) C***AUTHOR--DATE WRITTEN 10/79,LAWSON C. (JPL),HANSON R. (SLA), C KINCAID D. (U TEXAS), KROGH F. (JPL) C***PURPOSE C D.P COMPUTATION Y = A*X + Y C***DESCRIPTION C B L A S SUBPROGRAM C DESCRIPTION OF PARAMETERS C C --INPUT-- C N NUMBER OF ELEMENTS IN INPUT VECTOR(S) C DA DOUBLE PRECISION SCALAR MULTIPLIER C DX DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCX STORAGE SPACING BETWEEN ELEMENTS OF DX C DY DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCY STORAGE SPACING BETWEEN ELEMENTS OF DY C C --OUTPUT-- C DY DOUBLE PRECISION RESULT (UNCHANGED IF N.LE.0) C C OVERWRITE DOUBLE PRECISION DY WITH DOUBLE PRECISION DA*DX + DY. C FOR I = 0 TO N-1, REPLACE DY(LY+I*INCY) WITH DA*DX(LX+I*INCX) + C DY(LY+I*INCY), WHERE LX = 1 IF INCX .GE. 0, ELSE LX = (-INCX)*N C AND LY IS DEFINED IN A SIMILAR WAY USING INCY. C C***REFERENCE(S) C LAWSON C.L., HANSON R.J., KINCAID D.R., KROGH F.T., C *BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE*, C ALGORITHM NO. 539, TRANSACTIONS ON MATHEMATICAL SOFTWARE, C VOLUME 5, NUMBER 3, SEPTEMBER 1979, 308-323 C***ROUTINES CALLED NONE C***CARD COUNT IS 86 WITH 50 COMMENTS C***END PROLOGUE C DOUBLE PRECISION DX(1),DY(1),DA C***FIRST EXECUTABLE STATEMENT IF(N.LE.0.OR.DA.EQ.0.D0) RETURN IF(INCX.EQ.INCY) IF(INCX-1) 5,20,60 5 CONTINUE C C CODE FOR NONEQUAL OR NONPOSITIVE INCREMENTS. C IX = 1 IY = 1 IF(INCX.LT.0)IX = (-N+1)*INCX + 1 IF(INCY.LT.0)IY = (-N+1)*INCY + 1 DO 10 I = 1,N DY(IY) = DY(IY) + DA*DX(IX) IX = IX + INCX IY = IY + INCY 10 CONTINUE RETURN C C CODE FOR BOTH INCREMENTS EQUAL TO 1 C C C CLEAN-UP LOOP SO REMAINING VECTOR LENGTH IS A MULTIPLE OF 4. C 20 M = MOD(N,4) IF( M .EQ. 0 ) GO TO 40 DO 30 I = 1,M DY(I) = DY(I) + DA*DX(I) 30 CONTINUE IF( N .LT. 4 ) RETURN 40 MP1 = M + 1 DO 50 I = MP1,N,4 DY(I) = DY(I) + DA*DX(I) DY(I + 1) = DY(I + 1) + DA*DX(I + 1) DY(I + 2) = DY(I + 2) + DA*DX(I + 2) DY(I + 3) = DY(I + 3) + DA*DX(I + 3) 50 CONTINUE RETURN C C CODE FOR EQUAL, POSITIVE, NONUNIT INCREMENTS. C 60 CONTINUE NS = N*INCX DO 70 I=1,NS,INCX DY(I) = DA*DX(I) + DY(I) 70 CONTINUE RETURN END SUBROUTINE DROTM (N,DX,INCX,DY,INCY,DPARAM) DBLA 10 C***BEGIN PROLOGUE DROTM C***REVISION 3/1/80 C***CATEGORY NO. C***KEYWORD(S) C***AUTHOR--DATE WRITTEN 10/79, LAWSON C. (JPL), HANSON R. (SLA), C KINCAID D. (U TEXAS), KROGH F. (JPL) C***PURPOSE C APPLY D.P. MODIFIED GIVENS TRANSFORMATION C***DESCRIPTION C B L A S SUBPROGRAM C DESCRIPTION OF PARAMETERS C C --INPUT-- C N NUMBER OF ELEMENTS IN INPUT VECTOR(S) C DX DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCX STORAGE SPACING BETWEEN ELEMENTS OF DX C DY DOUBLE PRECISION VECTOR WITH N ELEMENTS C INCY STORAGE SPACING BETWEEN ELEMENTS OF DY C DPARAM 5-ELEMENT D.P. VECTOR. DPARAM(1) IS DFLAG DESCRIBED BELOW C ELEMENTS 2-5 FORM THE TRANSFORMATION MATRIX H. C C --OUTPUT-- C DX ROTATED VECTOR (UNCHANGED IF N.LE.0) C DY ROTATED VECTOR (UNCHANGED IF N.LE.0) C C APPLY THE MODIFIED GIVENS TRANSFORMATION, H, TO THE 2 BY N MATRIX C C (DX**T) , WHERE **T INDICATES TRANSPOSE. THE ELEMENTS OF DX ARE IN C (DY**T) C C DX(LX+I*INCX), I = 0 TO N-1, WHERE LX = 1 IF INCX .GE. 0, ELSE C LX = (-INCX)*N, AND SIMILARLY FOR SY USING LY AND INCY. C WITH DPARAM(1)=DFLAG, H HAS ONE OF THE FOLLOWING FORMS.. C C DFLAG=-1.D0 DFLAG=0.D0 DFLAG=1.D0 DFLAG=-2.D0 C C (DH11 DH12) (1.D0 DH12) (DH11 1.D0) (1.D0 0.D0) C H=( ) ( ) ( ) ( ) C (DH21 DH22), (DH21 1.D0), (-1.D0 DH22), (0.D0 1.D0). C SEE DROTMG FOR A DESCRIPTION OF DATA STORAGE IN DPARAM. C C C***REFERENCE(S) C LAWSON C.L., HANSON R.J., KINCAID D.R., KROGH F.T., C *BASIC LINEAR ALGEBRA SUBPROGRAMS FOR FORTRAN USAGE*, C ALGORITHM NO. 539, TRANSACTIONS ON MATHEMATICAL SOFTWARE, C VOLUME 5, NUMBER 3, SEPTEMBER 1979, 308-323 C***ROUTINES CALLED NONE C***CARD COUNT IS 142 WITH 54 COMMENTS C***END PROLOGUE C DOUBLE PRECISION DFLAG,DH12,DH22,DX,TWO,Z,DH11,DH21, 1 DPARAM,DY,W,ZERO DIMENSION DX(1),DY(1),DPARAM(5) DATA ZERO,TWO/0.D0,2.D0/ C***FIRST EXECUTABLE STATEMENT DFLAG=DPARAM(1) IF(N .LE. 0 .OR.(DFLAG+TWO.EQ.ZERO)) GO TO 140 IF(.NOT.(INCX.EQ.INCY.AND. INCX .GT.0)) GO TO 70 C NSTEPS=N*INCX IF(DFLAG) 50,10,30 10 CONTINUE DH12=DPARAM(4) DH21=DPARAM(3) DO 20 I=1,NSTEPS,INCX W=DX(I) Z=DY(I) DX(I)=W+Z*DH12 DY(I)=W*DH21+Z 20 CONTINUE GO TO 140 30 CONTINUE DH11=DPARAM(2) DH22=DPARAM(5) DO 40 I=1,NSTEPS,INCX W=DX(I) Z=DY(I) DX(I)=W*DH11+Z DY(I)=-W+DH22*Z 40 CONTINUE GO TO 140 50 CONTINUE DH11=DPARAM(2) DH12=DPARAM(4) DH21=DPARAM(3) DH22=DPARAM(5) DO 60 I=1,NSTEPS,INCX W=DX(I) Z=DY(I) DX(I)=W*DH11+Z*DH12 DY(I)=W*DH21+Z*DH22 60 CONTINUE GO TO 140 70 CONTINUE KX=1 KY=1 IF(INCX .LT. 0) KX=1+(1-N)*INCX IF(INCY .LT. 0) KY=1+(1-N)*INCY C IF(DFLAG)120,80,100 80 CONTINUE DH12=DPARAM(4) DH21=DPARAM(3) DO 90 I=1,N W=DX(KX) Z=DY(KY) DX(KX)=W+Z*DH12 DY(KY)=W*DH21+Z KX=KX+INCX KY=KY+INCY 90 CONTINUE GO TO 140 100 CONTINUE DH11=DPARAM(2) DH22=DPARAM(5) DO 110 I=1,N W=DX(KX) Z=DY(KY) DX(KX)=W*DH11+Z DY(KY)=-W+DH22*Z KX=KX+INCX KY=KY+INCY 110 CONTINUE GO TO 140 120 CONTINUE DH11=DPARAM(2) DH12=DPARAM(4) DH21=DPARAM(3) DH22=DPARAM(5) DO 130 I=1,N W=DX(KX) Z=DY(KY) DX(KX)=W*DH11+Z*DH12 DY(KY)=W*DH21+Z*DH22 KX=KX+INCX KY=KY+INCY 130 CONTINUE 140 CONTINUE RETURN END SUBROUTINE FDUMP XER 10 C ABSTRACT C ***NOTE*** MACHINE DEPENDENT ROUTINE C FDUMP IS INTENDED TO BE REPLACED BY A LOCALLY WRITTEN C VERSION WHICH PRODUCES A SYMBOLIC DUMP. FAILING THIS, C IT SHOULD BE REPLACED BY A VERSION WHICH PRINTS THE C SUBPROGRAM NESTING LIST. NOTE THAT THIS DUMP MUST BE C PRINTED ON EACH OF UP TO FIVE FILES, AS INDICATED BY THE C XGETUA ROUTINE. SEE XSETUA AND XGETUA FOR DETAILS. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 23 MAY 1979 C RETURN END SUBROUTINE XERABT(MESSG,NMESSG) XER 10 C C ABSTRACT C ***NOTE*** MACHINE DEPENDENT ROUTINE C XERABT ABORTS THE EXECUTION OF THE PROGRAM. C THE ERROR MESSAGE CAUSING THE ABORT IS GIVEN IN THE CALLING C SEQUENCE IN CASE ONE NEEDS IT FOR PRINTING ON A DAYFILE, C FOR EXAMPLE. C C DESCRIPTION OF PARAMETERS C MESSG AND NMESSG ARE AS IN XERROR, EXCEPT THAT NMESSG MAY C BE ZERO, IN WHICH CASE NO MESSAGE IS BEING SUPPLIED. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 7 JUNE 1978 C DIMENSION MESSG(NMESSG) IF (.TRUE.) STOP RETURN END FUNCTION J4SAVE(IWHICH,IVALUE,ISET) XER 10 C C ABSTRACT C J4SAVE SAVES AND RECALLS SEVERAL GLOBAL VARIABLES NEEDED C BY THE LIBRARY ERROR HANDLING ROUTINES. C C DESCRIPTION OF PARAMETERS C --INPUT-- C IWHICH - INDEX OF ITEM DESIRED. C = 1 REFERS TO CURRENT ERROR NUMBER. C = 2 REFERS TO CURRENT ERROR CONTROL FLAG. C = 3 REFERS TO CURRENT UNIT NUMBER TO WHICH ERROR C MESSAGES ARE TO BE SENT. (0 MEANS USE STANDARD.) C = 4 REFERS TO THE MAXIMUM NUMBER OF TIMES ANY C MESSAGE IS TO BE PRINTED (AS SET BY XERMAX). C = 5 REFERS TO THE TOTAL NUMBER OF UNITS TO WHICH C EACH ERROR MESSAGE IS TO BE WRITTEN. C = 6 REFERS TO THE 2ND UNIT FOR ERROR MESSAGES C = 7 REFERS TO THE 3RD UNIT FOR ERROR MESSAGES C = 8 REFERS TO THE 4TH UNIT FOR ERROR MESSAGES C = 9 REFERS TO THE 5TH UNIT FOR ERROR MESSAGES C IVALUE - THE VALUE TO BE SET FOR THE IWHICH-TH PARAMETER, C IF ISET IS .TRUE. . C ISET - IF ISET=.TRUE., THE IWHICH-TH PARAMETER WILL BE C GIVEN THE VALUE, IVALUE. IF ISET=.FALSE., THE C IWHICH-TH PARAMETER WILL BE UNCHANGED, AND IVALUE C IS A DUMMY PARAMETER. C --OUTPUT-- C THE (OLD) VALUE OF THE IWHICH-TH PARAMETER WILL BE RETURNED C IN THE FUNCTION VALUE, J4SAVE. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C ADAPTED FROM BELL LABORATORIES PORT LIBRARY ERROR HANDLER C END OF ABSTRACT C LATEST REVISION --- 23 MAY 1979 C LOGICAL ISET INTEGER IPARAM(9) DATA IPARAM(1),IPARAM(2),IPARAM(3),IPARAM(4)/0,2,0,10/ DATA IPARAM(5)/1/ DATA IPARAM(6),IPARAM(7),IPARAM(8),IPARAM(9)/0,0,0,0/ J4SAVE = IPARAM(IWHICH) IF (ISET) IPARAM(IWHICH) = IVALUE RETURN END FUNCTION NUMXER(NERR) XER 10 C C ABSTRACT C NUMXER RETURNS THE MOST RECENT ERROR NUMBER, C IN BOTH NUMXER AND THE PARAMETER NERR. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 7 JUNE 1978 C NERR = J4SAVE(1,0,.FALSE.) NUMXER = NERR RETURN END SUBROUTINE S88FMT(N,IVALUE,IFMT) XER 10 C C ABSTRACT C S88FMT REPLACES IFMT(1), ... ,IFMT(N) WITH THE C CHARACTERS CORRESPONDING TO THE N LEAST SIGNIFICANT C DIGITS OF IVALUE. C C TAKEN FROM THE BELL LABORATORIES PORT LIBRARY ERROR HANDLER C END OF ABSTRACT C LATEST REVISION --- 7 JUNE 1978 C DIMENSION IFMT(N),IDIGIT(10) DATA IDIGIT(1),IDIGIT(2),IDIGIT(3),IDIGIT(4),IDIGIT(5), 1 IDIGIT(6),IDIGIT(7),IDIGIT(8),IDIGIT(9),IDIGIT(10) 2 /1H0,1H1,1H2,1H3,1H4,1H5,1H6,1H7,1H8,1H9/ NT = N IT = IVALUE 10 IF (NT .EQ. 0) RETURN INDEX = MOD(IT,10) IFMT(NT) = IDIGIT(INDEX+1) IT = IT/10 NT = NT - 1 GO TO 10 END SUBROUTINE XERCLR XER 10 C C ABSTRACT C THIS ROUTINE SIMPLY RESETS THE CURRENT ERROR NUMBER TO ZERO. C THIS MAY BE NECESSARY TO DO IN ORDER TO DETERMINE THAT C A CERTAIN ERROR HAS OCCURRED AGAIN SINCE THE LAST TIME C NUMXER WAS REFERENCED. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 7 JUNE 1978 C JUNK = J4SAVE(1,0,.TRUE.) RETURN END SUBROUTINE XERCTL(MESSG1,NMESSG,NERR,LEVEL,KONTRL) XER 10 C C ABSTRACT C ALLOWS USER CONTROL OVER HANDLING OF INDIVIDUAL ERRORS. C JUST AFTER EACH MESSAGE IS RECORDED, BUT BEFORE IT IS C PROCESSED ANY FURTHER (I.E., BEFORE IT IS PRINTED OR C A DECISION TO ABORT IS MADE) A CALL IS MADE TO XERCTL. C IF THE USER HAS PROVIDED HIS OWN VERSION OF XERCTL, HE C CAN THEN OVERRIDE THE VALUE OF KONTROL USED IN PROCESSING C THIS MESSAGE BY REDEFINING ITS VALUE. C KONTRL MAY BE SET TO ANY VALUE FROM -2 TO 2. C THE MEANINGS FOR KONTRL ARE THE SAME AS IN XSETF, EXCEPT C THAT THE VALUE OF KONTRL CHANGES ONLY FOR THIS MESSAGE. C IF KONTRL IS SET TO A VALUE OUTSIDE THE RANGE FROM -2 TO 2, C IT WILL BE MOVED BACK INTO THAT RANGE. C C DESCRIPTION OF PARAMETERS C C --INPUT-- C MESSG1 - THE FIRST WORD (ONLY) OF THE ERROR MESSAGE. C NMESSG - SAME AS IN THE CALL TO XERROR OR XERRWV. C NERR - SAME AS IN THE CALL TO XERROR OR XERRWV. C LEVEL - SAME AS IN THE CALL TO XERROR OR XERRWV. C KONTRL - THE CURRENT VALUE OF THE CONTROL FLAG AS SET C BY A CALL TO XSETF. C C --OUTPUT-- C KONTRL - THE NEW VALUE OF KONTRL. IF KONTRL IS NOT C DEFINED, IT WILL REMAIN AT ITS ORIGINAL VALUE. C THIS CHANGED VALUE OF CONTROL AFFECTS ONLY C THE CURRENT OCCURRENCE OF THE CURRENT MESSAGE. C END OF ABSTRACT C RETURN END SUBROUTINE XERDMP XER 10 C C ABSTRACT C XERDMP PRINTS AN ERROR TABLE SHOWING ALL ERRORS WHICH C HAVE OCCURRED DURING THE CURRENT EXECUTION, OR SINCE XERDMP C WAS LAST CALLED. AFTER PRINTING, THE ERROR TABLE IS CLEARED, C AND IF PROGRAM EXECUTION IS CONTINUED ACCUMULATION OF THE C ERROR TABLE BEGINS AT ZERO. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 7 JUNE 1978 C CALL XERSAV(1H ,0,0,0,KOUNT) RETURN END SUBROUTINE XERMAX(MAX) XER 10 C C ABSTRACT C XERMAX SETS THE MAXIMUM NUMBER OF TIMES ANY MESSAGE C IS TO BE PRINTED. THAT IS, NON-FATAL MESSAGES ARE C NOT TO BE PRINTED AFTER THEY HAVE OCCURED MAX TIMES. C SUCH NON-FATAL MESSAGES MAY BE PRINTED LESS THAN C MAX TIMES EVEN IF THEY OCCUR MAX TIMES, IF ERROR C SUPPRESSION MODE (KONTRL=0) IS EVER IN EFFECT. C C THE DEFAULT VALUE FOR MAX IS 10. C C DESCRIPTION OF PARAMETER C --INPUT-- C MAX - THE MAXIMUM NUMBER OF TIMES ANY ONE MESSAGE C IS TO BE PRINTED. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 7 JUNE 1978 C JUNK = J4SAVE(4,MAX,.TRUE.) RETURN END SUBROUTINE XERPRT(MESSG,NMESSG) XER 10 C C ABSTRACT C PRINT THE HOLLERITH MESSAGE IN MESSG, OF LENGTH MESSG, C ON EACH FILE INDICATED BY XGETUA. C THIS VERSION PRINTS EXACTLY THE RIGHT NUMBER OF CHARACTERS, C NOT A NUMBER OF WORDS, AND THUS SHOULD WORK ON MACHINES C WHICH DO NOT BLANK FILL THE LAST WORD OF THE HOLLERITH. C C RON JONES, JUNE 1980 C END OF ABSTRACT C INTEGER F(10),G(14),LUN(5) DIMENSION MESSG(NMESSG) DATA F(1),F(2),F(3),F(4),F(5),F(6),F(7),F(8),F(9),F(10) 1 / 1H( ,1H1 ,1HX ,1H, ,1H ,1H ,1HA ,1H ,1H ,1H) / DATA G(1),G(2),G(3),G(4),G(5),G(6),G(7),G(8),G(9),G(10) 1 / 1H( ,1H1 ,1HX ,1H ,1H ,1H ,1H ,1H ,1H ,1H / DATA G(11),G(12),G(13),G(14) 1 / 1H ,1H ,1H ,1H) / DATA LA/1HA/,LCOM/1H,/,LBLANK/1H / C PREPARE FORMAT FOR WHOLE LINES NCHAR = I1MACH(6) NFIELD = 72/NCHAR CALL S88FMT(2,NFIELD,F(5)) CALL S88FMT(2,NCHAR,F(8)) C PREPARE FORMAT FOR LAST, PARTIAL LINE, IF NEEDED NCHARL = NFIELD*NCHAR NLINES = NMESSG/NCHARL NWORD = NLINES*NFIELD NCHREM = NMESSG - NLINES*NCHARL IF (NCHREM.LE.0) GO TO 40 DO 10 I=4,13 10 G(I) = LBLANK NFIELD = NCHREM/NCHAR IF (NFIELD.LE.0) GO TO 20 C PREPARE WHOLE WORD FIELDS G(4) = LCOM CALL S88FMT(2,NFIELD,G(5)) G(7) = LA CALL S88FMT(2,NCHAR,G(8)) 20 CONTINUE NCHLST = MOD(NCHREM,NCHAR) IF (NCHLST.LE.0) GO TO 30 C PREPARE PARTIAL WORD FIELD G(10) = LCOM G(11) = LA CALL S88FMT(2,NCHLST,G(12)) 30 CONTINUE 40 CONTINUE C PRINT THE MESSAGE NWORD1 = NWORD+1 NWORD2 = (NMESSG+NCHAR-1)/NCHAR CALL XGETUA(LUN,NUNIT) DO 50 KUNIT = 1,NUNIT IUNIT = LUN(KUNIT) IF (IUNIT.EQ.0) IUNIT = I1MACH(4) IF (NWORD.GT.0) WRITE (IUNIT,F) (MESSG(I),I=1,NWORD) IF (NCHREM.GT.0) WRITE (IUNIT,G) (MESSG(I),I=NWORD1,NWORD2) 50 CONTINUE RETURN END SUBROUTINE XERROR(MESSG,NMESSG,NERR,LEVEL) XER 10 C C ABSTRACT C XERROR PROCESSES A DIAGNOSTIC MESSAGE, IN A MANNER C DETERMINED BY THE VALUE OF LEVEL AND THE CURRENT VALUE C OF THE LIBRARY ERROR CONTROL FLAG, KONTRL. C (SEE SUBROUTINE XSETF FOR DETAILS.) C C DESCRIPTION OF PARAMETERS C --INPUT-- C MESSG - THE HOLLERITH MESSAGE TO BE PROCESSED, CONTAINING C NO MORE THAN 72 CHARACTERS. C NMESSG- THE ACTUAL NUMBER OF CHARACTERS IN MESSG. C NERR - THE ERROR NUMBER ASSOCIATED WITH THIS MESSAGE. C NERR MUST NOT BE ZERO. C LEVEL - ERROR CATEGORY. C =2 MEANS THIS IS AN UNCONDITIONALLY FATAL ERROR. C =1 MEANS THIS IS A RECOVERABLE ERROR. (I.E., IT IS C NON-FATAL IF XSETF HAS BEEN APPROPRIATELY CALLED.) C =0 MEANS THIS IS A WARNING MESSAGE ONLY. C =-1 MEANS THIS IS A WARNING MESSAGE WHICH IS TO BE C PRINTED AT MOST ONCE, REGARDLESS OF HOW MANY C TIMES THIS CALL IS EXECUTED. C C EXAMPLES C CALL XERROR(23HSMOOTH -- NUM WAS ZERO.,23,1,2) C CALL XERROR(43HINTEG -- LESS THAN FULL ACCURACY ACHIEVED., C 43,2,1) C CALL XERROR(65HROOTER -- ACTUAL ZERO OF F FOUND BEFORE INTERVAL C 1 FULLY COLLAPSED.,65,3,0) C CALL XERROR(39HEXP -- UNDERFLOWS BEING SET TO ZERO.,39,1,-1) C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C REVISED BY K HASKELL TO CHECK INPUT ARGS, 2/18/80 C DIMENSION MESSG(NMESSG) C CHECK FOR VALID INPUT LKNTRL = J4SAVE (2,0,.FALSE.) IF (NMESSG.GT.0) GO TO 10 IF (LKNTRL.GT.0) CALL XERPRT(17HFATAL ERROR IN...,17) CALL XERPRT (33HXERROR -- NMESSG MUST BE POSITIVE,33) IF (LKNTRL.GT.0) CALL FDUMP IF (LKNTRL.GT.0) CALL XERPRT(29HJOB ABORT DUE TO FATAL ERROR., 1 29) IF (LKNTRL.GT.0) CALL XERSAV (1H ,0,0,0,KDUMMY) CALL XERABT (23HXERROR -- INVALID INPUT,23) RETURN 10 CONTINUE IF (NERR.NE.0) GO TO 15 IF (LKNTRL.GT.0) CALL XERPRT(17HFATAL ERROR IN...,17) CALL XERPRT (28HXERROR -- NERR=0 IS AN ERROR,28) IF (LKNTRL.GT.0) CALL FDUMP IF (LKNTRL.GT.0) CALL XERPRT(29HJOB ABORT DUE TO FATAL ERROR., 1 29) IF (LKNTRL.GT.0) CALL XERSAV (1H ,0,0,0,KDUMMY) CALL XERABT (23HXERROR -- INVALID INPUT,23) RETURN 15 CONTINUE IF ((LEVEL.GE.(-1)).AND.(LEVEL.LE.2)) GO TO 20 IF (LKNTRL.GT.0) CALL XERPRT(17HFATAL ERROR IN...,17) CALL XERPRT (32HXERROR -- INVALID VALUE OF LEVEL,32) IF (LKNTRL.GT.0) CALL FDUMP IF (LKNTRL.GT.0) CALL XERPRT(29HJOB ABORT DUE TO FATAL ERROR., 1 29) IF (LKNTRL.GT.0) CALL XERSAV (1H ,0,0,0,KDUMMY) CALL XERABT (23HXERROR -- INVALID INPUT,23) RETURN 20 CONTINUE CALL XERRWV(MESSG,NMESSG,NERR,LEVEL,0,0,0,0,0.,0.) RETURN END SUBROUTINE XERRWV(MESSG,NMESSG,NERR,LEVEL,NI,I1,I2,NR,R1,R2) XER 10 C C ABSTRACT C XERRWV PROCESSES A DIAGNOSTIC MESSAGE, IN A MANNER C DETERMINED BY THE VALUE OF LEVEL AND THE CURRENT VALUE C OF THE LIBRARY ERROR CONTROL FLAG, KONTRL. C (SEE SUBROUTINE XSETF FOR DETAILS.) C IN ADDITION, UP TO TWO INTEGER VALUES AND TWO REAL C VALUES MAY BE PRINTED ALONG WITH THE MESSAGE. C C DESCRIPTION OF PARAMETERS C --INPUT-- C MESSG - THE HOLLERITH MESSAGE TO BE PROCESSED. C NMESSG- THE ACTUAL NUMBER OF CHARACTERS IN MESSG. C NERR - THE ERROR NUMBER ASSOCIATED WITH THIS MESSAGE. C NERR MUST NOT BE ZERO. C LEVEL - ERROR CATEGORY. C =2 MEANS THIS IS AN UNCONDITIONALLY FATAL ERROR. C =1 MEANS THIS IS A RECOVERABLE ERROR. (I.E., IT IS C NON-FATAL IF XSETF HAS BEEN APPROPRIATELY CALLED.) C =0 MEANS THIS IS A WARNING MESSAGE ONLY. C =-1 MEANS THIS IS A WARNING MESSAGE WHICH IS TO BE C PRINTED AT MOST ONCE, REGARDLESS OF HOW MANY C TIMES THIS CALL IS EXECUTED. C NI - NUMBER OF INTEGER VALUES TO BE PRINTED. (O TO 2) C I1 - FIRST INTEGER VALUE. C I2 - SECOND INTEGER VALUE. C NR - NUMBER OF REAL VALUES TO BE PRINTED. (0 TO 2) C R1 - FIRST REAL VALUE. C R2 - SECOND REAL VALUE. C C EXAMPLES C CALL XERRWV(29HSMOOTH -- NUM (=I1) WAS ZERO.,29,1,2, C 1 1,NUM,0,0,0.,0.) C CALL XERRWV(54HQUADXY -- REQUESTED ERROR (R1) LESS THAN MINIMUM C 1 (R2).,54,77,1,0,0,0,2,ERRREQ,ERRMIN) C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 19 MAR 1980 C REVISED BY K HASKELL TO CHECK INPUT ARGS, 2/18/80 C DIMENSION MESSG(NMESSG),LUN(5) C GET FLAGS LKNTRL = J4SAVE(2,0,.FALSE.) MAXMES = J4SAVE(4,0,.FALSE.) C CHECK FOR VALID INPUT IF (NMESSG.GT.0) GO TO 2 IF (LKNTRL.GT.0) CALL XERPRT(17HFATAL ERROR IN...,17) CALL XERPRT (33HXERRWV -- NMESSG MUST BE POSITIVE,33) IF (LKNTRL.GT.0) CALL FDUMP IF (LKNTRL.GT.0) CALL XERPRT(29HJOB ABORT DUE TO FATAL ERROR., 1 29) IF (LKNTRL.GT.0) CALL XERSAV(1H ,0,0,0,KDUMMY) CALL XERABT (23HXERRWV -- INVALID INPUT,23) RETURN 2 CONTINUE IF (NERR.NE.0) GO TO 4 IF (LKNTRL.GT.0) CALL XERPRT(17HFATAL ERROR IN...,17) CALL XERPRT (28HXERRWV -- NERR=0 IS AN ERROR,28) IF (LKNTRL.GT.0) CALL FDUMP IF (LKNTRL.GT.0) CALL XERPRT(29HJOB ABORT DUE TO FATAL ERROR., 1 29) IF (LKNTRL.GT.0) CALL XERSAV(1H ,0,0,0,KDUMMY) CALL XERABT (23HXERRWV -- INVALID INPUT,23) RETURN 4 CONTINUE IF ((LEVEL.GE.(-1)).AND.(LEVEL.LE.2)) GO TO 10 IF (LKNTRL.GT.0) CALL XERPRT(17HFATAL ERROR IN...,17) CALL XERPRT (32HXERRWV -- INVALID VALUE OF LEVEL,32) IF (LKNTRL.GT.0) CALL FDUMP IF (LKNTRL.GT.0) CALL XERPRT(29HJOB ABORT DUE TO FATAL ERROR., 1 29) IF (LKNTRL.GT.0) CALL XERSAV(1H ,0,0,0,KDUMMY) CALL XERABT(23HXERROR -- INVALID INPUT,23) RETURN 10 CONTINUE C RECORD MESSAGE JUNK = J4SAVE(1,NERR,.TRUE.) CALL XERSAV(MESSG,NMESSG,NERR,LEVEL,KOUNT) C LET USER OVERRIDE LFIRST = MESSG(1) LMESSG = NMESSG LERR = NERR LLEVEL = LEVEL CALL XERCTL(LFIRST,LMESSG,LERR,LLEVEL,LKNTRL) C RESET TO ORIGINAL VALUES LMESSG = NMESSG LERR = NERR LLEVEL = LEVEL LKNTRL = MAX0(-2,MIN0(2,LKNTRL)) MKNTRL = IABS(LKNTRL) C DECIDE WHETHER TO PRINT MESSAGE IF ((LLEVEL.LT.2).AND.(LKNTRL.EQ.0)) GO TO 100 IF (((LLEVEL.EQ.(-1)).AND.(KOUNT.GT.MIN0(1,MAXMES))) 1.OR.((LLEVEL.EQ.0) .AND.(KOUNT.GT.MAXMES)) 2.OR.((LLEVEL.EQ.1) .AND.(KOUNT.GT.MAXMES).AND.(MKNTRL.EQ.1)) 3.OR.((LLEVEL.EQ.2) .AND.(KOUNT.GT.MAX0(1,MAXMES)))) GO TO 100 IF (LKNTRL.LE.0) GO TO 20 CALL XERPRT(1H ,1) C INTRODUCTION IF (LLEVEL.EQ.(-1)) CALL XERPRT 1(57HWARNING MESSAGE...THIS MESSAGE WILL ONLY BE PRINTED ONCE.,57) IF (LLEVEL.EQ.0) CALL XERPRT(13HWARNING IN...,13) IF (LLEVEL.EQ.1) CALL XERPRT 1 (23HRECOVERABLE ERROR IN...,23) IF (LLEVEL.EQ.2) CALL XERPRT(17HFATAL ERROR IN...,17) 20 CONTINUE C MESSAGE CALL XERPRT(MESSG,LMESSG) CALL XGETUA(LUN,NUNIT) DO 50 KUNIT=1,NUNIT IUNIT = LUN(KUNIT) IF (IUNIT.EQ.0) IUNIT = I1MACH(4) IF (NI.GE.1) WRITE (IUNIT,22) I1 IF (NI.GE.2) WRITE (IUNIT,23) I2 IF (NR.GE.1) WRITE (IUNIT,24) R1 IF (NR.GE.2) WRITE (IUNIT,25) R2 22 FORMAT (11X,21HIN ABOVE MESSAGE, I1=,I10) 23 FORMAT (11X,21HIN ABOVE MESSAGE, I2=,I10) 24 FORMAT (11X,21HIN ABOVE MESSAGE, R1=,E20.10) 25 FORMAT (11X,21HIN ABOVE MESSAGE, R2=,E20.10) IF (LKNTRL.LE.0) GO TO 40 C ERROR NUMBER WRITE (IUNIT,30) LERR 30 FORMAT (15H ERROR NUMBER =,I10) 40 CONTINUE 50 CONTINUE C TRACE-BACK CALL FDUMP 100 CONTINUE IFATAL = 0 IF ((LLEVEL.EQ.2).OR.((LLEVEL.EQ.1).AND.(MKNTRL.EQ.2))) 1IFATAL = 1 C QUIT HERE IF MESSAGE IS NOT FATAL IF (IFATAL.LE.0) RETURN IF (LKNTRL.LE.0) GO TO 120 C PRINT REASON FOR ABORT IF (LLEVEL.EQ.1) CALL XERPRT 1 (35HJOB ABORT DUE TO UNRECOVERED ERROR.,35) IF (LLEVEL.EQ.2) CALL XERPRT 1 (29HJOB ABORT DUE TO FATAL ERROR.,29) C PRINT ERROR SUMMARY CALL XERSAV(1H ,0,0,0,KDUMMY) 120 CONTINUE C ABORT IF ((LLEVEL.EQ.2).AND.(KOUNT.GT.MAX0(1,MAXMES))) LMESSG = 0 CALL XERABT(MESSG,LMESSG) RETURN END SUBROUTINE XERSAV(MESSG,NMESSG,NERR,LEVEL,ICOUNT) XER 10 C C ABSTRACT C RECORD THAT THIS ERROR OCCURRED. C C DESCRIPTION OF PARAMETERS C --INPUT-- C MESSG, NMESSG, NERR, LEVEL ARE AS IN XERROR, C EXCEPT THAT WHEN NMESSG=0 THE TABLES WILL BE C DUMPED AND CLEARED, AND WHEN NMESSG IS LESS THAN ZERO THE C TABLES WILL BE DUMPED AND NOT CLEARED. C --OUTPUT-- C ICOUNT WILL BE THE NUMBER OF TIMES THIS MESSAGE HAS C BEEN SEEN, OR ZERO IF THE TABLE HAS OVERFLOWED AND C DOES NOT CONTAIN THIS MESSAGE SPECIFICALLY. C WHEN NMESSG=0, ICOUNT WILL NOT BE ALTERED. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C INTEGER F(17),LUN(5) DIMENSION MESSG(1) DIMENSION MESTAB(10),NERTAB(10),LEVTAB(10),KOUNT(10) C NEXT THREE DATA STATEMENTS ARE NEEDED MERELY TO SATISFY C CERTAIN CONVENTIONS FOR COMPILERS WHICH DYNAMICALLY C ALLOCATE STORAGE. DATA MESTAB(1),MESTAB(2),MESTAB(3),MESTAB(4),MESTAB(5), 1 MESTAB(6),MESTAB(7),MESTAB(8),MESTAB(9),MESTAB(10) 2 /0,0,0,0,0,0,0,0,0,0/ DATA NERTAB(1),NERTAB(2),NERTAB(3),NERTAB(4),NERTAB(5), 1 NERTAB(6),NERTAB(7),NERTAB(8),NERTAB(9),NERTAB(10) 2 /0,0,0,0,0,0,0,0,0,0/ DATA LEVTAB(1),LEVTAB(2),LEVTAB(3),LEVTAB(4),LEVTAB(5), 1 LEVTAB(6),LEVTAB(7),LEVTAB(8),LEVTAB(9),LEVTAB(10) 2 /0,0,0,0,0,0,0,0,0,0/ C NEXT TWO DATA STATEMENTS ARE NECESSARY TO PROVIDE A BLANK C ERROR TABLE INITIALLY DATA KOUNT(1),KOUNT(2),KOUNT(3),KOUNT(4),KOUNT(5), 1 KOUNT(6),KOUNT(7),KOUNT(8),KOUNT(9),KOUNT(10) 2 /0,0,0,0,0,0,0,0,0,0/ DATA KOUNTX/0/ C NEXT DATA STATEMENT SETS UP OUTPUT FORMAT DATA F(1),F(2),F(3),F(4),F(5),F(6),F(7),F(8),F(9),F(10), 1 F(11),F(12),F(13),F(14),F(15),F(16),F(17) 2 /1H( ,1H1 ,1HX ,1H, ,1HA ,1H ,1H ,1H, ,1HI ,1H , 3 1H ,1H, ,1H2 ,1HI ,1H1 ,1H0 ,1H) / IF (NMESSG.GT.0) GO TO 80 C DUMP THE TABLE IF (KOUNT(1).EQ.0) RETURN C PREPARE FORMAT NCHAR = I1MACH(6) CALL S88FMT(2,NCHAR,F(6)) NCOL = 20 - NCHAR CALL S88FMT(2,NCOL,F(10)) C PRINT TO EACH UNIT CALL XGETUA(LUN,NUNIT) DO 60 KUNIT=1,NUNIT IUNIT = LUN(KUNIT) IF (IUNIT.EQ.0) IUNIT = I1MACH(4) C PRINT TABLE HEADER WRITE (IUNIT,10) 10 FORMAT (32H0 ERROR MESSAGE SUMMARY/ 1 41H FIRST WORD NERR LEVEL COUNT) C PRINT BODY OF TABLE DO 20 I=1,10 IF (KOUNT(I).EQ.0) GO TO 30 WRITE (IUNIT,F) MESTAB(I),NERTAB(I),LEVTAB(I),KOUNT(I) 20 CONTINUE 30 CONTINUE C PRINT NUMBER OF OTHER ERRORS IF (KOUNTX.NE.0) WRITE (IUNIT,40) KOUNTX 40 FORMAT (41H0OTHER ERRORS NOT INDIVIDUALLY TABULATED=,I10) WRITE (IUNIT,50) 50 FORMAT (1X) 60 CONTINUE IF (NMESSG.LT.0) RETURN C CLEAR THE ERROR TABLES DO 70 I=1,10 70 KOUNT(I) = 0 KOUNTX = 0 RETURN 80 CONTINUE C PROCESS A MESSAGE... C SEARCH FOR THIS MESSG, OR ELSE AN EMPTY SLOT FOR THIS MESSG, C OR ELSE DETERMINE THAT THE ERROR TABLE IS FULL. DO 90 I=1,10 II = I IF (KOUNT(I).EQ.0) GO TO 110 IF (MESSG(1).NE.MESTAB(I)) GO TO 90 IF (NERR.NE.NERTAB(I)) GO TO 90 IF (LEVEL.NE.LEVTAB(I)) GO TO 90 GO TO 100 90 CONTINUE C THREE POSSIBLE CASES... C TABLE IS FULL KOUNTX = KOUNTX+1 ICOUNT = 1 RETURN C MESSAGE FOUND IN TABLE 100 KOUNT(II) = KOUNT(II) + 1 ICOUNT = KOUNT(II) RETURN C EMPTY SLOT FOUND FOR NEW MESSAGE 110 MESTAB(II) = MESSG(1) NERTAB(II) = NERR LEVTAB(II) = LEVEL KOUNT(II) = 1 ICOUNT = 1 RETURN END SUBROUTINE XGETF(KONTRL) XER 10 C C ABSTRACT C XGETF RETURNS THE CURRENT VALUE OF THE ERROR CONTROL FLAG C IN KONTRL. SEE SUBROUTINE XSETF FOR FLAG VALUE MEANINGS. C (KONTRL IS AN OUTPUT PARAMETER ONLY.) C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 7 JUNE 1978 C KONTRL = J4SAVE(2,0,.FALSE.) RETURN END SUBROUTINE XGETUA(IUNIT,N) XER 10 C C ABSTRACT C XGETUA MAY BE CALLED TO DETERMINE THE UNIT NUMBER OR NUMBERS C TO WHICH ERROR MESSAGES ARE BEING SENT. C THESE UNIT NUMBERS MAY HAVE BEEN SET BY A CALL TO XSETUN, C OR A CALL TO XSETUA, OR MAY BE A DEFAULT VALUE. C C DESCRIPTION OF PARAMETERS C --OUTPUT-- C IUNIT - AN ARRAY OF ONE TO FIVE UNIT NUMBERS, DEPENDING C ON THE VALUE OF N. A VALUE OF ZERO REFERS TO THE C DEFAULT UNIT, AS DEFINED BY THE I1MACH MACHINE C CONSTANT ROUTINE. ONLY IUNIT(1),...,IUNIT(N) ARE C DEFINED BY XGETUA. THE VALUES OF IUNIT(N+1),..., C IUNIT(5) ARE NOT DEFINED (FOR N.LT.5) OR ALTERED C IN ANY WAY BY XGETUA. C N - THE NUMBER OF UNITS TO WHICH COPIES OF THE C ERROR MESSAGES ARE BEING SENT. N WILL BE IN THE C RANGE FROM 1 TO 5. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C DIMENSION IUNIT(5) N = J4SAVE(5,0,.FALSE.) DO 30 I=1,N INDEX = I+4 IF (I.EQ.1) INDEX = 3 IUNIT(I) = J4SAVE(INDEX,0,.FALSE.) 30 CONTINUE RETURN END SUBROUTINE XGETUN(IUNIT) XER 10 C C ABSTRACT C XGETUN GETS THE (FIRST) OUTPUT FILE TO WHICH ERROR MESSAGES C ARE BEING SENT. TO FIND OUT IF MORE THAN ONE FILE IS BEING C USED, ONE MUST USE THE XGETUA ROUTINE. C C DESCRIPTION OF PARAMETER C --OUTPUT-- C IUNIT - THE LOGICAL UNIT NUMBER OF THE (FIRST) UNIT TO C WHICH ERROR MESSAGES ARE BEING SENT. C A VALUE OF ZERO MEANS THAT THE DEFAULT FILE, AS C DEFINED BY THE I1MACH ROUTINE, IS BEING USED. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 23 MAY 1979 C IUNIT = J4SAVE(3,0,.FALSE.) RETURN END SUBROUTINE XSETF(KONTRL) XER 10 C C ABSTRACT C XSETF SETS THE ERROR CONTROL FLAG VALUE TO KONTRL. C (KONTRL IS AN INPUT PARAMETER ONLY.) C THE FOLLOWING TABLE SHOWS HOW EACH MESSAGE IS TREATED, C DEPENDING ON THE VALUES OF KONTRL AND LEVEL. (SEE XERROR C FOR DESCRIPTION OF LEVEL.) C C IF KONTRL IS ZERO OR NEGATIVE, NO INFORMATION OTHER THAN THE C MESSAGE ITSELF (INCLUDING NUMERIC VALUES, IF ANY) WILL BE C PRINTED. IF KONTRL IS POSITIVE, INTRODUCTORY MESSAGES, C TRACE-BACKS, ETC., WILL BE PRINTED IN ADDITION TO THE MESSAGE. C C IABS(KONTRL) C LEVEL 0 1 2 C VALUE C 2 FATAL FATAL FATAL C C 1 NOT PRINTED PRINTED FATAL C C 0 NOT PRINTED PRINTED PRINTED C C -1 NOT PRINTED PRINTED PRINTED C ONLY ONLY C ONCE ONCE C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 23 MAY 1979 C IF ((KONTRL.GE.(-2)).AND.(KONTRL.LE.2)) GO TO 10 CALL XERRWV(39HXSETF -- INVALID VALUE OF KONTRL (I1).,33,1,2, 1 1,KONTRL,0,0,0.,0.) RETURN 10 JUNK = J4SAVE(2,KONTRL,.TRUE.) RETURN END SUBROUTINE XSETUA(IUNIT,N) XER 10 C C ABSTRACT C XSETUA MAY BE CALLED TO DECLARE A LIST OF UP TO FIVE C LOGICAL UNITS, EACH OF WHICH IS TO RECEIVE A COPY OF C EACH ERROR MESSAGE PROCESSED BY THIS PACKAGE. C THE PURPOSE OF XSETUA IS TO ALLOW SIMULTANEOUS PRINTING C OF EACH ERROR MESSAGE ON, SAY, A MAIN OUTPUT FILE, C AN INTERACTIVE TERMINAL, AND OTHER FILES SUCH AS GRAPHICS C COMMUNICATION FILES. C C DESCRIPTION OF PARAMETERS C --INPUT-- C IUNIT - AN ARRAY OF UP TO FIVE UNIT NUMBERS. C NORMALLY THESE NUMBERS SHOULD ALL BE DIFFERENT. C (BUT DUPLICATES ARE NOT PROHIBITED.) C N - THE NUMBER OF UNIT NUMBERS PROVIDED IN IUNIT. C MUST HAVE 1 .LE. N .LE. 5. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 23 MAY 1979 C DIMENSION IUNIT(5) IF ((N.GE.1).AND.(N.LE.5)) GO TO 10 CALL XERRWV(34HXSETUA -- INVALID VALUE OF N (I1).,34,1,2, 1 1,N,0,0,0.,0.) RETURN 10 CONTINUE DO 20 I=1,N INDEX = I+4 IF (I.EQ.1) INDEX = 3 JUNK = J4SAVE(INDEX,IUNIT(I),.TRUE.) 20 CONTINUE JUNK = J4SAVE(5,N,.TRUE.) RETURN END SUBROUTINE XSETUN(IUNIT) XER 10 C C ABSTRACT C XSETUN SETS THE OUTPUT FILE TO WHICH ERROR MESSAGES ARE TO C BE SENT. ONLY ONE FILE WILL BE USED. SEE XSETUA FOR C HOW TO DECLARE MORE THAN ONE FILE. C C DESCRIPTION OF PARAMETER C --INPUT-- C IUNIT - AN INPUT PARAMETER GIVING THE LOGICAL UNIT NUMBER C TO WHICH ERROR MESSAGES ARE TO BE SENT. C C WRITTEN BY RON JONES, WITH SLATEC COMMON MATH LIBRARY SUBCOMMITTEE C END OF ABSTRACT C LATEST REVISION --- 7 JUNE 1978 C JUNK = J4SAVE(3,IUNIT,.TRUE.) JUNK = J4SAVE(5,1,.TRUE.) RETURN END INTEGER FUNCTION I1MACH(I) C***BEGIN PROLOGUE I1MACH C***REVISION DATE 811015 (YYMMDD) C***CATEGORY NO. Q C***KEYWORDS MACHINE CONSTANTS,INTEGER C***DATE WRITTEN 1975 C***AUTHOR FOX P.A.,HALL A.D.,SCHRYER N.L. (BELL LABS) C***PURPOSE C RETURNS INTEGER MACHINE DEPENDENT CONSTANTS C***DESCRIPTION C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * C THESE MACHINE CONSTANT ROUTINES MUST BE ACTIVATED FOR C A PARTICULAR ENVIRONMENT. C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * C C I1MACH CAN BE USED TO OBTAIN MACHINE-DEPENDENT PARAMETERS C FOR THE LOCAL MACHINE ENVIRONMENT. IT IS A FUNCTION C SUBROUTINE WITH ONE (INPUT) ARGUMENT, AND CAN BE CALLED C AS FOLLOWS, FOR EXAMPLE C C K = I1MACH(I) C C WHERE I=1,...,16. THE (OUTPUT) VALUE OF K ABOVE IS C DETERMINED BY THE (INPUT) VALUE OF I. THE RESULTS FOR C VARIOUS VALUES OF I ARE DISCUSSED BELOW. C C I/O UNIT NUMBERS. C I1MACH( 1) = THE STANDARD INPUT UNIT. C I1MACH( 2) = THE STANDARD OUTPUT UNIT. C I1MACH( 3) = THE STANDARD PUNCH UNIT. C I1MACH( 4) = THE STANDARD ERROR MESSAGE UNIT. C C WORDS. C I1MACH( 5) = THE NUMBER OF BITS PER INTEGER STORAGE UNIT. C I1MACH( 6) = THE NUMBER OF CHARACTERS PER INTEGER STORAGE UNIT. C C INTEGERS. C ASSUME INTEGERS ARE REPRESENTED IN THE S-DIGIT, BASE-A FORM C C SIGN ( X(S-1)*A**(S-1) + ... + X(1)*A + X(0) ) C C WHERE 0 .LE. X(I) .LT. A FOR I=0,...,S-1. C I1MACH( 7) = A, THE BASE. C I1MACH( 8) = S, THE NUMBER OF BASE-A DIGITS. C I1MACH( 9) = A**S - 1, THE LARGEST MAGNITUDE. C C FLOATING-POINT NUMBERS. C ASSUME FLOATING-POINT NUMBERS ARE REPRESENTED IN THE T-DIGIT, C BASE-B FORM C SIGN (B**E)*( (X(1)/B) + ... + (X(T)/B**T) ) C C WHERE 0 .LE. X(I) .LT. B FOR I=1,...,T, C 0 .LT. X(1), AND EMIN .LE. E .LE. EMAX. C I1MACH(10) = B, THE BASE. C C SINGLE-PRECISION C I1MACH(11) = T, THE NUMBER OF BASE-B DIGITS. C I1MACH(12) = EMIN, THE SMALLEST EXPONENT E. C I1MACH(13) = EMAX, THE LARGEST EXPONENT E. C C DOUBLE-PRECISION C I1MACH(14) = T, THE NUMBER OF BASE-B DIGITS. C I1MACH(15) = EMIN, THE SMALLEST EXPONENT E. C I1MACH(16) = EMAX, THE LARGEST EXPONENT E. C C TO ALTER THIS FUNCTION FOR A PARTICULAR ENVIRONMENT, C THE DESIRED SET OF DATA STATEMENTS SHOULD BE ACTIVATED BY C REMOVING THE C FROM COLUMN 1. ALSO, THE VALUES OF C I1MACH(1) - I1MACH(4) SHOULD BE CHECKED FOR CONSISTENCY C WITH THE LOCAL OPERATING SYSTEM. C C***REFERENCES C FOX P.A., HALL A.D., SCHRYER N.L.,*FRAMEWORK FOR A PORTABLE LIBRARY*, C ACM TRANSACTION ON MATHEMATICAL SOFTWARE, VOL. 4, NO. 2, C JUNE 1978, PP. 177-188. C***ROUTINES CALLED XERROR C***END PROLOGUE I1MACH C INTEGER IMACH(16),OUTPUT C C EQUIVALENCE (IMACH(4),OUTPUT) C C MACHINE CONSTANTS FOR THE BURROUGHS 1700 SYSTEM. C C DATA IMACH( 1) / 7 / C DATA IMACH( 2) / 2 / C DATA IMACH( 3) / 2 / C DATA IMACH( 4) / 2 / C DATA IMACH( 5) / 36 / C DATA IMACH( 6) / 4 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 33 / C DATA IMACH( 9) / Z1FFFFFFFF / C DATA IMACH(10) / 2 / C DATA IMACH(11) / 24 / C DATA IMACH(12) / -256 / C DATA IMACH(13) / 255 / C DATA IMACH(14) / 60 / C DATA IMACH(15) / -256 / C DATA IMACH(16) / 255 / C C MACHINE CONSTANTS FOR THE BURROUGHS 5700 SYSTEM. C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 7 / C DATA IMACH( 4) / 6 / C DATA IMACH( 5) / 48 / C DATA IMACH( 6) / 6 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 39 / C DATA IMACH( 9) / O0007777777777777 / C DATA IMACH(10) / 8 / C DATA IMACH(11) / 13 / C DATA IMACH(12) / -50 / C DATA IMACH(13) / 76 / C DATA IMACH(14) / 26 / C DATA IMACH(15) / -50 / C DATA IMACH(16) / 76 / C C MACHINE CONSTANTS FOR THE BURROUGHS 6700/7700 SYSTEMS. C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 7 / C DATA IMACH( 4) / 6 / C DATA IMACH( 5) / 48 / C DATA IMACH( 6) / 6 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 39 / C DATA IMACH( 9) / O0007777777777777 / C DATA IMACH(10) / 8 / C DATA IMACH(11) / 13 / C DATA IMACH(12) / -50 / C DATA IMACH(13) / 76 / C DATA IMACH(14) / 26 / C DATA IMACH(15) / -32754 / C DATA IMACH(16) / 32780 / C C MACHINE CONSTANTS FOR THE CDC 6000/7000 SERIES. C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 7 / C DATA IMACH( 4) /6LOUTPUT/ C DATA IMACH( 5) / 60 / C DATA IMACH( 6) / 10 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 48 / C DATA IMACH( 9) / 00007777777777777777B / C DATA IMACH(10) / 2 / C DATA IMACH(11) / 48 / C DATA IMACH(12) / -974 / C DATA IMACH(13) / 1070 / C DATA IMACH(14) / 96 / C DATA IMACH(15) / -927 / C DATA IMACH(16) / 1070 / C C MACHINE CONSTANTS FOR THE CRAY 1 C C DATA IMACH( 1) / 100 / C DATA IMACH( 2) / 101 / C DATA IMACH( 3) / 102 / C DATA IMACH( 4) / 101 / C DATA IMACH( 5) / 64 / C DATA IMACH( 6) / 8 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 63 / C DATA IMACH( 9) / 777777777777777777777B / C DATA IMACH(10) / 2 / C DATA IMACH(11) / 48 / C DATA IMACH(12) / -8192 / C DATA IMACH(13) / 8191 / C DATA IMACH(14) / 96 / C DATA IMACH(15) / -8192 / C DATA IMACH(16) / 8191 / C C MACHINE CONSTANTS FOR THE DATA GENERAL ECLIPSE S/200 C C DATA IMACH( 1) / 11 / C DATA IMACH( 2) / 12 / C DATA IMACH( 3) / 8 / C DATA IMACH( 4) / 10 / C DATA IMACH( 5) / 16 / C DATA IMACH( 6) / 2 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 15 / C DATA IMACH( 9) /32767 / C DATA IMACH(10) / 16 / C DATA IMACH(11) / 6 / C DATA IMACH(12) / -64 / C DATA IMACH(13) / 63 / C DATA IMACH(14) / 14 / C DATA IMACH(15) / -64 / C DATA IMACH(16) / 63 / C C MACHINE CONSTANTS FOR THE HARRIS 220 C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 0 / C DATA IMACH( 4) / 6 / C DATA IMACH( 5) / 24 / C DATA IMACH( 6) / 3 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 23 / C DATA IMACH( 9) / 8388607 / C DATA IMACH(10) / 2 / C DATA IMACH(11) / 23 / C DATA IMACH(12) / -127 / C DATA IMACH(13) / 127 / C DATA IMACH(14) / 38 / C DATA IMACH(15) / -127 / C DATA IMACH(16) / 127 / C C MACHINE CONSTANTS FOR THE HONEYWELL 600/6000 SERIES. C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 43 / C DATA IMACH( 4) / 6 / C DATA IMACH( 5) / 36 / C DATA IMACH( 6) / 6 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 35 / C DATA IMACH( 9) / O377777777777 / C DATA IMACH(10) / 2 / C DATA IMACH(11) / 27 / C DATA IMACH(12) / -127 / C DATA IMACH(13) / 127 / C DATA IMACH(14) / 63 / C DATA IMACH(15) / -127 / C DATA IMACH(16) / 127 / C C MACHINE CONSTANTS FOR THE HP 2100 C 3 WORD DOUBLE PRECISION OPTION WITH FTN4 C C DATA IMACH(1) / 5/ C DATA IMACH(2) / 6 / C DATA IMACH(3) / 4 / C DATA IMACH(4) / 1 / C DATA IMACH(5) / 16 / C DATA IMACH(6) / 2 / C DATA IMACH(7) / 2 / C DATA IMACH(8) / 15 / C DATA IMACH(9) / 32767 / C DATA IMACH(10)/ 2 / C DATA IMACH(11)/ 23 / C DATA IMACH(12)/ -128 / C DATA IMACH(13)/ 127 / C DATA IMACH(14)/ 39 / C DATA IMACH(15)/ -128 / C DATA IMACH(16)/ 127 / C C MACHINE CONSTANTS FOR THE HP 2100 C 4 WORD DOUBLE PRECISION OPTION WITH FTN4 C C DATA IMACH(1) / 5 / C DATA IMACH(2) / 6 / C DATA IMACH(3) / 4 / C DATA IMACH(4) / 1 / C DATA IMACH(5) / 16 / C DATA IMACH(6) / 2 / C DATA IMACH(7) / 2 / C DATA IMACH(8) / 15 / C DATA IMACH(9) / 32767 / C DATA IMACH(10)/ 2 / C DATA IMACH(11)/ 23 / C DATA IMACH(12)/ -128 / C DATA IMACH(13)/ 127 / C DATA IMACH(14)/ 55 / C DATA IMACH(15)/ -128 / C DATA IMACH(16)/ 127 / C C MACHINE CONSTANTS FOR THE IBM 360/370 SERIES, C THE XEROX SIGMA 5/7/9, THE SEL SYSTEMS 85/86, AND C THE PERKIN ELMER (INTERDATA) 7/32. C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 7 / C DATA IMACH( 4) / 6 / C DATA IMACH( 5) / 32 / C DATA IMACH( 6) / 4 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 31 / C DATA IMACH( 9) / Z7FFFFFFF / C DATA IMACH(10) / 16 / C DATA IMACH(11) / 6 / C DATA IMACH(12) / -64 / C DATA IMACH(13) / 63 / C DATA IMACH(14) / 14 / C DATA IMACH(15) / -64 / C DATA IMACH(16) / 63 / C C MACHINE CONSTANTS FOR THE PDP-10 (KA PROCESSOR). C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 5 / C DATA IMACH( 4) / 6 / C DATA IMACH( 5) / 36 / C DATA IMACH( 6) / 5 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 35 / C DATA IMACH( 9) / "377777777777 / C DATA IMACH(10) / 2 / C DATA IMACH(11) / 27 / C DATA IMACH(12) / -128 / C DATA IMACH(13) / 127 / C DATA IMACH(14) / 54 / C DATA IMACH(15) / -101 / C DATA IMACH(16) / 127 / C C MACHINE CONSTANTS FOR THE PDP-10 (KI PROCESSOR). C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 5 / C DATA IMACH( 4) / 6 / C DATA IMACH( 5) / 36 / C DATA IMACH( 6) / 5 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 35 / C DATA IMACH( 9) / "377777777777 / C DATA IMACH(10) / 2 / C DATA IMACH(11) / 27 / C DATA IMACH(12) / -128 / C DATA IMACH(13) / 127 / C DATA IMACH(14) / 62 / C DATA IMACH(15) / -128 / C DATA IMACH(16) / 127 / C C MACHINE CONSTANTS FOR PDP-11 FORTRAN S SUPPORTING C 32-BIT INTEGER ARITHMETIC. C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 5 / C DATA IMACH( 4) / 6 / C DATA IMACH( 5) / 32 / C DATA IMACH( 6) / 4 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 31 / C DATA IMACH( 9) / 2147483647 / C DATA IMACH(10) / 2 / C DATA IMACH(11) / 24 / C DATA IMACH(12) / -127 / C DATA IMACH(13) / 127 / C DATA IMACH(14) / 56 / C DATA IMACH(15) / -127 / C DATA IMACH(16) / 127 / C C MACHINE CONSTANTS FOR PDP-11 FORTRAN S SUPPORTING C 16-BIT INTEGER ARITHMETIC. C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 5 / C DATA IMACH( 4) / 6 / C DATA IMACH( 5) / 16 / C DATA IMACH( 6) / 2 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 15 / C DATA IMACH( 9) / 32767 / C DATA IMACH(10) / 2 / C DATA IMACH(11) / 24 / C DATA IMACH(12) / -127 / C DATA IMACH(13) / 127 / C DATA IMACH(14) / 56 / C DATA IMACH(15) / -127 / C DATA IMACH(16) / 127 / C C MACHINE CONSTANTS FOR THE UNIVAC 1100 SERIES. FTN COMPILER C C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 1 / C DATA IMACH( 4) / 6 / C DATA IMACH( 5) / 36 / C DATA IMACH( 6) / 4 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 35 / C DATA IMACH( 9) / O377777777777 / C DATA IMACH(10) / 2 / C DATA IMACH(11) / 27 / C DATA IMACH(12) / -128 / C DATA IMACH(13) / 127 / C DATA IMACH(14) / 60 / C DATA IMACH(15) /-1024 / C DATA IMACH(16) / 1023 / C C MACHINE CONSTANTS FOR THE UNIVAC 1100 SERIES. FOR COMPILER C C DATA IMACH( 1) / 5 / C DATA IMACH( 2) / 6 / C DATA IMACH( 3) / 7 / C DATA IMACH( 4) / 6 / C DATA IMACH( 5) / 36 / C DATA IMACH( 6) / 6 / C DATA IMACH( 7) / 2 / C DATA IMACH( 8) / 35 / C DATA IMACH( 9) / O377777777777 / C DATA IMACH(10) / 2 / C DATA IMACH(11) / 27 / C DATA IMACH(12) / -128 / C DATA IMACH(13) / 127 / C DATA IMACH(14) / 60 / C DATA IMACH(15) /-1024/ C DATA IMACH(16) / 1023 / C C C MACHINE CONSTANTS FOR THE VAX 11/780 C C DATA IMACH(1) / 5 / C DATA IMACH(2) / 6 / C DATA IMACH(3) / 5 / C DATA IMACH(4) / 6 / C DATA IMACH(5) / 32 / C DATA IMACH(6) / 4 / C DATA IMACH(7) / 2 / C DATA IMACH(8) / 31 / C DATA IMACH(9) /2147483647 / C DATA IMACH(10)/ 2 / C DATA IMACH(11)/ 24 / C DATA IMACH(12)/ -127 / C DATA IMACH(13)/ 127 / C DATA IMACH(14)/ 56 / C DATA IMACH(15)/ -127 / C DATA IMACH(16)/ 127 / C C***FIRST EXECUTABLE STATEMENT I1MACH C IF (I .LT. 1 .OR. I .GT. 16) GO TO 10 C I1MACH=IMACH(I) RETURN C 10 CONTINUE WRITE(OUTPUT,9000) 9000 FORMAT(39H1ERROR 1 IN I1MACH - I OUT OF BOUNDS ) C C CALL FDUMP C C STOP END SUBROUTINE CLSTP(KLOG, COND, ISTAT) CLS 10 C C THE EDITING REQUIRED TO CONVERT THIS SUBROUTINE FROM SINGLE TO C DOUBLE PRECISION INVOLVES THE FOLLOWING CHARACTER STRING CHANGES. C USE AN EDITING COMMAND (CHANGE) /STRING-1/(TO)STRING-2/. C (BEGIN THE CHANGES AT THE LINE WITH C++ IN COLS. 1-3.) C /REAL (12 BLANKS)/DOUBLE PRECISION/,/SCOPY/DCOPY/,/SDOT/DDOT/, C /SNRM2/DNRM2/,/SQRT/DSQRT/,/E0/D0/,/SSCAL/DSCAL/,/SAXPY/DAXPY/, C /SRELPR/DRELPR/,/SSWAP/DSWAP/ C C REVISED 820305-2000 C REVISED YYMMDD-HHMM C C THIS SUBROUTINE EXERCISES MOST OF THE MATHEMATICAL FEATURES OF THE C CONSTRAINED LEAST SQUARES SUBPROGRAMS WNNLS( ) AND LSEI( ). C THE PROBLEM THAT IS SOLVED HERE IS OF THE FORM C C A*X=B (LEAST SQUARES, A MA BY N), C C C SUBJECT TO CONSTRAINTS C C E*X=F (CONSTRAINT EQUATIONS, ME BY N), C AND G*X .GE. H (INEQUALITY CONSTRAINTS, MG BY N). C C THE CLASS OF PROBLEMS THAT IS SOLVED HERE IS GENERATED WITH C HADAMARD MATRICES OF ORDER=POWER OF 2. EACH OF THE MATRICES C A,E, AND G HAVE A SPECIFIED CONDITION NUMBER. FOR EXAMPLE C A=HADAMARD MATRIX * DIAGONAL MATRIX * HADAMARD MATRIX. C DIAGONAL TERMS OF THE DIAGONAL MATRIX ARE CHOSEN SO THAT A C HAS A GIVEN CONDITION NUMBER. THE MATRICES E AND G ARE C CONSTRUCTED IN SIMILIAR WAYS. FURTHER, THE PROBLEM IS CONSTRUCTED C SO THAT THE TRUE SOLUTION IS X=(1,...,1) (TRANSPOSED). C THIS REQUIRES COMPUTING THE RIGHT HAND SIDE VECTORS B,F AND C H. THE VECTOR B=A*X+COMPONENT ORTHOGONAL TO COL. SPACE OF C A, F=E*X, AND H=G*H-SLACK COMPONENTS. THESE SLACK COMPONENTS C ARE CHOSEN SO THAT THE FIRST MI OF THE INEQUALITIES ARE C STRICT INEQUALITIES. C C THE PROBLEMS DIMENSIONS ARE SPECIFIED BY C C MA = 2**KA C ME = 2**KE C MG = 2**KG C MI = 2**KI C N = 2**KN C C WHERE KA, KE, KG, KI, AND KN ARE INPUT TO THE SUBROUTINE AS C DISCUSSED BELOW. C C THE SUBROUTINE ARGUMENTS ARE AS FOLLOWS C C I N P U T C C KLOG(*) - AN INTEGER ARRAY WHOSE DIMENSION IS AT LEAST 5. THE C ENTRIES CORRESPOND TO THE POWERS OF 2 NECESSARY C TO SPECIFY THE PROBLEM DIMENSIONS. REFERRING TO C THE ABOVE DISCUSSION, THE ENTRIES OF KLOG(*) C SHOULD BE SET AS FOLLOWS C C KLOG(1) = KA C KLOG(2) = KE C KLOG(3) = KG C KLOG(4) = KI C KLOG(5) = KN C C IF KA, KE, KG, OR KI IS LESS THAN ZERO, THE C CORRESPONDING DIMENSION WILL BE SET TO ZERO. C C KN.LT.0 WILL CAUSE THE SUBROUTINE TO SIMPLY RETURN. C C COND(*) - AN ARRAY WHOSE DIMENSION IS AT LEAST 3. THE C ENTRIES COND(1), COND(2), AND COND(3) RESPECTIVELY C SPECIFY THE CONDITION NUMBER FOR THE LEAST SQUARES C MATRIX, THE EQUALITY CONSTRAINT MATRIX, AND THE C INEQUALITY CONSTRAINT MATRIX. C C O U T P U T C C ISTAT - AN INTEGER FLAG WHICH INDICATES WHETHER THE SOLUTION C WAS CORRECTLY COMPUTED. C =1 NEITHER WNNLS( ) NOR LSEI( ) PASSED THE TEST. C =2 WNNLS( ) PASSED BUT LSEI( ) FAILED THE TEST. C =3 LSEI( ) PASSED BUT WNNLS( ) FAILED THE TEST. C =4 BOTH WNNLS( ) AND LSEI( ) PASSED THE TEST. C C THE DIMENSION STATEMENTS BELOW ARE SET UP TO SOLVE PROBLEMS FOR C WHICH NONE OF THE ABOVE LOGARITHMS IS GREATER THAN 5. TO CHANGE C THESE DIMENSIONS TO SOLVE LARGER PROBLEMS, USE THE FOLLOWING C FORMULAS C C DIMENSION W(MA+ME+MG,N+MG+1),X(N+MG),HH(MMAX,MMAX),GG(MMAX,MMAX) C DIMENSION WORK(2*(ME+N)+K+(MG+2)*(N+7)),IWORK(ME+MA+2*MG+N) C DIMENSION SA(MIN(MA,N)),SE(MIN(ME,N)),SG(MIN(MG,N)) C C WHERE MMAX = MAX(MA,ME,MG,N) C K = MAX(MA+MG,N) C C NOTE THAT IF THE DIMENSIONS ARE CHANGED, THE VALUES ASSIGNED TO C MDW, MDH, AND MDG BELOW MUST BE ALTERED APPROPRIATELY. THESE C ARE THE RESPECTIVE ROW DIMENSIONS OF THE ARRAYS W(*,*), HH(*,*), C AND GG(*,*). C++ REAL ANSR, BETA, BNORM, CONDA, CONDE, CONDG, * DXBYX, GAM, GNORM, ONE, PHI, RHO, RNORME, * RNORML, SOLERR, SRELPR, T, TWO, ZERO REAL SNRM2, SDOT, SQRT REAL W(96,65), X(64), HH(32,32), GG(32,32) REAL WORK(1518) INTEGER IWORK(0640) REAL SA(32), SE(32), SG(32) C C THE FOLLOWING DIMENSION STATEMENTS NEED NOT BE ALTERED TO C SOLVE LARGER PROBLEMS. REAL COND(3), PRGOPT(4) INTEGER KLOG(5) LOGICAL DONE C MDW = 96 MDH = 32 MDG = 32 ZERO = 0.E0 ONE = 1.E0 TWO = 2.E0 ISTAT = 1 C COMPUTE THE RELATIVE MACHINE PRECISION. SRELPR = ONE 10 IF (ONE+SRELPR.EQ.ONE) GO TO 20 SRELPR = SRELPR/TWO GO TO 10 20 SRELPR = SRELPR*TWO C C SET THE OUTPUT UNIT TO WHICH ERROR MESSAGES WILL BE PRINTED. LOUT = I1MACH(4) C C SET UP THE PROBLEM DIMENSIONS KA = KLOG(1) KE = KLOG(2) KG = KLOG(3) KI = KLOG(4) KN = KLOG(5) CONDA = ONE CONDE = ONE CONDG = ONE DONE = KN.LT.0 IF (.NOT.(DONE)) GO TO 30 RETURN 30 MA = 0 ME = 0 MG = 0 N = 0 C C SET NOISE-TO-SIGNAL RATIO PARAMETER FOR LEAST SQUARES EQUAS. C THIS ESSENTIALLY SPECIFIES THE RATIO C C NORM(RESIDUAL VECTOR) C --------------------- C NORM(A*X) ANSR = 0.01 C C SET UP THE CONDITION NUMBERS FOR THE MATRICES A, E, AND G. IF (KA.GE.0) CONDA = COND(1) IF (KE.GE.0) CONDE = COND(2) IF (KG.GE.0) CONDG = COND(3) C C CHECK THE VALIDITY OF THE INPUT IF (.NOT.(.NOT.(KA.LE.5 .AND. KE.LE.5 .AND. KG.LE.5 .AND. KI.LE.5 * .AND. KN.LE.5))) GO TO 40 WRITE (LOUT,99999) RETURN 40 IF (.NOT.(CONDA.LT.ONE .OR. CONDE.LT.ONE .OR. CONDG.LT.ONE)) GO * TO 50 WRITE (LOUT,99998) 99999 FORMAT (/42H KA, KE, KG, KI, AND KN MUST ALL BE .LE. 5, 7H AS REQ, * 53HUIRED BY THE CURRENT SUBPROGRAM DIMENSION STATEMENTS.) 99998 FORMAT (/46H CONDA, CONDE, AND CONDG MUST ALL BE .GE. ONE.) RETURN 50 CONTINUE ICASE = 1 60 CONTINUE ISEED = 100001 T = RAN(ISEED) ISEED = 0 C C COMPUTE THE PRE-MULTIPLYING HADAMARD MATRIX FOR E. K = KE ASSIGN 70 TO NGO GO TO 900 70 ME = NN C C SAVE THE HADAMARD MATRIX. J = 1 N20011 = ME GO TO 90 80 J = J + 1 90 IF ((N20011-J).LT.0) GO TO 100 CALL SCOPY(ME, HH(1,J), 1, GG(1,J), 1) GO TO 80 C C NOW FORM THE POST-MULTIPLYING HADAMARD MATRIX. 100 K = KN ASSIGN 110 TO NGO GO TO 900 110 N = NN C C COMPUTE THE SINGULAR VALUES OF THE MATRIX E. C DISTRIBUTE THEM UNIFORMLY BETWEEN 1. AND CONDE. SE(1) = CONDE MNE = MAX0(1,MIN0(ME,N)) SE(MNE) = ONE I = 2 N20016 = MNE - 1 GO TO 130 120 I = I + 1 130 IF ((N20016-I).LT.0) GO TO 140 SE(I) = ONE + RAN(ISEED)*(CONDE-ONE) GO TO 120 140 J = 1 N20020 = MNE GO TO 160 150 J = J + 1 160 IF ((N20020-J).LT.0) GO TO 170 CALL SSCAL(ME, SE(J), GG(1,J), 1) GO TO 150 170 J = 1 N20024 = N GO TO 190 180 J = J + 1 190 IF ((N20024-J).LT.0) GO TO 230 IF (ME.GT.0) W(1,J) = ZERO CALL SCOPY(ME, W(1,J), 0, W(1,J), 1) I = 1 N20028 = MNE GO TO 210 200 I = I + 1 210 IF ((N20028-I).LT.0) GO TO 220 CALL SAXPY(ME, HH(I,J), GG(1,I), 1, W(1,J), 1) GO TO 200 220 GO TO 180 C C COMPUTE E*X AND STORE IN W(*,N+1). 230 I = 1 N20032 = ME GO TO 250 240 I = I + 1 250 IF ((N20032-I).LT.0) GO TO 260 X(1) = ONE W(I,N+1) = SDOT(N,X,0,W(I,1),MDW) GO TO 240 C C COMPUTE THE PRE-MULTIPLYING HADAMARD MATRIX FOR A. 260 K = KA ASSIGN 270 TO NGO GO TO 900 270 MA = NN C C SAVE THE HADAMARD MATRIX. J = 1 N20037 = MA GO TO 290 280 J = J + 1 290 IF ((N20037-J).LT.0) GO TO 300 CALL SCOPY(MA, HH(1,J), 1, GG(1,J), 1) GO TO 280 C C NOW FORM THE POST-MULTIPLYING HADAMARD MATRIX. 300 K = KN ASSIGN 310 TO NGO GO TO 900 310 N = NN C C COMPUTE THE SINGULAR VALUES OF THE MATRIX A. C DISTRUBUTE THEM UNIFORMLY BETWEEN 1. AND CONDA. SA(1) = CONDA MNA = MAX0(1,MIN0(MA,N)) SA(MNA) = ONE I = 2 N20042 = MNA - 1 GO TO 330 320 I = I + 1 330 IF ((N20042-I).LT.0) GO TO 340 SA(I) = ONE + RAN(ISEED)*(CONDA-ONE) GO TO 320 340 J = 1 N20046 = MNA GO TO 360 350 J = J + 1 360 IF ((N20046-J).LT.0) GO TO 370 CALL SSCAL(MA, SA(J), GG(1,J), 1) GO TO 350 370 J = 1 N20050 = N GO TO 390 380 J = J + 1 390 IF ((N20050-J).LT.0) GO TO 430 C C COMPUTE THE PRODUCT IN PLACE INTO W(*,*). IF (MA.GT.0) W(ME+1,J) = ZERO CALL SCOPY(MA, W(ME+1,J), 0, W(ME+1,J), 1) I = 1 N20054 = MNA GO TO 410 400 I = I + 1 410 IF ((N20054-I).LT.0) GO TO 420 CALL SAXPY(MA, HH(I,J), GG(1,I), 1, W(ME+1,J), 1) GO TO 400 420 GO TO 380 C C COMPUTE A*X AND STORE IN W(*,N+1). 430 I = 1 N20058 = MA GO TO 450 440 I = I + 1 450 IF ((N20058-I).LT.0) GO TO 460 MEPI = ME + I X(1) = ONE W(MEPI,N+1) = SDOT(N,X,0,W(MEPI,1),MDW) GO TO 440 460 BNORM = SNRM2(MA,W(ME+1,N+1),1) C C ADD COMPONENTS TO RIGHT SIDE THAT ARE ORTHOGONAL TO COL. C SPACE OF A. K = KA ASSIGN 470 TO NGO GO TO 900 470 MA = NN I = N + 1 N20063 = MA GO TO 490 480 I = I + 1 490 IF ((N20063-I).LT.0) GO TO 500 T = RAN(ISEED)*BNORM*ANSR CALL SAXPY(MA, T, HH(1,I), 1, W(ME+1,N+1), 1) GO TO 480 C C COMPUTE THE PRE-MULTIPLYING HADAMARD MATRIX FOR G. 500 K = KG ASSIGN 510 TO NGO GO TO 900 510 MG = NN C C SAVE THE HADAMARD MATRIX. J = 1 N20068 = MG GO TO 530 520 J = J + 1 530 IF ((N20068-J).LT.0) GO TO 540 CALL SCOPY(MG, HH(1,J), 1, GG(1,J), 1) GO TO 520 C C NOW FORM THE POST-MULTIPLYING HADAMARD MATRIX. 540 K = KN ASSIGN 550 TO NGO GO TO 900 550 N = NN C C COMPUTE THE SINGULAR VALUES OF G. C DISTRIBUTE THEM UNIFORMLY BETWEEN 1. AND CONDG. SG(1) = CONDG MNG = MAX0(1,MIN0(MG,N)) SG(MNG) = ONE I = 2 N20073 = MNG - 1 GO TO 570 560 I = I + 1 570 IF ((N20073-I).LT.0) GO TO 580 SG(I) = ONE + RAN(ISEED)*(CONDG-ONE) GO TO 560 580 J = 1 N20077 = MNG GO TO 600 590 J = J + 1 600 IF ((N20077-J).LT.0) GO TO 610 CALL SSCAL(MG, SG(J), GG(1,J), 1) GO TO 590 610 J = 1 N20081 = N GO TO 630 620 J = J + 1 630 IF ((N20081-J).LT.0) GO TO 670 MEPMA = ME + MA IF (MG.GT.0) W(MEPMA+1,J) = ZERO CALL SCOPY(MG, W(MEPMA+1,J), 0, W(MEPMA+1,J), 1) I = 1 N20085 = MNG GO TO 650 640 I = I + 1 650 IF ((N20085-I).LT.0) GO TO 660 CALL SAXPY(MG, HH(I,J), GG(1,I), 1, W(MEPMA+1,J), 1) GO TO 640 660 GO TO 620 C C COMPUTE G*X AND STORE IN W(*,N+1). 670 I = 1 N20089 = MG GO TO 690 680 I = I + 1 690 IF ((N20089-I).LT.0) GO TO 700 IROW = I + MEPMA X(1) = ONE W(IROW,N+1) = SDOT(N,X,0,W(IROW,1),MDW) GO TO 680 C C MAKE FIRST MI=2**KI OF THE INEQUALITIES STRICT. 700 IF (.NOT.(KI.GE.0)) GO TO 710 MI = 1 GO TO 720 710 MI = 0 720 K = 1 N20096 = KI GO TO 740 730 K = K + 1 740 IF ((N20096-K).LT.0) GO TO 750 MI = MI + MI GO TO 730 750 GNORM = SNRM2(MG,W(MEPMA+1,N+1),1) I = 1 N20100 = MIN0(MI,MG) GO TO 770 760 I = I + 1 770 IF ((N20100-I).LT.0) GO TO 780 IROW = I + MEPMA W(IROW,N+1) = W(IROW,N+1) - RAN(ISEED)*GNORM GO TO 760 C C OBTAIN THE CONSTRAINED LEAST SQUARES SOLUTION. C C NOTE THE LENGTHS OF THE WORK ARRAYS IN IWORK(*). 780 IWORK(1) = 1518 IWORK(2) = 0640 IF (.NOT.(ICASE.EQ.1)) GO TO 810 C C EXCHANGE POSITIONS OF THE ROWS (A B) AND (G H). NP1 = N + 1 DO 790 J=1,NP1 IROW = ME + (MA+MG+2)/2 CALL SSWAP((MA+MG+1)/2, W(ME+1,J), 1, W(IROW,J), -1) 790 CONTINUE C C MOVE RT-SIDE TO W(*,N+MG+1). JCOL = N + MG + 1 CALL SCOPY(ME+MA+MG, W(1,N+1), 1, W(1,JCOL), 1) C C PUT IN SLACK VARIABLE COLS. AS REQUIRED. IF (.NOT.(MG.GT.0)) GO TO 800 W(1,N+1) = ZERO CALL SCOPY(MDW*MG, W(1,N+1), 0, W(1,N+1), 1) W(ME+1,N+1) = -ONE CALL SCOPY(MG, W(ME+1,N+1), 0, W(ME+1,N+1), MDW+1) 800 CONTINUE C C SET THE OPTION (NUMBER 6) FOR WNNLS( ) TO SCALE THE C COLUMNS OF THE MATRIX TO HAVE UNIT LENGTH. PRGOPT(1) = 4 PRGOPT(2) = 6 PRGOPT(3) = 1 PRGOPT(4) = 1 CALL WNNLS(W, MDW, ME+MG, MA, N+MG, N, PRGOPT, X, RNORML, MODE, * IWORK, WORK) GO TO 820 810 CONTINUE C C SET THE OPTION (NUMBER 2) FOR LSEI( ) TO SCALE THE C COLUMNS OF THE MATRIX TO HAVE UNIT LENGTH. PRGOPT(1) = 4 PRGOPT(2) = 2 PRGOPT(3) = 1 PRGOPT(4) = 1 CALL LSEI(W, MDW, ME, MA, MG, N, PRGOPT, X, RNORME, RNORML, MODE, * WORK, IWORK) 820 CONTINUE C C COMPUTE THE RESIDUAL SUM OF SQUARES OF ERRORS. SOLERR = ZERO I = 1 N20104 = N GO TO 840 830 I = I + 1 840 IF ((N20104-I).LT.0) GO TO 850 X(I) = ONE - X(I) SOLERR = SOLERR + X(I)**2 GO TO 830 850 SOLERR = SQRT(SOLERR) C C TEST SIZE OF ERROR (REF. LAWSON-HANSON, PAGE 51 AND CH. 16) PHI = 100. T = N DXBYX = SOLERR/SQRT(T) RHO = ONE IF (BNORM.NE.ZERO) RHO = RNORML/BNORM GAM = (6*MAX0(MA,N)-3*MIN0(MA,N))*MIN0(MA,N) BETA = CONDA*(ONE+CONDA*RHO)*GAM*PHI IF (.NOT.(DXBYX+BETA.EQ.BETA)) GO TO 860 ISTAT = ISTAT + ICASE GO TO 870 860 CONTINUE IF (MA.EQ.0 .AND. MODE.EQ.0) ISTAT = ISTAT + ICASE 870 CONTINUE IF (.NOT.(ICASE.EQ.1)) GO TO 880 WRITE (LOUT,99997) RNORML 99997 FORMAT (18H0LEAST SQS. RESID., E012.5, 2X, 12HFOR WNNLS( )/ * 30H ERRORS, 1-X(I), FOR WNNLS( ).) WRITE (LOUT,99996) (I,X(I),I=1,N) 99996 FORMAT (4(I4, E012.5)) GO TO 890 880 CONTINUE WRITE (LOUT,99995) RNORML, IWORK(1), IWORK(2) 99995 FORMAT (18H0LEAST SQS. RESID., E012.5, 2X, 11HFOR LSEI( )/ * 41H COMP. RANK OF E, COMP. RANK OF REDUCED A, 2I4/11H ERRORS, 1-, * 18HX(I), FOR LSEI( ).) WRITE (LOUT,99996) (I,X(I),I=1,N) 890 CONTINUE IF (ICASE.EQ.2) RETURN ICASE = 2 GO TO 60 C C PROCEDURE (GET HADAMARD MATRIX) 900 NN = 0 IF (.NOT.(K.GE.0)) GO TO 940 NN = 1 I = 1 N20114 = K GO TO 920 910 I = I + 1 920 IF ((N20114-I).LT.0) GO TO 930 NN = NN + NN GO TO 910 930 GO TO 950 940 NN = 0 GO TO 1080 C C PLACE THE SYMMETRIC HADAMARD MATRIX IN THE ARRAY HH(*,*). 950 HH(1,1) = ONE NN = 1 L = 1 N20118 = K GO TO 970 960 L = L + 1 970 IF ((N20118-L).LT.0) GO TO 1040 J = 1 N20122 = NN GO TO 990 980 J = J + 1 990 IF ((N20122-J).LT.0) GO TO 1000 CALL SCOPY(NN, HH(1,J), 1, HH(NN+1,J), 1) GO TO 980 1000 J = 1 N20126 = NN GO TO 1020 1010 J = J + 1 1020 IF ((N20126-J).LT.0) GO TO 1030 JPNN = J + NN CALL SCOPY(2*NN, HH(1,J), 1, HH(1,JPNN), 1) CALL SSCAL(NN, -ONE, HH(NN+1,JPNN), 1) GO TO 1010 1030 NN = NN + NN GO TO 960 C C MAKE THE MATRIX ORTHOGONAL BY SCALING THE ENTRIES. 1040 T = NN T = ONE/SQRT(T) J = 1 N20130 = NN GO TO 1060 1050 J = J + 1 1060 IF ((N20130-J).LT.0) GO TO 1070 CALL SSCAL(NN, T, HH(1,J), 1) GO TO 1050 1070 CONTINUE 1080 GO TO NGO, (70, 110, 270, 310, 470, 510, 550) END C PROGRAM CLSTST (INPUT,OUTPUT,TAPE5=INPUT,TAPE6=OUTPUT) MAN 10 C MAN 20 C TO CONVERT THE CONSTRAINED LEAST SQUARES PACKAGE OF SUBPROGRAMS MAN 30 C TO DOUBLE PRECISION, FOLLOW THE EDITING INSTRUCTIONS NEAR THE MAN 40 C BEGINNING OF THE FOLLOWING SUBPROGRAMS MAN 50 C LSEI(), LSI(), LPDP(), WNNLS(), WNLSM(), WNLIT(), MAN 60 C HFTI(), H12(), DIFF(), AND THE TESTING SUBPROGRAM CLSTP(). MAN 70 C REVISED 820305-2000 MAN 80 C REVISED YYMMDD-HHMM MAN 90 C MAN 100 C MAN 110 C CHANGE STRING /REAL /DOUBLE PRECISION/, AND MAN 120 C CHANGE STRING /E12/D12/ MAN 130 REAL COND(3) MAN 140 INTEGER KLOG(5) MAN 150 LOGICAL DONE MAN 160 C MAN 170 LIN = 5 MAN 180 LOUT = I1MACH(4) MAN 190 C MAN 200 C MAN 210 C READ IN THE LOGS OF THE VARIOUS DIMENSIONS. MAN 220 10 READ (LIN,99999) (KLOG(I),I=1,5) MAN 230 99999 FORMAT (5I5) MAN 240 DONE = KLOG(5).LT.0 MAN 250 IF (.NOT.(DONE)) GO TO 20 MAN 260 GO TO 30 MAN 270 C MAN 280 C READ THE CONDITION NUMBERS FOR THE THREE MATRICES. MAN 290 20 READ (LIN,99998) (COND(I),I=1,3) MAN 300 99998 FORMAT (3F10.0) MAN 310 C MAN 320 WRITE (LOUT,99997) KLOG, COND MAN 330 99997 FORMAT (/////17H KLOG(*) ARRAY = , 5I5/17H COND(*) ARRAY = , MAN 340 * 3E12.4) MAN 350 C MAN 360 C CALL TESTING SUBPROGRAM TO FORM CONSTRAINED LEAST SQUARES MAN 370 C SYSTEM AND SOLVE IT. MAN 380 CALL CLSTP(KLOG, COND, ISTAT) MAN 390 C MAN 400 WRITE (LOUT,99996) ISTAT MAN 410 99996 FORMAT (/23H FROM CLSTP( ), ISTAT =, I2, 2X, 16H(ISTAT=4 IS GOOD/ MAN 420 * 27X, 24H ISTAT=1,2,3 MAY BE BAD)) MAN 430 C MAN 440 GO TO 10 MAN 450 30 STOP MAN 460 END MAN 470 REAL FUNCTION RAN(K) RAN 10 C C RANDOM NUMBER GENERATOR - BASED ON ALGORITHM 266 C BY PIKE AND HILL (MODIFIED BY HANSSON) C COLLECTED ALG. FROM CACM. C C THIS SUBPROGRAM IS INTENDED FOR USE ON COMPUTERS WITH C FIXED POINT WORDLENGTH OF AT LEAST 29 BITS. IT IS C BEST IF THE FLOATING POINT SIGNIFICAND HAS AT MOST C 29 BITS. C INTEGER IY,K DATA IY/100001/ C IF(K.GT.0) IY = K IY = IY * 125 IY = IY - (IY/2796203) * 2796203 RAN = FLOAT(IY) / 2796203.0E0 RETURN C ---------- LAST CARD OF RAN ---------- END openopt-0.38+svn1589/openopt/solvers/Standalone/toms587_oo.py000066400000000000000000000037451175775750500240630ustar00rootroot00000000000000from numpy.linalg import norm from numpy import dot, asfarray, atleast_1d, zeros, ones, int, float128, float64, where, inf, hstack, vstack, array, ravel from openopt.kernel.baseSolver import baseSolver from toms587 import lsei from openopt.kernel.ooMisc import xBounds2Matrix f = lambda x: norm(dot(p.C, x) - p.d) class toms587(baseSolver): __name__ = 'toms587' __license__ = "BSD" __authors__ = 'R. J. HANSON AND K. H. HASKELL' #__alg__ = '' __info__ = 'requires manual compilation of toms_587.f by f2py, see OO online doc for details' #__optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub'] T = float64 def __init__(self): pass def __solver__(self, p): xBounds2Matrix(p) T = self.T n = p.n #xf = zeros(n, T) xf = zeros(1, T) A, B = T(p.C), T(p.d).reshape(-1, 1) G, H = T(p.A), T(p.b).reshape(-1, 1) E, F = T(p.Aeq), T(p.beq).reshape(-1, 1) me, ma, mg = F.size, B.size, H.size #mdw = me + ma + mg prgopt = ravel(1.0) w = vstack((hstack((E, F)), hstack((A, B)), hstack((G, H)))) mode = -15 rnorme, rnorml = -15.0, -15.0 ip = array((-15, -15, -15)) ws = ravel(-15.0) #bl, bu = p.lb.copy(), p.ub.copy() # bl[where(bl==-inf)[0]] = -self.BVLS_inf # bu[where(bu==inf)[0]] = self.BVLS_inf # if hasattr(bvls, 'boundedleastsquares'):#f90 version # p.debugmsg('using BVLS.f90') # xf,loopa = bvls.boundedleastsquares.bvls(key,a,b,bl,bu,istate) # else: # p.debugmsg('using BVLS.f') # bvls.bvls(key, a, b, bl, bu, xf, w, act, zz, istate, loopa) #lsei(w,me,ma,mg,n,prgopt,xf,rnorme,rnorml,mode,ws,ip,[mdw]) #print w.flatten() lsei(w.flatten(),me,ma,mg,n,prgopt,xf,rnorme,rnorml,mode,ws,ip) #p.iter = loopa ff = atleast_1d(asfarray(f(xf))) p.xf = p.xk = xf p.ff = p.fk = ff p.istop = 1000 openopt-0.38+svn1589/openopt/solvers/Standalone/toms587test.py000066400000000000000000000015031175775750500242540ustar00rootroot00000000000000#from toms587 import lsei #from numpy import * # #W = array([8.94558004, 7.3286058, 3.0, 2.05011463, 0.43314039, 70.31767878, -12.29662251, -13.91359675, 75.74379415]) #me,ma,mg,n,prgopt,xf,rnorme,rnorml,mode,ws,ip = 0, 3, 0, 2, ravel(1.), ravel(0.), -15.0, -15.0, -15, ravel(-15.), ravel((-15, -15, -15)) # #lsei(W,me,ma,mg,n,prgopt,xf,rnorme,rnorml,mode,ws,ip) #StdErr: *** glibc detected *** /usr/bin/python: free(): invalid next size (fast): 0x0000000000cfb390 *** from toms587 import lsei from numpy import * W = array([8.94558004, 7.3286058, 3.0, 2.05011463, 0.43314039, 70.31767878, -12.29662251, -13.91359675, 75.74379415]) me,ma,mg,n,prgopt,xf,rnorme,rnorml,mode,ws,ip = 0, 3, 0, 2, ravel(1.), ravel(0.), -15.0, -15.0, -15, ravel(-15.), array((-15, -15, -15)) lsei(W,me,ma,mg,n,prgopt,xf,rnorme,rnorml,mode,ws,ip) openopt-0.38+svn1589/openopt/solvers/UkrOpt/000077500000000000000000000000001175775750500207115ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/solvers/UkrOpt/Dilation.py000066400000000000000000000027571175775750500230410ustar00rootroot00000000000000from numpy import dot, zeros, float64, diag, ones, ndarray, isfinite, all, asarray from numpy.linalg import norm class Dilation(): def __init__(self, p): self.T = float64 # if hasattr(numpy, 'float128'): # pass # self.T = numpy.float128 self.b = diag(ones(p.n, dtype = self.T)) def getDilatedVector(self, vec): assert type(vec) == ndarray and all(isfinite(vec)) tmp = dot(self.b.T, vec) if any(tmp): tmp /= norm(tmp) return dot(self.b, tmp) def updateDilationMatrix(self, vec, alp=2.0): assert type(vec) == ndarray and all(isfinite(vec)) g = dot(self.b.T, vec) ng = norm(g) # if self.needRej(p, b, g1, g) or selfNeedRej: # selfNeedRej = False # if self.showRej or p.debug: # p.info('debug msg: matrix B restoration in ralg solver') # b = B0.copy() # hs = p.norm(prevIter_best_ls_point.x - best_ls_point.x) # # TODO: iterPoint = projection(iterPoint,Aeq) if res_Aeq > 0.75*contol # if ng < 1e-40: # hs *= 0.9 # p.debugmsg('small dilation direction norm (%e), skipping' % ng) if all(isfinite(g)) and ng > 1e-50: g = (g / ng).reshape(-1,1) vec1 = dot(self.b, g) w = asarray(1.0/alp-1.0, self.T) # w = asarray(1.0/(alp+alp_addition)-1.0, T) vec2 = w * g.T self.b += dot(vec1, vec2) openopt-0.38+svn1589/openopt/solvers/UkrOpt/Dilation2.py000066400000000000000000000372321175775750500231170ustar00rootroot00000000000000from numpy import dot, sign, zeros, all, isfinite, array, sqrt, any, isnan, pi, sin, arccos, inf, argmax, asfarray import numpy from numpy.linalg import norm class DilationUnit(): #vectorNorm = 0 # TODO: remove it? #dilationCoeff = 1.0 maxScalarComponentsLength = 2 def __init__(self, vector, dilationCoeff): #self.vectorDirection = None self.scalarComponents = [] nv = norm(vector) assert nv != 0 #self.vectorDirection, self.vectorNorm, self.dilationCoeff = vector/nv, nv, dilationCoeff self.vectorDirection, self.dilationCoeff = vector/nv, dilationCoeff class Dilation(): #maxUnits = 10 #treshhold = 1.01 th_phi = 0.1 dilationCoeffThreshold = 0.999999 prevRest = None #maxVectorNum = 50 def __init__(self, maxUnitsNum): self.maxUnitsNum = maxUnitsNum self.units = [] self.unitsNum = 0 self.T = numpy.float64 if hasattr(numpy, 'float128'): pass self.T = numpy.float128 def addDilationUnit(self, vector, dilationCoeff = 0.99999): assert all(isfinite(vector)) self.unitsNum += 1 v = self.T(vector.copy()) nv = norm(v) v /= nv # TODO: COMMENT IT OUT # M = 0 # for i, unit in enumerate(self.units): # M = max((M, abs(dot(unit.vectorDirection, v)))) # if M > 1e-2: # print 'warning: max M=', M, 'nv=', nv # return #self.units.add(DilationUnit(vector.copy(), dilationCoeff)) self.units.append(DilationUnit(v, dilationCoeff)) print 'add new dilation vector; curr num: ', len(self.units) def getProjections(self, vv): #assert len(self.units) != 0 V = self.T(vv) NV = norm(V) V /= NV r= [] #print 'norm(V):', norm(V) for unit in self.units: # TODO: try to involve less multiplication ops scalarComponent = dot(unit.vectorDirection, V) # print 'norm(unit.vectorDirection):', norm(unit.vectorDirection) # print 'scalarComponent>>>', scalarComponent component = unit.vectorDirection * scalarComponent#V r.append((scalarComponent, component, unit)) for scalarComponent, component, unit in r: V -= component return r, V#*NV def getDilatedDirection(self, direction): projectionsInfo, rest = self.getProjections(direction) dilatedDirection = zeros(direction.size) for scalarComponent, component, unit in projectionsInfo: dilatedDirection += component * unit.dilationCoeff return projectionsInfo, dilatedDirection+rest def getRestrictedDilatedDirection(self, direction): projectionsInfo, rest = self.getProjections(direction) dilatedDirection = zeros(direction.size) s, ns = [], [] for scalarComponent, component, unit in projectionsInfo: t = component * unit.dilationCoeff s.append(t) ns.append(norm(t)) dilatedDirection += t r = dilatedDirection+rest nr = norm(r) for i in xrange(len(s)): if ns[i] < 1e-10*nr: r += 1e-10*nr*s[i]/ns[i]-s[i] return projectionsInfo, r def getMostInsufficientUnit(self, scalarComponents): assert self.unitsNum != 0 ind, miUnit, miValue = 0, self.units[0], self.units[0].dilationCoeff#abs(scalarComponents[0])*(1-self.units[0].dilationCoeff) for i, unit in enumerate(self.units): #newValue = unit.dilationCoeff*abs(scalarComponents[i]) newValue = unit.dilationCoeff#abs(scalarComponents[i])*(1-unit.dilationCoeff) if newValue > miValue: ind, miUnit, miValue = i, unit, newValue return ind, miUnit def updateDilationCoeffs2(self, scalarComponents, rest): arr_u = array([unit.dilationCoeff for unit in self.units]) if self.unitsNum == 1: self.units[0].dilationCoeff /= 2.0 return m = self.unitsNum n = rest.size #th = norm(rest) * sqrt(n-m) for i, unit in enumerate(self.units): c = unit.dilationCoeff * abs(scalarComponents[i]) / n if c < 0.125: unit.dilationCoeff *= 2.0 elif c > 0.25 : unit.dilationCoeff /= 2.0 print i, unit.dilationCoeff def updateDilationCoeffs(self, scalarComponents, rest): arr_u = array([unit.dilationCoeff for unit in self.units]) # if self.unitsNum == 1: # self.units[0].dilationCoeff /= 2.0 # return Ui2 = arr_u ** 2 UiSCi = abs(array([unit.dilationCoeff*scalarComponents[i] for i, unit in enumerate(self.units)])) Ui2SCi2 = array(UiSCi) ** 2 S, S2 = sum(Ui2), sum(Ui2SCi2) SCi = abs(array(scalarComponents)) SCi2 = SCi ** 2 alp = 2.0 beta = 1.0 / alp #k = sqrt(S2 / (alp*sum((1.0-UiSCi)**2 * UiSCi2))) #rr = k * sqrt(1.0-UiSCi)**2 m, n = self.unitsNum, rest.size b = abs(beta) #b = min((abs(beta), m/(16*n*sqrt(sum(UiSCi))))) #b = m/(n*sqrt(sum(UiSCi))) nr2 = norm(rest) ** 2 k = b*sqrt(S2 / sum(Ui2SCi2*(1.0-UiSCi))) #k = sqrt(((b2-1)*nr2 + b2 * S2) / sum(Ui2SCi2*(1.0-UiSCi))) # k1 = sqrt(b2 * S2 / sum(Ui2SCi2*(1.0-UiSCi))) # m, n = self.unitsNum, rest.size # rr1 = k1 * (1-UiSCi) # u1 = rr1 * arr_u rr = k * (1-UiSCi) assert k > 0 #k = sqrt(S2 / (alp*sum((1.0-SCi)**2 * Ui2SCi2))) #rr = k * sqrt(1.0-SCi)**2 rr[rr>4.0] = 4.0 rr[rr<0.25] = 0.25 r = rr * arr_u #r[r<1e-20] = 1e-20 assert len(r) == self.unitsNum == len(self.units) #print '--------------------' for i, unit in enumerate(self.units): unit.dilationCoeff = r[i] print 'nU=%d k=%0.1g r_min=%0.1g r_max=%0.1g' % (self.unitsNum, k, min(r), max(r)) #print r #print i, unit.dilationCoeff # print 'old sum:', S2,'new sum:', sum(array([unit.dilationCoeff*scalarComponents[i] for i, unit in enumerate(self.units)])**2) # print '=====================' def _updateDilationInfo(self, _dilationDirection_, ls, _moveDirection_): r = {'increased':0, 'decreased':0} #projectionsInfo, dilatedDirectionComponent, rest = self.getDilatedDirection(_moveDirection_) projectionsInfo, rest = self.getProjections(_dilationDirection_) # for scalarComponent, component, unit in projectionsInfo1: # scs = unit.scalarComponents # if len(scs) >= unit.maxScalarComponentsLength: # scs.pop(0) # scs.append(scalarComponent) print 'norm(rest1):', norm(rest) #cond_add = norm(rest1) > 1e-2 s = abs(asfarray([scalarComponent for (scalarComponent, component, unit) in projectionsInfo])) #cond_add = self.unitsNum == 0 or any(norm(rest1) > 64.0*asfarray([unit.dilationCoeff * s[i] for i, unit in enumerate(self.units)])) cond_add = norm(rest) > 1e-3 #or (self.prevRest is not None and dot(self.prevRest, rest1) <= 0) if cond_add: self.addDilationUnit(rest) projectionsInfo, rest = self.getProjections(_dilationDirection_) print 'norm(rest11):', norm(rest) #print '!>', dot(dilatedDirectionComponent1, rest1) / norm(dilatedDirectionComponent1) / norm(rest1) #print '!!>', dilatedDirectionComponent1, rest1 #assert norm(dilatedDirectionComponent1) > 1e-10 # mostUnusefulUnitNumber = -1 # mostUnusefulUnitCoeff = -1 # for i, u in enumerate(self.units): # if u.dilationCoeff > mostUnusefulUnitCoeff: # mostUnusefulUnitNumber, mostUnusefulUnitCoeff = i, u.dilationCoeff #print 'norm(_dilationDirection_) :', norm(_dilationDirection_) #s = norm(rest1) / norm(dilatedDirectionComponent1) #print 's:', s scalarComponents = [scalarComponent for (scalarComponent, component, unit) in projectionsInfo] #print argmax(scalarComponents) #m = len(self.units) #n = _dilationDirection_.size #print 'norm(rest1), norm(scalarComponents, inf):', norm(rest1) , norm(scalarComponents, inf) #print '' #condReasonableBigRest = self.unitsNum == 0 or norm(rest1) > norm(scalarComponents, inf)#miUnit.dilationCoeff* abs(scalarComponents[ind_mi]) # s > 0.05 #print 'norm(rest1):', norm(rest1), 'miUnit.dilationCoeff:', miUnit.dilationCoeff, 'miUnit.sc:', scalarComponents[ind_mi] #if 1 or norm(rest1) > 0.9: #print '>', rest1/norm(rest1), norm(rest1), [Unit.dilationCoeff for Unit in self.units], [Unit.vectorDirection for Unit in self.units] #and self.prevRest is not None and (True or dot(self.prevRest, rest) <= 0) #projectionsInfo2, dilatedDirectionComponent2, rest2 = self.getDilatedDirection( dilatedDirectionComponent1 + rest1) #assert norm(dilatedDirectionComponent2) > 1e-10 #projectionsInfo3, dilatedDirectionComponent, rest = self.getDilatedDirection( dilatedDirectionComponent + rest) #print 'norm(r1), norm(d1):', norm(rest1), norm(dilatedDirectionComponent1) #abs_tan_phi = norm(rest1) / norm(dilatedDirectionComponent1) #projectionsInfo, dilatedDirectionComponent, rest = projectionsInfo2, dilatedDirectionComponent2, rest2 #print 'norm(r2), norm(d2):', norm(rest2), norm(dilatedDirectionComponent2) #cond_drift = self.prevRest is not None and dot(self.prevRest, rest1) > 0 # TODO: what if self.prevRest is None? #haveToAdd = condReasonableBigRest and any(rest1!=0) #and not cond_drift self.updateDilationCoeffs(scalarComponents, rest) self.prevRest = rest.copy() #print 'self.unitsNum, self.maxUnitsNum:', self.unitsNum, self.maxUnitsNum if self.unitsNum >= self.maxUnitsNum: self.unitsNum = 0 self.units = [] # ind_mi, miUnit = self.getMostInsufficientUnit(scalarComponents) # self.units.pop(ind_mi) # self.unitsNum -= 1 # for unit in self.units: # unit.dilationCoeff /= miUnit.dilationCoeff #print 'mi removed:', ind_mi nRemoved = self.cleanUnnessesaryDilationUnits() if nRemoved: print 'nRemoved:', nRemoved return r #d = 1.0 #projectionsInfo, dilatedDirectionComponent, rest = self.getDilatedDirection(_dilationDirection_) # for scalarComponent, component, unit in projectionsInfo: # # angle between ort and dilation direction # angle = arccos(scalarComponent) # values from 0 to pi # if angle > pi/2: angle = pi - angle # if d < 1.0: # unit.dilationCoeff *= max((0.5, sin(d*angle))) # elif d > 1.0: # unit.dilationCoeff *= max((2.0, d/sqrt(1-scalarComponent**2))) # # if cond_overdilated: # #TODO - omit repeated calculations # nRemoved = self.cleanUnnessesaryDilationUnits() # print 'REMOVED: ', nRemoved#, 'increaseMultiplier:', increaseMultiplier # if sign(dot(_moveDirection_, component)) == sign(scalarComponent): # #print 'case 1' # unit.dilationCoeff *= multiplier # if unit.dilationCoeff > 1.0: unit.dilationCoeff = 1.0 # else: # reduceMultiplier = max((0.5, sqrt(1 - scalarComponent**2))) # unit.dilationCoeff *= reduceMultiplier #unit.dilationCoeff /= 2.0#multiplier #print 'case 2' # #cond_overDilated = abs_tan_phi > 0.5#min((2.0, 1.0 / self.th_phi)) # if abs_tan_phi < self.th_phi: #abs_tan_phi < 0.1 * len(self.units) / (_dilationDirection_.size-len(self.units)): # koeff = 0.5 # for scalarComponent, component, unit in projectionsInfo: # unit.dilationCoeff *= koeff * max((0.1, sqrt(1 - scalarComponent**2))) # #elif cond_overDilated: # TODO: use separate parameter instead of (1.0 / self.th_phi) # else: # #elif abs_tan_phi > # multiplier = self.th_phi / abs_tan_phi # if multiplier > 2.0: multiplier = 2.0 # elif multiplier < 1.3: multiplier = 1.3 # for scalarComponent, component, unit in projectionsInfo: # if sign(dot(_moveDirection_, component)) == sign(scalarComponent): # unit.dilationCoeff *= multiplier # #pass # for scalarComponent, component, unit in projectionsInfo: # pass #reduceMultiplier = max((0.25, sqrt(1 - scalarComponent**2))) #unit.dilationCoeff *= reduceMultiplier ########################################## # get NEW rest # TODO - omit repeated calculations #projectionsInfo, dilatedDirectionComponent, rest = self.getDilatedDirection(_dilationDirection_) ########################################## #if self.prevRest is not None:print 'sign dot:', sign(dot(self.prevRest, rest)) #print 'norm(rest) / norm(dilatedDirectionComponent:', norm(rest)/ norm(dilatedDirectionComponent) #haveToAdd = True def cleanUnnessesaryDilationUnits(self): indUnitsToRemove = [] for i, unit in enumerate(self.units): if unit.dilationCoeff > self.dilationCoeffThreshold: print '>>', unit.dilationCoeff , self.dilationCoeffThreshold indUnitsToRemove.append(i) #unitsToRemove.add(unit) for j in xrange(len(indUnitsToRemove)): self.units.pop(indUnitsToRemove[-1-j]) nRemoved = len(indUnitsToRemove) self.unitsNum -= nRemoved #if nRemoved!=0: print 'dilation units: removed = %d left=%d' % (nRemoved, len(self.units)) return nRemoved # def cleanUnnessesaryDilationUnits(self): # unitsToRemove = set() # for unit in self.units: # if unit.dilationCoeff >= self.treshhold: # unitsToRemove.add(unit) # self.units = self.units.difference(unitsToRemove) # def updateDilationInfo(self, projectionsInfo, ls): # r = {'increased':0, 'decreased':0} # # for scalarComponent, component, unit in projectionsInfo: # scs = unit.scalarComponents # if len(scs) >= unit.maxScalarComponentsLength: # scs.pop(0) # scs.append(scalarComponent) # signs = sign(scs) # # #cond_1 = norm(unit.vectorDirection - array([1.0]+[0]*(unit.vectorDirection.size-1)))<1e-4 # #cond_1 = any(unit.vectorDirection[:10]==1) # # # TODO: remove cycles # # if len(signs)>1: # TODO: handle signs[-1-i] == 0 case # if ls <= 1: # if signs[-1] == signs[-2]: # pass # else: # unit.dilationCoeff /= 2.0 # r['decreased'] += 1 # elif ls > 1: # if signs[-1] == signs[-2]: # unit.dilationCoeff *= 1 + 0.1#ls/3.0 # r['increased'] += 1 # else: # pass # return r openopt-0.38+svn1589/openopt/solvers/UkrOpt/Dilation3.py000066400000000000000000000367471175775750500231320ustar00rootroot00000000000000from numpy import dot, sign, zeros, all, isfinite, array, sqrt, any, isnan, pi, sin, arccos, inf, argmax, asfarray import numpy from numpy.linalg import norm class DilationUnit(): #vectorNorm = 0 # TODO: remove it? #dilationCoeff = 1.0 maxScalarComponentsLength = 2 def __init__(self, vector, dilationCoeff): #self.vectorDirection = None self.scalarComponents = [] nv = norm(vector) assert nv != 0 #self.vectorDirection, self.vectorNorm, self.dilationCoeff = vector/nv, nv, dilationCoeff self.vectorDirection, self.dilationCoeff = vector/nv, dilationCoeff class Dilation(): #maxUnits = 10 #treshhold = 1.01 th_phi = 0.1 dilationCoeffThreshold = 0.999999 prevRest = None #maxVectorNum = 50 def __init__(self, maxUnitsNum): self.maxUnitsNum = maxUnitsNum self.units = [] self.unitsNum = 0 self.T = numpy.float64 if hasattr(numpy, 'float128'): pass self.T = numpy.float128 def addDilationUnit(self, vector, dilationCoeff = 0.99999): assert all(isfinite(vector)) self.unitsNum += 1 v = self.T(vector.copy()) nv = norm(v) v /= nv # TODO: COMMENT IT OUT # M = 0 # for i, unit in enumerate(self.units): # M = max((M, abs(dot(unit.vectorDirection, v)))) # if M > 1e-2: # print 'warning: max M=', M, 'nv=', nv # return #self.units.add(DilationUnit(vector.copy(), dilationCoeff)) self.units.append(DilationUnit(v, dilationCoeff)) print 'add new dilation vector; curr num: ', len(self.units) def getProjections(self, vv): #assert len(self.units) != 0 V = self.T(vv) NV = norm(V) V /= NV r= [] #print 'norm(V):', norm(V) for unit in self.units: # TODO: try to involve less multiplication ops scalarComponent = dot(unit.vectorDirection, V) # print 'norm(unit.vectorDirection):', norm(unit.vectorDirection) # print 'scalarComponent>>>', scalarComponent component = unit.vectorDirection * scalarComponent#V r.append((scalarComponent, component, unit)) for scalarComponent, component, unit in r: V -= component return r, V#*NV def getDilatedDirection(self, direction): projectionsInfo, rest = self.getProjections(direction) dilatedDirection = zeros(direction.size) for scalarComponent, component, unit in projectionsInfo: dilatedDirection += component * unit.dilationCoeff return projectionsInfo, dilatedDirection+rest def getRestrictedDilatedDirection(self, direction): projectionsInfo, rest = self.getProjections(direction) dilatedDirection = zeros(direction.size) s, ns = [], [] for scalarComponent, component, unit in projectionsInfo: t = component * unit.dilationCoeff s.append(t) ns.append(norm(t)) dilatedDirection += t r = dilatedDirection+rest nr = norm(r) for i in xrange(len(s)): if ns[i] < 1e-10*nr: r += 1e-10*nr*s[i]/ns[i]-s[i] return projectionsInfo, r def getMostInsufficientUnit(self, scalarComponents): assert self.unitsNum != 0 ind, miUnit, miValue = 0, self.units[0], self.units[0].dilationCoeff#abs(scalarComponents[0])*(1-self.units[0].dilationCoeff) for i, unit in enumerate(self.units): #newValue = unit.dilationCoeff*abs(scalarComponents[i]) newValue = unit.dilationCoeff#abs(scalarComponents[i])*(1-unit.dilationCoeff) if newValue > miValue: ind, miUnit, miValue = i, unit, newValue return ind, miUnit def updateDilationCoeffs2(self, scalarComponents, rest): arr_u = array([unit.dilationCoeff for unit in self.units]) if self.unitsNum == 1: self.units[0].dilationCoeff /= 2.0 return m = self.unitsNum n = rest.size #th = norm(rest) * sqrt(n-m) for i, unit in enumerate(self.units): c = unit.dilationCoeff * abs(scalarComponents[i]) / n if c < 0.125: unit.dilationCoeff *= 2.0 elif c > 0.25 : unit.dilationCoeff /= 2.0 print i, unit.dilationCoeff def updateDilationCoeffs(self, scalarComponents, rest): arr_u = array([unit.dilationCoeff for unit in self.units]) # if self.unitsNum == 1: # self.units[0].dilationCoeff /= 2.0 # return Ui2 = arr_u ** 2 UiSCi = abs(array([unit.dilationCoeff*scalarComponents[i] for i, unit in enumerate(self.units)])) Ui2SCi2 = array(UiSCi) ** 2 S, S2 = sum(Ui2), sum(Ui2SCi2) SCi = abs(array(scalarComponents)) SCi2 = SCi ** 2 alp = 2.0 beta = 1.0 / alp #k = sqrt(S2 / (alp*sum((1.0-UiSCi)**2 * UiSCi2))) #rr = k * sqrt(1.0-UiSCi)**2 m, n = self.unitsNum, rest.size b = abs(beta) #b = min((abs(beta), m/(16*n*sqrt(sum(UiSCi))))) #b = m/(n*sqrt(sum(UiSCi))) nr2 = norm(rest) ** 2 k = b*sqrt(S2 / sum(Ui2SCi2*(1.0-UiSCi))) #k = sqrt(((b2-1)*nr2 + b2 * S2) / sum(Ui2SCi2*(1.0-UiSCi))) # k1 = sqrt(b2 * S2 / sum(Ui2SCi2*(1.0-UiSCi))) # m, n = self.unitsNum, rest.size # rr1 = k1 * (1-UiSCi) # u1 = rr1 * arr_u rr = k * (1-UiSCi) assert k > 0 #k = sqrt(S2 / (alp*sum((1.0-SCi)**2 * Ui2SCi2))) #rr = k * sqrt(1.0-SCi)**2 rr[rr>4.0] = 4.0 rr[rr<0.25] = 0.25 r = rr * arr_u #r[r<1e-20] = 1e-20 assert len(r) == self.unitsNum == len(self.units) #print '--------------------' for i, unit in enumerate(self.units): unit.dilationCoeff = r[i] print 'nU=%d k=%0.1g r_min=%0.1g r_max=%0.1g' % (self.unitsNum, k, min(r), max(r)) #print r #print i, unit.dilationCoeff # print 'old sum:', S2,'new sum:', sum(array([unit.dilationCoeff*scalarComponents[i] for i, unit in enumerate(self.units)])**2) # print '=====================' def _updateDilationInfo(self, _dilationDirection_, ls, _moveDirection_): r = {'increased':0, 'decreased':0} #projectionsInfo, dilatedDirectionComponent, rest = self.getDilatedDirection(_moveDirection_) projectionsInfo1, rest1 = self.getProjections(_dilationDirection_) print 'norm(rest1):', norm(rest1) #cond_add = norm(rest1) > 1e-2 s = abs(asfarray([scalarComponent for (scalarComponent, component, unit) in projectionsInfo1])) #cond_add = self.unitsNum == 0 or any(norm(rest1) > 64.0*asfarray([unit.dilationCoeff * s[i] for i, unit in enumerate(self.units)])) cond_add = norm(rest1) > 1e-3 #or (self.prevRest is not None and dot(self.prevRest, rest1) <= 0) if cond_add: self.addDilationUnit(rest1) projectionsInfo1, rest1 = self.getProjections(_dilationDirection_) print 'norm(rest11):', norm(rest1) #print '!>', dot(dilatedDirectionComponent1, rest1) / norm(dilatedDirectionComponent1) / norm(rest1) #print '!!>', dilatedDirectionComponent1, rest1 #assert norm(dilatedDirectionComponent1) > 1e-10 # mostUnusefulUnitNumber = -1 # mostUnusefulUnitCoeff = -1 # for i, u in enumerate(self.units): # if u.dilationCoeff > mostUnusefulUnitCoeff: # mostUnusefulUnitNumber, mostUnusefulUnitCoeff = i, u.dilationCoeff #print 'norm(_dilationDirection_) :', norm(_dilationDirection_) #s = norm(rest1) / norm(dilatedDirectionComponent1) #print 's:', s scalarComponents = [scalarComponent for (scalarComponent, component, unit) in projectionsInfo1] #print argmax(scalarComponents) #m = len(self.units) #n = _dilationDirection_.size #print 'norm(rest1), norm(scalarComponents, inf):', norm(rest1) , norm(scalarComponents, inf) #print '' #condReasonableBigRest = self.unitsNum == 0 or norm(rest1) > norm(scalarComponents, inf)#miUnit.dilationCoeff* abs(scalarComponents[ind_mi]) # s > 0.05 #print 'norm(rest1):', norm(rest1), 'miUnit.dilationCoeff:', miUnit.dilationCoeff, 'miUnit.sc:', scalarComponents[ind_mi] #if 1 or norm(rest1) > 0.9: #print '>', rest1/norm(rest1), norm(rest1), [Unit.dilationCoeff for Unit in self.units], [Unit.vectorDirection for Unit in self.units] #and self.prevRest is not None and (True or dot(self.prevRest, rest) <= 0) #projectionsInfo2, dilatedDirectionComponent2, rest2 = self.getDilatedDirection( dilatedDirectionComponent1 + rest1) #assert norm(dilatedDirectionComponent2) > 1e-10 #projectionsInfo3, dilatedDirectionComponent, rest = self.getDilatedDirection( dilatedDirectionComponent + rest) projectionsInfo, rest = projectionsInfo1, rest1 #print 'norm(r1), norm(d1):', norm(rest1), norm(dilatedDirectionComponent1) #abs_tan_phi = norm(rest1) / norm(dilatedDirectionComponent1) #projectionsInfo, dilatedDirectionComponent, rest = projectionsInfo2, dilatedDirectionComponent2, rest2 #print 'norm(r2), norm(d2):', norm(rest2), norm(dilatedDirectionComponent2) #cond_drift = self.prevRest is not None and dot(self.prevRest, rest1) > 0 # TODO: what if self.prevRest is None? #haveToAdd = condReasonableBigRest and any(rest1!=0) #and not cond_drift self.updateDilationCoeffs(scalarComponents, rest) self.prevRest = rest.copy() #print 'self.unitsNum, self.maxUnitsNum:', self.unitsNum, self.maxUnitsNum if self.unitsNum >= self.maxUnitsNum: self.unitsNum = 0 self.units = [] # ind_mi, miUnit = self.getMostInsufficientUnit(scalarComponents) # self.units.pop(ind_mi) # self.unitsNum -= 1 # for unit in self.units: # unit.dilationCoeff /= miUnit.dilationCoeff #print 'mi removed:', ind_mi nRemoved = self.cleanUnnessesaryDilationUnits() if nRemoved: print 'nRemoved:', nRemoved return r #d = 1.0 #projectionsInfo, dilatedDirectionComponent, rest = self.getDilatedDirection(_dilationDirection_) # for scalarComponent, component, unit in projectionsInfo: # # angle between ort and dilation direction # angle = arccos(scalarComponent) # values from 0 to pi # if angle > pi/2: angle = pi - angle # if d < 1.0: # unit.dilationCoeff *= max((0.5, sin(d*angle))) # elif d > 1.0: # unit.dilationCoeff *= max((2.0, d/sqrt(1-scalarComponent**2))) # # if cond_overdilated: # #TODO - omit repeated calculations # nRemoved = self.cleanUnnessesaryDilationUnits() # print 'REMOVED: ', nRemoved#, 'increaseMultiplier:', increaseMultiplier # if sign(dot(_moveDirection_, component)) == sign(scalarComponent): # #print 'case 1' # unit.dilationCoeff *= multiplier # if unit.dilationCoeff > 1.0: unit.dilationCoeff = 1.0 # else: # reduceMultiplier = max((0.5, sqrt(1 - scalarComponent**2))) # unit.dilationCoeff *= reduceMultiplier #unit.dilationCoeff /= 2.0#multiplier #print 'case 2' # #cond_overDilated = abs_tan_phi > 0.5#min((2.0, 1.0 / self.th_phi)) # if abs_tan_phi < self.th_phi: #abs_tan_phi < 0.1 * len(self.units) / (_dilationDirection_.size-len(self.units)): # koeff = 0.5 # for scalarComponent, component, unit in projectionsInfo: # unit.dilationCoeff *= koeff * max((0.1, sqrt(1 - scalarComponent**2))) # #elif cond_overDilated: # TODO: use separate parameter instead of (1.0 / self.th_phi) # else: # #elif abs_tan_phi > # multiplier = self.th_phi / abs_tan_phi # if multiplier > 2.0: multiplier = 2.0 # elif multiplier < 1.3: multiplier = 1.3 # for scalarComponent, component, unit in projectionsInfo: # if sign(dot(_moveDirection_, component)) == sign(scalarComponent): # unit.dilationCoeff *= multiplier # #pass # for scalarComponent, component, unit in projectionsInfo: # pass #reduceMultiplier = max((0.25, sqrt(1 - scalarComponent**2))) #unit.dilationCoeff *= reduceMultiplier ########################################## # get NEW rest # TODO - omit repeated calculations #projectionsInfo, dilatedDirectionComponent, rest = self.getDilatedDirection(_dilationDirection_) ########################################## #if self.prevRest is not None:print 'sign dot:', sign(dot(self.prevRest, rest)) #print 'norm(rest) / norm(dilatedDirectionComponent:', norm(rest)/ norm(dilatedDirectionComponent) #haveToAdd = True def cleanUnnessesaryDilationUnits(self): indUnitsToRemove = [] for i, unit in enumerate(self.units): if unit.dilationCoeff > self.dilationCoeffThreshold: print '>>', unit.dilationCoeff , self.dilationCoeffThreshold indUnitsToRemove.append(i) #unitsToRemove.add(unit) for j in xrange(len(indUnitsToRemove)): self.units.pop(indUnitsToRemove[-1-j]) nRemoved = len(indUnitsToRemove) self.unitsNum -= nRemoved #if nRemoved!=0: print 'dilation units: removed = %d left=%d' % (nRemoved, len(self.units)) return nRemoved # def cleanUnnessesaryDilationUnits(self): # unitsToRemove = set() # for unit in self.units: # if unit.dilationCoeff >= self.treshhold: # unitsToRemove.add(unit) # self.units = self.units.difference(unitsToRemove) # def updateDilationInfo(self, projectionsInfo, ls): # r = {'increased':0, 'decreased':0} # # for scalarComponent, component, unit in projectionsInfo: # scs = unit.scalarComponents # if len(scs) >= unit.maxScalarComponentsLength: # scs.pop(0) # scs.append(scalarComponent) # signs = sign(scs) # # #cond_1 = norm(unit.vectorDirection - array([1.0]+[0]*(unit.vectorDirection.size-1)))<1e-4 # #cond_1 = any(unit.vectorDirection[:10]==1) # # # TODO: remove cycles # # if len(signs)>1: # TODO: handle signs[-1-i] == 0 case # if ls <= 1: # if signs[-1] == signs[-2]: # pass # else: # unit.dilationCoeff /= 2.0 # r['decreased'] += 1 # elif ls > 1: # if signs[-1] == signs[-2]: # unit.dilationCoeff *= 1 + 0.1#ls/3.0 # r['increased'] += 1 # else: # pass # return r openopt-0.38+svn1589/openopt/solvers/UkrOpt/PolytopProjection.py000066400000000000000000000016341175775750500247720ustar00rootroot00000000000000from openopt import QP from numpy import dot, asfarray, ones, zeros, max from numpy.linalg import norm def PolytopProjection(data, T = 1.0, isProduct = False, solver = None): if solver is None: solver = 'cvxopt_qp' #data = float128(data) if isProduct: H = data n = data.shape[0] m = len(T) else: H = dot(data, data.T) n, m = data.shape #print H.shape #print 'PolytopProjection: n=%d, m=%d, H.shape[0]= %d, H.shape[1]= %d ' %(n, m, H.shape[0], H.shape[1]) #T = abs(dot(H, ones(n))) f = -asfarray(T) *ones(n) p = QP(H, f, lb = zeros(n), iprint = -1, maxIter = 150) xtol = 1e-6 if max(T) < 1e5*xtol: xtol = max(T)/1e5 r = p._solve(solver, ftol = 1e-16, xtol = xtol, maxIter = 10000) sol = r.xf if isProduct: return r.xf else: s = dot(data.T, r.xf) return s.flatten(), r.xf openopt-0.38+svn1589/openopt/solvers/UkrOpt/ShorEllipsoid_oo.py000066400000000000000000000047601175775750500245470ustar00rootroot00000000000000if __name__ == '__main__': import sys, os.path as pth sys.path.insert(0,pth.split(pth.split(pth.split(pth.split(pth.realpath(pth.dirname(__file__)))[0])[0])[0])[0]) from openopt import NSP from numpy import ones, arange N = 4 p = NSP(lambda x: abs(x).sum(), ones([N,1]), maxFunEvals = 1e6, plot = False) p.r0 = N r = p.solve('ShorEllipsoid') from numpy import diag, ones, inf, any, copy, sqrt from openopt.kernel.baseSolver import baseSolver class ShorEllipsoid(baseSolver): __name__ = 'ShorEllipsoid' __license__ = "BSD" __authors__ = "Dmitrey" __alg__ = "Naum Z. Shor modificated method of ellipsoids" iterfcnConnected = True #__optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] def __init__(self): pass def __solver__(self, p): #if p.useScaling: p.err('ShorEllipsoid + scaling isn''t implemented yet') n = p.n B = diag(ones(n)) x0 = copy(p.x0) ######################## # Shor MME engine # # //by Dmitrey Kroshko # # //icq 275976670(inviz) # ######################## x = x0.copy() xPrev = x0.copy() xf = x0.copy() xk = x0.copy() p.xk = x0.copy() if not hasattr(p, 'r0'): p.err('ShorEllipsoid solver requires r0') r = p.r0 f = p.f(x) fk = f ff = f p.fk = fk g = p.df(x) p._df = g p.iterfcn() if p.istop: p.xf = x p.ff = f #r.advanced.ralg.hs = hs return multiplier_R = sqrt(1.+1./n**2) beta = multiplier_R - 1. / n alfa = 1. / beta for k in range(p.maxIter): BTG = p.matmult(B.T, g.reshape(-1,1)) dzeta_k = (BTG / p.norm(BTG)) hk = r*beta/n x -= hk * p.matmult(B, dzeta_k).flatten() B += p.matmult(B, p.matmult((1-alfa)*dzeta_k, dzeta_k.T)) r *= multiplier_R f = p.f(x) g = p.df(x) xk = x.copy() fk = f if fk < ff: ff, xf = fk, xk.copy() p.fk = fk p.xk = xk p._df = g#CHECK ME! - MODIFIED!! p.iterfcn() if p.istop: p.xf = xf p.ff = ff #p.advanced.ralg.hs = max(norm(xPrev - x), hsmin) p._df = g return openopt-0.38+svn1589/openopt/solvers/UkrOpt/UkrOptMisc.py000066400000000000000000000171501175775750500233270ustar00rootroot00000000000000from numpy import concatenate, vstack, hstack, inf, ones, zeros, diag, dot, abs, where, max, min from openopt import NLP, LLSP from openopt.kernel.ooMisc import norm from openopt.kernel.setDefaultIterFuncs import IS_MAX_ITER_REACHED funcDirectionValue = lambda alpha, func, x, direction: func(x+alpha*direction) def funcDirectionValueWithMaxConstraintLimit(alpha, func, x, direction, maxConstrLimit, p): xx = x+alpha*direction mc = p.getMaxResidual(xx) if mc > maxConstrLimit: return 1e150 * mc else: return func(xx) # cond1 = not(p_LS is None) and hasattr(p_LS, 'xPrevF') and alpha1 == p_LS.xPrevF # # if cond1: # constr1 = p.getMaxResidual(x+alpha1*direction) # constr2 = p.getMaxResidual(x+alpha2*direction) # else: # constr2 = p.getMaxResidual(x+alpha2*direction) # constr1 = p.getMaxResidual(x+alpha1*direction) # if constr2 > constr1 and constr2 > maxConstrLimit: return True # elif constr1 > constr2 and constr1 > maxConstrLimit: return False # # if cond1: # f1 = p.f(x+alpha1*direction) # f2 = p.f(x+alpha2*direction) # else: # f2 = p.f(x+alpha2*direction) # f1 = p.f(x+alpha1*direction) # if f1 < f2: return True # else: return False def getConstrDirection(p, x, regularization = 1e-7): c, dc, h, dh, df = p.c(x), p.dc(x), p.h(x), p.dh(x), p.df(x) A, Aeq = vstack((dc, p.A)), vstack((dh, p.Aeq)) b = concatenate((-c, p.b-p.matmult(p.A,x))) beq = concatenate((-h, p.beq-p.matmult(p.Aeq,x))) lb = p.lb - x ub = p.ub - x nC = b.size #TODO: USE if nC == 0 instead if A.size == 0: A_LLS = hstack((zeros((nC, p.n)), diag(ones(nC)))) else: A_LLS = hstack((A, diag(ones(nC)))) if Aeq.size == 0: Awhole_LLS = vstack((A_LLS, hstack((diag(regularization*ones(p.n)), zeros((p.n, nC)))))) else: Aeq_LLS = hstack((Aeq, zeros((beq.size, nC)))) Awhole_LLS = vstack((Aeq_LLS, A_LLS, hstack((diag(regularization*ones(p.n)), zeros((p.n, nC)))))) if p.getMaxResidual(x) > p.contol: dump_x = -p.getMaxConstrGradient(x) else: dump_x = -df bwhole_LLS = concatenate((beq, b, dump_x)) lb_LLS = hstack((lb, zeros(nC))) ub_LLS = hstack((ub, inf*ones(nC))) p_sp = LLSP(Awhole_LLS, bwhole_LLS, lb = lb_LLS, ub = ub_LLS, iprint = -1) r_sp = p_sp.solve('BVLS', BVLS_inf=1e30) return r_sp.xf[:p.n] class DirectionOptimPoint: def __init__(self): pass def getDirectionOptimPoint(p, func, x, direction, forwardMultiplier = 2.0, maxiter = 150, xtol = None, maxConstrLimit = None, \ alpha_lb = 0, alpha_ub = inf, \ rightLocalization = 0, leftLocalization = 0, \ rightBorderForLocalization = 0, leftBorderForLocalization = None): if all(direction==0): p.err('nonzero direction is required') if maxConstrLimit is None: lsFunc = funcDirectionValue args = (func, x, direction) else: lsFunc = funcDirectionValueWithMaxConstraintLimit args = (func, x, direction, maxConstrLimit, p) prev_alpha, new_alpha = alpha_lb, min(alpha_lb+0.5, alpha_ub) prev_val = lsFunc(prev_alpha, *args) for i in range(p.maxLineSearch): if lsFunc(new_alpha, *args)>prev_val or new_alpha==alpha_ub: break else: if i != 0: prev_alpha = min(alpha_lb, new_alpha) new_alpha *= forwardMultiplier if i == p.maxLineSearch-1: p.debugmsg('getDirectionOptimPoint: maxLineSearch is exeeded') lb, ub = prev_alpha, new_alpha if xtol is None: xtol = p.xtol / 2.0 # NB! goldenSection solver ignores x0 p_LS = NLP(lsFunc, x0=0, lb = lb, ub = ub, iprint = -1, \ args=args, xtol = xtol, maxIter = maxiter, contol = p.contol)# contol is used in funcDirectionValueWithMaxConstraintLimit r = p_LS.solve('goldenSection', useOOiterfcn=False, rightLocalization=rightLocalization, leftLocalization=leftLocalization, rightBorderForLocalization=rightBorderForLocalization, leftBorderForLocalization=leftBorderForLocalization) if r.istop == IS_MAX_ITER_REACHED: p.warn('getDirectionOptimPoint: max iter has been exceeded') alpha_opt = r.special.rightXOptBorder R = DirectionOptimPoint() R.leftAlphaOptBorder = r.special.leftXOptBorder R.leftXOptBorder = x + R.leftAlphaOptBorder * direction R.rightAlphaOptBorder = r.special.rightXOptBorder R.rightXOptBorder = x + R.rightAlphaOptBorder * direction R.x = x + alpha_opt * direction R.alpha = alpha_opt R.evalsF = r.evals['f']+i return R from numpy import arccos def getAltitudeDirection(p, pointTop, point2, point3): b = point2 - pointTop c = point3 - pointTop alpha = dot(c, c-b) / norm(c-b)**2 h = alpha * b + (1-alpha) * c abh = arccos(dot(h, b)/norm(h) /norm(b)) ach = arccos(dot(h, c)/norm(h) /norm(c)) abc = arccos(dot(b, c)/norm(b) /norm(c)) #ahbc = arccos(dot(h, b-c)/norm(h) /norm(b-c)) isInsideTriangle = abh+ach-abc<=1e-8 return h, isInsideTriangle from openopt.kernel.setDefaultIterFuncs import IS_LINE_SEARCH_FAILED from openopt.kernel.ooMisc import isSolved def getBestPointAfterTurn(oldPoint, newPoint, altLinInEq=None, maxLS = 3, maxDeltaX = None, maxDeltaF = None, sf = None, \ hs=None, new_bs = True, checkTurnByGradient = False): assert altLinInEq is not None p = oldPoint.p contol = p.contol altPoint = oldPoint.linePoint(0.5, newPoint) if maxLS is None: maxLS = p.maxLineSearch assert maxLS != 0 if maxDeltaX is None: if p.iter != 0: maxDeltaX = 1.5e4*p.xtol else: maxDeltaX = 1.5e1*p.xtol if maxDeltaF is None: maxDeltaF = 150*p.ftol prev_prev_point = newPoint if checkTurnByGradient: direction = newPoint.x-oldPoint.x condNotBetter = lambda altPoint, prevPoint: dot(prevPoint._getDirection(p.solver.approach), direction) <= 0.0 dType = 1 else: condNotBetter = lambda altPoint, prevPoint: not altPoint.betterThan(prevPoint, altLinInEq=altLinInEq) dType = 2 for ls in range(maxLS): altPoint, prevPoint = oldPoint.linePoint(0.5, altPoint), altPoint if sf is not None and sf(altPoint): p.debugmsg('Return by sf: ls = %d' % ls) return altPoint, prevPoint, -1-ls #!!! "not betterThan" is used vs "betterThan" because prevPoint can become same to altPoint #if not altPoint.betterThan(prevPoint, altLinInEq=altLinInEq): if condNotBetter(altPoint, prevPoint): if new_bs: bestPoint, pointForDilation = prevPoint, prev_prev_point #if dType == 1: bestPoint = prev_prev_point return bestPoint, pointForDilation, -1-ls else: return prev_prev_point, -1-ls prev_prev_point = prevPoint if p.norm(oldPoint.x - altPoint.x) < maxDeltaX: #print 'insufficient step norm during backward search:', p.norm(oldPoint.x - altPoint.x) , maxDeltaX break rr = oldPoint.f() - altPoint.f() if (oldPoint.isFeas(True) or altPoint.isFeas(True)) and maxDeltaF/2**15 < abs(rr) < maxDeltaF: break # TODO: is it worth to implement? if (oldPoint.mr_alt() > contol and altPoint.mr_alt() > p.contol) and altPoint.mr_alt() > 0.9*oldPoint.mr(): break # got here if maxLS is exeeded; altPoint is better than prevPoint if new_bs: bestPoint, pointForDilation = altPoint, prevPoint return bestPoint, pointForDilation, -1-ls else: return prev_prev_point, -1-ls openopt-0.38+svn1589/openopt/solvers/UkrOpt/__init__.py000066400000000000000000000000021175775750500230120ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/solvers/UkrOpt/amsg2p.py000066400000000000000000000027401175775750500224570ustar00rootroot00000000000000from numpy import dot, diag, ones, zeros, sqrt from openopt.kernel.ooMisc import norm def amsg2p(f, df, x0, epsilon, f_opt, gamma, callback = lambda x, f: False): # returns optim point and iteration number f0 = f(x0) if f0 - f_opt <= epsilon: return x0, 0 x, n = x0.copy(), x0.size df0 = df(x0) ndf = norm(df0) h, dzeta, p, B = gamma * (f0 - f_opt) / ndf, df0 / ndf, zeros(n), diag(ones(n, 'float64')) # TODO: add possibility to create B of type float128 k = 0 while True: k += 1 x -= h * dot(B, dzeta) F = f(x) r = callback(x, F) if r not in (0, False, None): break # user-demanded stop if F - f_opt <= epsilon: break DF = df(x) DF_dilated = dot(B.T, DF) nDF_dilated = norm(DF_dilated) dzeta_new, h = DF_dilated / nDF_dilated, gamma * (F-f_opt) / nDF_dilated lambda1, lambda2 = -dot(p, dzeta_new), -dot(dzeta, dzeta_new) c1, c2 = lambda1>0, lambda2>0 p = (lambda1 * p + lambda2 * dzeta)/sqrt(lambda1**2+lambda2**2) if c1 and c2 else dzeta if c2 and not c1 else zeros(n) if not c1 and not c2 else p mu = dot(p, dzeta_new) if -1 < mu < 0: S = sqrt(1-mu**2) nu = (1/S-1) * dzeta_new - (mu/S) * p B += dot(dot(B, nu.reshape(n, 1)), dzeta_new.reshape(1, n)) h /= S p = (p - mu * dzeta_new) / S else: p = zeros(n) dzeta = dzeta_new return x, k openopt-0.38+svn1589/openopt/solvers/UkrOpt/amsg2p_oo.py000066400000000000000000000033011175775750500231460ustar00rootroot00000000000000from openopt.kernel.baseSolver import * #from openopt.kernel.Point import Point #from openopt.kernel.setDefaultIterFuncs import * from numpy import isfinite from amsg2p import amsg2p as Solver class amsg2p(baseSolver): __name__ = 'amsg2p' __license__ = "BSD" __authors__ = "Dmitrey" __alg__ = "Petro I. Stetsyuk, amsg2p" __optionalDataThatCanBeHandled__ = [] iterfcnConnected = True #_canHandleScipySparse = True #default parameters # T = float64 showRes = False show_nnan = False gamma = 1.0 # approach = 'all active' def __init__(self): pass def __solver__(self, p): #assert self.approach == 'all active' if not p.isUC: p.warn('Handling of constraints is not implemented properly for the solver %s yet' % self.__name__) if p.fOpt is None: if not isfinite(p.fEnough): p.err('the solver %s requires providing optimal value fOpt') else: p.warn("you haven't provided optimal value fOpt for the solver %s; fEnough = %0.2e will be used instead" %(self.__name__, p.fEnough)) p.fOpt = p.fEnough if p.fTol is None: s = ''' the solver %s requires providing required objective function tolerance fTol 15*ftol = %0.1e will be used instead ''' % (self.__name__, p.ftol) p.pWarn(s) fTol = 15*p.ftol else: fTol = p.fTol def itefcn(*args, **kwargs): p.iterfcn(*args, **kwargs) return p.istop x, itn = Solver(p.f, p.df, p.x0, fTol, p.fOpt, self.gamma, itefcn) if p.f(x) < p.fOpt + fTol: p.istop = 10 #p.iterfcn(x) openopt-0.38+svn1589/openopt/solvers/UkrOpt/de_oo.py000066400000000000000000000245241175775750500223570ustar00rootroot00000000000000#from numpy import asfarray, argmax, sign, inf, log10 from openopt.kernel.baseSolver import baseSolver #from numpy import asfarray, inf, atleast_1d from openopt.kernel.setDefaultIterFuncs import SMALL_DELTA_X, SMALL_DELTA_F import math import numpy as np nanPenalty = 1e10 class de(baseSolver): __name__ = 'de' __license__ = "BSD" __authors__ = "Stepan Hlushak, stepanko - at - gmail - dot - com, connected to OO by Dmitrey" __alg__ = "Two array differential evolution algorithm, Feoktistov V. Differential Evolution. In Search of Solutions (Springer, 2006)(ISBN 0387368965)." iterfcnConnected = True __homepage__ = '' __isIterPointAlwaysFeasible__ = lambda self, p: p.__isNoMoreThanBoxBounded__() __optionalDataThatCanBeHandled__ = ['lb', 'ub', 'A', 'b', 'Aeq','beq','c','h'] _requiresFiniteBoxBounds = True """Strategy for selecting base vector. 'random' - random base vector. 'best' - base vector is chosen to be the best one. """ baseVectorStrategy = 'random' """Strategy of evaluating difference vector. 'random' - random direction. 'best' - move into direction of best vectors. """ searchDirectionStrategy = 'random' """Strategy of choosing F factor. 'constant' - F factor is constant. 'random' - F is vector of random numbers, that are less or equal than F. """ differenceFactorStrategy = 'random' population = 'default: 10*nVars will be used' differenceFactor = 0.8 crossoverRate = 0.5 hndvi = 1 __info__ = """ This is two array differential evolution algorithm. Can handle constraints Ax <= b and c(x) <= 0 Finite box-bound constraints lb <= x <= ub are required. Parameters: population - population number (should be ~ 10*nVars), differenceFactor - difference factor (should be in (0,1] range), crossoverRate - constant of crossover (should be ~ 0.5, in (0,1] range), baseVectorStrategy - strategy of selection of base vector, can be 'random' (default) or 'best' (best vector). searchDirectionStrategy - strategy for calculation of the difference vector, can be 'random' (random direction, default) or 'best' (direction of the best vectors). differenceFactorStrategy - strategy for difference factror (F), can be 'constant' (constant factor, default) or 'random' (F is chosen random for each vector and each component of vector). hndvi - half of number of individuals that take part in creation of difference vector. """ def __init__(self):pass def __solver__(self, p): #def DE2arr(func, lb, ub, itermax=1000, NP=100, F=0.8, Cr=0.5, strategy=(1, 1, 1, 1), constraints=None): if not p.__isFiniteBoxBounded__(): p.err('this solver requires finite lb, ub: lb <= x <= ub') p.kernelIterFuncs.pop(SMALL_DELTA_X, None) p.kernelIterFuncs.pop(SMALL_DELTA_F, None) lb, ub = p.lb, p.ub D = p.n#dimension if isinstance(self.population,str): NP = 10*D else: NP = self.population F = self.differenceFactor Cr = self.crossoverRate #func = p.f #constraints = lambda x: np.hstack((p.c(x), p._get_AX_Less_B_residuals(x))) ################################################# np.random.seed() #initialize population pop = np.random.rand(NP,D)*(ub-lb) + lb #evaluate population best, vals, constr_vals = _eval_pop(pop, p) if self.baseVectorStrategy == 'random': useRandBaseVectStrat = True elif self.baseVectorStrategy == 'best': useRandBaseVectStrat = False else: p.err('incorrect baseVectorStrategy, should be "random" or "best", got ' + str(self.baseVectorStrategy)) if self.searchDirectionStrategy == 'random': useRandSearchDirStrat = True elif self.searchDirectionStrategy == 'best': useRandSearchDirStrat = False else: p.err('incorrect searchDirectionStrategy, should be "random" or "best", got ' + str(self.searchDirectionStrategy)) if self.differenceFactorStrategy == 'random': useRandDiffFactorStrat = True elif self.differenceFactorStrategy == 'constant': useRandDiffFactorStrat = False else: p.err('incorrect differenceFactorStrategy, should be "random" or "constant", got ' + str(self.differenceFactorStrategy)) for i in range(p.maxIter+10): old_pop = pop old_vals = vals old_constr_vals = constr_vals old_best = best #BASE VECTOR if useRandBaseVectStrat: #random base vector beta = old_pop[np.random.randint(NP, size=NP)] else: #best vector beta = np.ones((NP,D),'d') beta = beta*best[3] #TODO: I think there is a better way to create such matrix num_ind = self.hndvi #half of the number of individuals that take part # in differential creation #DIFFERENCE if useRandSearchDirStrat: #random search r1_ints = np.random.randint(NP, size=(num_ind,NP)) r2_ints = np.random.randint(NP, size=(num_ind,NP)) barycenter1 = ((old_pop[r1_ints]).sum(0))/num_ind barycenter2 = ((old_pop[r2_ints]).sum(0))/num_ind else: #directed search r_ints = np.random.randint(NP, size=(2*num_ind)) list = [ (j,constr_vals[j],vals[j]) for j in r_ints] list_arr = np.array(list, dtype=[('i', int), ('constr_val', float), ('val', float)]) list_arr.sort(order=['constr_val','val']) best_list = list_arr[0:num_ind] best_arr = np.array([j for (j,c,f) in best_list], 'i') worst_list = list_arr[num_ind:2*num_ind] worst_arr = np.array([j for (j,c,f) in worst_list], 'i') barycenter1 = ((old_pop[worst_arr]).sum(0))/num_ind barycenter2 = ((old_pop[best_arr]).sum(0))/num_ind delta = barycenter2 - barycenter1 #should be (NP,D)-shape array if useRandDiffFactorStrat: Ft = np.random.rand(NP,D) Ft = Ft*F else: Ft = F pop = beta + Ft*delta #CROSSOVER cross_v = np.ones((NP,D)) const_v = np.random.rand(NP,D) const_v = np.ceil(const_v - Cr) cross_v = cross_v - const_v pop = old_pop*const_v + pop*cross_v #CHECK CONSTRAINTS pop = _correct_box_constraints(lb,ub,pop) best, vals, constr_vals = _eval_pop(pop, p) #SELECTION bool_constr_v = old_constr_vals < constr_vals #true when the old individual is better bool_v = old_vals < vals #also true when the old individual is better # Stephan, I dislike all these integer operations, I'm sure bool operations are faster and clearer, but it's your right // Dmitrey zero_constr_v = 1*((constr_vals > 0) + (old_constr_vals > 0)) # 0 - when all constrains in old and new pops are satisfied # 1 - when not bool_constr_v = (bool_constr_v*4 - 2)*zero_constr_v bool_v = bool_v*2 - 1 bool_v = bool_constr_v + bool_v bool_v = bool_v > 0 old_sel_v = (bool_v*1).reshape(NP,1) #converting from bool to int array sel_v = np.ones((NP,1)) - old_sel_v pop = old_pop*old_sel_v + pop*sel_v old_sel_v = old_sel_v.reshape(NP) sel_v = sel_v.reshape(NP) vals = old_vals*old_sel_v + vals*sel_v constr_vals = old_constr_vals*old_sel_v + constr_vals*sel_v #END SELECTION if (old_best[2] < best[2]) or ((old_best[2] == best[2]) and (old_best[1] < best[1])): best = old_best xk = best[3] if best[1] != 0: fk = best[1] p.iterfcn(xk, fk) else: p.iterfcn(xk) newPoint = p.point(xk) if i==0 or newPoint.betterThan(bestPoint): bestPoint = newPoint if p.istop: p.iterfcn(bestPoint) return def _eval_pop(pop, p): NP = pop.shape[0] vals = p.f(pop) constr_vals = np.zeros(NP) if p.__isNoMoreThanBoxBounded__(): #TODO: omit transpose #print(type(vals)) #print(vals) best_i = vals.argmin() best = (best_i, vals[best_i], 0, pop[best_i]) else: for i in range(NP): newPoint = p.point(pop[i]) constr_vals[i] = newPoint.mr() + nanPenalty * newPoint.nNaNs() if i == 0 or newPoint.betterThan(bestPoint): bestPoint = newPoint bestPoint.i = i best = (bestPoint.i, bestPoint.f(), bestPoint.mr() + nanPenalty * bestPoint.nNaNs(), bestPoint.x) return best, vals, constr_vals def _correct_box_constraints(lb, ub, pop): diff_lb = pop - lb check_lb = diff_lb < 0.0 scale = 1.0 while np.any(check_lb): check_lb = check_lb*1 pop = pop - (1+scale)*check_lb*diff_lb diff_lb = pop - lb check_lb = diff_lb < 0.0 scale /= 2 diff_ub = pop - ub check_ub = diff_ub > 0.0 scale = 1.0 while np.any(check_ub): check_ub = check_ub*1 pop = pop - (1+scale)*check_ub*diff_ub diff_ub = pop - ub check_ub = diff_ub > 0.0 scale /= 2 return pop openopt-0.38+svn1589/openopt/solvers/UkrOpt/goldenSection_oo.py000066400000000000000000000100771175775750500245620ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver from openopt.kernel.setDefaultIterFuncs import SMALL_DELTA_X, IS_MAX_ITER_REACHED, SMALL_DELTA_F from numpy import nan, diff, copy class goldenSection(baseSolver): __name__ = 'goldenSection' __optionalDataThatCanBeHandled__ = ['lb', 'ub'] __license__ = "BSD" __authors__ = 'Dmitrey' __alg__ = "golden section" __info__ = '1-dimensional minimizer for finite box-bound problems' __isIterPointAlwaysFeasible__ = lambda self, p: True useOOiterfcn = True rightLocalization = 0 # stop criterium, should be between 0.0 and 1.0 leftLocalization = 0 # stop criterium, should be between 0.0 and 1.0 rightBorderForLocalization = None leftBorderForLocalization = None # solutionType = 'best'# 'right', 'left' are also allowed def __init__(self):pass def __solver__(self, p): if p.n != 1: p.err('the solver ' + self.__name__ +' can handle singe-variable problems only') if not p.__isFiniteBoxBounded__(): p.err('the solver ' + self.__name__ +' requires finite lower and upper bounds') if SMALL_DELTA_X in p.kernelIterFuncs.keys(): p.kernelIterFuncs.pop(SMALL_DELTA_X) a, b, f = copy(p.lb), copy(p.ub), p.f if self.rightBorderForLocalization is None: self.rightBorderForLocalization = p.ub if self.leftBorderForLocalization is None: self.leftBorderForLocalization = p.lb if self.leftLocalization * (b - self.leftBorderForLocalization) > b - a: p.istop, p.msg = 23, 'right localization has been reached (objFunc evaluation is skipped)' elif self.rightLocalization * (a - self.rightBorderForLocalization) > b - a : p.istop, p.msg = 24, 'left localization has been reached (objFunc evaluation is skipped)' if p.istop: p.xk, p.fk = 0.5*(a+b), nan return #if hasattr(p, ) #phi = 1.6180339887498949 # (1+sqrt(5)) / 2 s1 = 0.3819660112501051# (3-sqrt(double(5)))/2 s2 = 0.6180339887498949# (sqrt(double(5))-1)/2 x1 = a+s1*(b-a) x2 = a+s2*(b-a) y1, y2 = f(x1), f(x2) for i in range(p.maxIter): p.xk, p.fk = 0.5*(x1+x2), 0.5*(y1+y2) if y1 <= y2: xmin, ymin = x1, y1 b, x2 = x2, x1 x1 = a + s1*(b - a) y2, y1 = y1, f(x1) else: xmin, ymin = x2, y2 a, x1 = x1, x2 x2 = a + s2*(b - a) y1, y2 = y2, f(x2) #TODO: handle fEnough criterium for min(y1, y2), not for 0.5*(y1+y2) if self.useOOiterfcn: p.iterfcn() if i > 4 and max(p.iterValues.f[-4:]) < min(p.iterValues.f[-4:]) + p.ftol: p.xf, p.ff = xmin, ymin p.istop, p.msg = SMALL_DELTA_F, '|| F[k] - F[k-1] || < ftol' elif -p.xtol < b - a < p.xtol: # p.iterfcn may be turned off p.xf, p.ff = xmin, ymin # if self.solutionType == 'best': # p.xf, p.ff = xmin, ymin # elif self.solutionType == 'left': # p.xf, p.ff = x1, y1 # elif self.solutionType == 'right': # p.xf, p.ff = x2, y2 # else: # p.err('incorrect solutionType, should be "best", "right" or "left"') p.istop, p.msg = SMALL_DELTA_X, '|| X[k] - X[k-1] || < xtol' elif self.leftLocalization * (b - self.leftBorderForLocalization) > b - a: p.istop, p.msg = 25, 'right localization has been reached' elif self.rightLocalization * (a - self.rightBorderForLocalization) > b - a : p.istop, p.msg = 26, 'left localization has been reached' if y2 > y1: p.special.leftXOptBorder = a p.special.rightXOptBorder = x2 else: p.special.leftXOptBorder = x1 p.special.rightXOptBorder = b if p.istop: return p.istop, p.msg = IS_MAX_ITER_REACHED, 'Max Iter has been reached' openopt-0.38+svn1589/openopt/solvers/UkrOpt/gsubg_oo.py000066400000000000000000001244101175775750500230710ustar00rootroot00000000000000from numpy import diag, array, sqrt, eye, ones, inf, any, copy, zeros, dot, where, all, tile, sum, nan, isfinite, float64, isnan, log10, \ max, sign, array_equal, nonzero, ix_, arctan, pi, logical_not, logical_and, atleast_2d, matrix, delete, empty, ndarray, \ logical_and, logical_not from numpy.linalg import norm, solve, LinAlgError from openopt.kernel.baseSolver import * from openopt.kernel.Point import Point from openopt.kernel.setDefaultIterFuncs import * from openopt.solvers.UkrOpt.UkrOptMisc import getBestPointAfterTurn from openopt.solvers.UkrOpt.PolytopProjection import PolytopProjection class gsubg(baseSolver): __name__ = 'gsubg' __license__ = "BSD" __authors__ = "Dmitrey" __alg__ = "Nikolay G. Zhurbenko generalized epsilon-subgradient" __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] iterfcnConnected = True _canHandleScipySparse = True #gsubg default parameters h0 = 1.0 hmult = 0.5 T = float64 showLS = False show_hs = False showRes = False show_nnan = False doBackwardSearch = True new_bs = True approach = 'all active' zhurb = 100 sigma = 1e-3 dual = True ls_direction = 'simple' qpsolver = 'cvxopt_qp' ns = 15 dilation = 'auto' addASG = False def __init__(self): pass def __solver__(self, p): assert self.approach == 'all active' if not p.isUC: p.warn('Handling of constraints is not implemented properly for the solver %s yet' % self.__name__) dilation = self.dilation assert dilation in ('auto', True, False, 0, 1) if dilation == 'auto': dilation = False #dilation = True if p.n < 150 else False p.debugmsg('%s: autoselect set dilation to %s' %(self.__name__, dilation)) if dilation: from Dilation import Dilation D = Dilation(p) # LB, UB = p.lb, p.ub # fin_lb = isfinite(LB) # fin_ub = isfinite(UB) # ind_lb = where(fin_lb)[0] # ind_ub = where(fin_ub)[0] # ind_only_lb = where(logical_and(fin_lb, logical_not(fin_ub)))[0] # ind_only_ub = where(logical_and(fin_ub, logical_not(fin_lb)))[0] # ind_bb = where(logical_and(fin_ub, fin_lb))[0] # lb_val = LB[ind_only_lb] # ub_val = UB[ind_only_ub] # dist_lb_ub = UB[ind_bb] - LB[ind_bb] # double_dist_lb_ub = 2 * dist_lb_ub # ub_bb = UB[ind_bb] # doubled_ub_bb = 2 * ub_bb # def Point(x): # z = x.copy() # z[ind_only_lb] = abs(x[ind_only_lb]-lb_val) + lb_val # z[ind_only_ub] = ub_val - abs(x[ind_only_ub]-ub_val) # # ratio = x[ind_bb] / double_dist_lb_ub # z1 = x[ind_bb] - array(ratio, int) * double_dist_lb_ub # ind = where(z1>ub_bb)[0] # z1[ind] = doubled_ub_bb - z1[ind] # z[ind_bb] = z1 # #raise 0 # return p.point(z) Point = lambda x: p.point(x) h0 = self.h0 T = self.T # alternatively instead of alp=self.alp etc you can use directly self.alp etc n = p.n x0 = p.x0 if p.nbeq == 0 or any(abs(p._get_AeqX_eq_Beq_residuals(x0))>p.contol): # TODO: add "or Aeqconstraints(x0) out of contol" x0[x0p.ub] = p.ub[x0>p.ub] hs = asarray(h0, T) ls_arr = [] """ Nikolay G. Zhurbenko generalized epsilon-subgradient engine """ bestPoint = Point(asarray(copy(x0), T)) bestFeasiblePoint = None if not bestPoint.isFeas(True) else bestPoint prevIter_best_ls_point = bestPoint best_ls_point = bestPoint iterStartPoint = bestPoint prevIter_bestPointAfterTurn = bestPoint bestPointBeforeTurn = None g = bestPoint._getDirection(self.approach) g1 = iterStartPoint._getDirection(self.approach, currBestFeasPoint = bestFeasiblePoint) if not any(g) and all(isfinite(g)): # TODO: create ENUMs p.istop = 14 if bestPoint.isFeas(False) else -14 p.msg = 'move direction has all-zero coords' return HS = [] LS = [] # TODO: add possibility to handle f_opt if known instead of fTol #fTol = 1.0 if p.fTol is None: p.warn("""The solver requres user-supplied fTol (objective function tolerance); since you have not provided it value, 15*ftol = %0.1e will be used""" % (15*p.ftol)) p.fTol = 15 * p.ftol fTol_start = p.fTol/2.0 fTol = fTol_start subGradientNorms, points, values, isConstraint, epsilons, inactive, normedSubGradients, normed_values = [], [], [], [], [], [], [], [] StoredInfo = [subGradientNorms, points, values, isConstraint, epsilons, inactive, normedSubGradients, normed_values] nMaxVec = self.zhurb nVec = 0 ns = 0 #ScalarProducts = empty((10, 10)) maxQPshoutouts = 15 """ gsubg main cycle """ itn = -1 while True: itn += 1 # TODO: change inactive data removing # TODO: change inner cycle condition # TODO: improve 2 points obtained from backward line search koeffs = None while ns < self.ns: ns += 1 nAddedVectors = 0 projection = None F0 = asscalar(bestFeasiblePoint.f() - fTol_start) if bestFeasiblePoint is not None else nan #iterStartPoint = prevIter_best_ls_point if bestPointBeforeTurn is None: sh = schedule = [bestPoint] #x = iterStartPoint.x else: sh = [point1, point2] if point1.betterThan(point2, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint) else [point2, point1] #sh = [iterStartPoint, bestPointBeforeTurn, bestPointAfterTurn] #sh.sort(cmp = lambda point1, point2: -1+2*int(point1.betterThan(point2, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint))) iterStartPoint = sh[-1] schedule = [point for point in sh if id(point.x) != id(points[-1])] #x = iterStartPoint.x.copy() #x = 0.5*(point1.x+point2.x) #print 'len(schedule):', len(schedule) x = iterStartPoint.x.copy() #print 'itn:', itn, 'ns:', ns, 'x:', x, 'hs:', hs # if itn != 0: # Xdist = norm(prevIter_best_ls_point.x-bestPointAfterTurn.x) # if hs < 0.25*Xdist : # hs = 0.25*Xdist iterInitialDataSize = len(values) for point in schedule: if (point.sum_of_all_active_constraints()>p.contol / 10 or not isfinite(point.f())) and any(point.sum_of_all_active_constraints_gradient()): #print '111111' # if not point.isFeas(True): # TODO: use old-style w/o the arg "currBestFeasPoint = bestFeasiblePoint" #tmp = point._getDirection(self.approach, currBestFeasPoint = bestFeasiblePoint) nVec += 1 tmp = point.sum_of_all_active_constraints_gradient()#, currBestFeasPoint = bestFeasiblePoint) if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() n_tmp = norm(tmp) assert n_tmp != 0.0 normedSubGradients.append(tmp/n_tmp) subGradientNorms.append(n_tmp) val = point.sum_of_all_active_constraints() values.append(asscalar(val)) normed_values.append(asscalar(val/n_tmp)) #epsilons.append(asscalar(val / n_tmp - dot(point.x, tmp)/n_tmp**2)) epsilons.append(asscalar((val + dot(point.x, tmp))/n_tmp)) #epsilons.append(asscalar(val - dot(point.x, tmp))/n_tmp) #epsilons.append(asscalar(val)) isConstraint.append(True) points.append(point.x) inactive.append(0) nAddedVectors += 1 if bestFeasiblePoint is not None and isfinite(point.f()): #print '222222' tmp = point.df() if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A tmp = tmp.flatten() n_tmp = norm(tmp) if n_tmp < p.gtol: p._df = n_tmp # TODO: change it p.iterfcn(point) return nVec += 1 normedSubGradients.append(tmp/n_tmp) subGradientNorms.append(n_tmp) val = point.f() values.append(asscalar(val)) normed_values.append(asscalar(val/n_tmp)) epsilons.append(asscalar((val + dot(point.x, tmp))/n_tmp)) isConstraint.append(False) points.append(point.x) inactive.append(0) nAddedVectors += 1 if self.addASG and itn != 0 and Projection is not None: tmp = Projection if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A tmp = tmp.flatten() n_tmp = norm(tmp) nVec += 1 normedSubGradients.append(tmp/n_tmp) subGradientNorms.append(n_tmp) val = ProjectionVal #val = n_tmp*(1-1e-7) # to prevent small numerical errors accumulation values.append(asscalar(val)) normed_values.append(asscalar(val/n_tmp))# equals to 0 epsilons.append(asscalar((val + dot(prevIterPoint.x, tmp))/n_tmp)) if not p.isUC: p.pWarn('addASG is not ajusted with constrained problems handling yet') isConstraint.append(False if p.isUC else True) points.append(prevIterPoint.x) inactive.append(0) nAddedVectors += 1 # else: # p.err('bug in %s, inform openopt developers' % self.__name__) indToBeRemovedBySameAngle = [] valDistances1 = asfarray(normed_values) valDistances2 = asfarray([(0 if isConstraint[i] else -F0) for i in range(nVec)]) / asfarray(subGradientNorms) valDistances3 = asfarray([dot(x-points[i], vec) for i, vec in enumerate(normedSubGradients)]) valDistances = valDistances1 + valDistances2 + valDistances3 #valDistances4 = asfarray([(0 if isConstraint[i] else -F0) for i in range(nVec)]) / asfarray(subGradientNorms) #valDistancesForExcluding = valDistances1 + valDistances3 + valDistances4 # with constraints it may yield different result vs valDistances # if p.debug: p.debugmsg('valDistances: ' + str(valDistances)) if iterInitialDataSize != 0: for j in range(nAddedVectors): ind = -1-j scalarProducts = dot(normedSubGradients, normedSubGradients[ind]) IND = where(scalarProducts > 1 - self.sigma)[0] if IND.size != 0: _case = 1 if _case == 1: mostUseful = argmax(valDistances[IND]) IND = delete(IND, mostUseful) indToBeRemovedBySameAngle +=IND.tolist() else: indToBeRemovedBySameAngle += IND[:-1].tolist() indToBeRemovedBySameAngle = list(set(indToBeRemovedBySameAngle)) # TODO: simplify it indToBeRemovedBySameAngle.sort(reverse=True) if p.debug: p.debugmsg('indToBeRemovedBySameAngle: ' + str(indToBeRemovedBySameAngle) + ' from %d' %nVec) if indToBeRemovedBySameAngle == range(nVec-1, nVec-nAddedVectors-1, -1) and ns > 5: # print 'ns =', ns, 'hs =', hs, 'iterStartPoint.f():', iterStartPoint.f(), 'prevInnerCycleIterStartPoint.f()', prevInnerCycleIterStartPoint.f(), \ # 'diff:', iterStartPoint.f()-prevInnerCycleIterStartPoint.f() #raise 0 p.istop = 17 p.msg = 'all new subgradients have been removed due to the angle threshold' return #print 'added:', nAddedVectors,'current lenght:', len(values), 'indToBeRemoved:', indToBeRemoved valDistances = valDistances.tolist() valDistances2 = valDistances2.tolist() for ind in indToBeRemovedBySameAngle:# TODO: simplify it for List in StoredInfo + [valDistances, valDistances2]: del List[ind] nVec -= len(indToBeRemovedBySameAngle) if nVec > nMaxVec: for List in StoredInfo + [valDistances, valDistances2]: del List[:-nMaxVec] assert len(StoredInfo[-1]) == nMaxVec nVec = nMaxVec valDistances = asfarray(valDistances) valDistances2 = asfarray(valDistances2) #F = 0.0 indActive = where(valDistances >= 0)[0] m = len(indActive) product = None #print('fTol: %f m: %d ns: %d' %(fTol, m, ns)) #raise 0 if p.debug: p.debugmsg('fTol: %f ns: %d' %(fTol, ns)) Projection = None if nVec > 1: normalizedSubGradients = asfarray(normedSubGradients) product = dot(normalizedSubGradients, normalizedSubGradients.T) #best_QP_Point = None #maxQPshoutouts = 1 for j in range(maxQPshoutouts if bestFeasiblePoint is not None else 1): F = asscalar(bestFeasiblePoint.f() - fTol * 5**j) if bestFeasiblePoint is not None else nan valDistances2_modified = asfarray([(0 if isConstraint[i] else -F) for i in range(nVec)]) / asfarray(subGradientNorms) ValDistances = valDistances + valDistances2_modified - valDistances2 # DEBUG!!!!!!!!! #ValDistances = array([0, -1]) #ValDistances = valDistances # DEBUG END!!!!!!!!! # !!!!!!!!!!!!! TODO: analitical solution for m==2 new = 0 if nVec == 2 and new: a, b = normedSubGradients[0]*ValDistances[0], normedSubGradients[1]*ValDistances[1] a2, b2, ab = (a**2).sum(), (b**2).sum(), dot(a, b) beta = a2 * (ab-b2) / (ab**2 - a2 * b2) alpha = b2 * (ab-a2) / (ab**2 - a2 * b2) g1 = alpha * a + beta * b else: #projection, koeffs = PolytopProjection(product, asfarray(ValDistances), isProduct = True) #print 'before PolytopProjection' koeffs = PolytopProjection(product, asfarray(ValDistances), isProduct = True, solver = self.qpsolver) # assert all(isfinite(koeffs)) #print koeffs #print 'after PolytopProjection' projection = dot(normalizedSubGradients.T, koeffs).flatten() #print 'norm(projection):', norm(projection) #raise 0 # from openopt import QP # p2 = QP(diag(ones(n)), zeros(n), A=-asfarray(normedSubGradients), b=-ValDistances) # projection = p2.solve('cvxopt_qp', iprint=-1).xf # print 'proj:', projection # if itn != 0: raise 0 #if ns > 3: raise 0 threshold = 1e-9 # for to prevent small numerical issues if j == 0 and any(dot(normalizedSubGradients, projection) < ValDistances * (1-threshold*sign(ValDistances)) - threshold): p.istop = 16 p.msg = 'optimal solution wrt required fTol has been obtained' return #p.debugmsg('g1 shift: %f' % norm(g1/norm(g1)-projection/norm(projection))) g1 = projection if j == 0: Projection = projection ProjectionVal = sum(koeffs*asfarray(ValDistances)) #hs = 0.4*norm(g1) M = norm(koeffs, inf) # TODO: remove the cycles indActive = where(koeffs >= M / 1e7)[0] for k in indActive.tolist(): inactive[k] = 0 NewPoint = Point(x - g1) #print 'isBetter:', NewPoint.betterThan(p.point(x), altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint) if j == 0 or NewPoint.betterThan(best_QP_Point, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint): best_proj = g1 best_QP_Point = NewPoint else: g1 = best_proj break maxQPshoutouts = max((j+2, 1)) #print 'opt j:', j, 'nVec:', nVec #Xdist = norm(projection1) # if hs < 0.25*Xdist : # hs = 0.25*Xdist else: g1 = iterStartPoint._getDirection(self.approach, currBestFeasPoint = bestFeasiblePoint) if any(isnan(g1)): p.istop = 900 return if dilation and len(sh) == 2: point = sh[0] if dot(iterStartPoint._getDirection(self.approach), sh[0]._getDirection(self.approach)) < 0 else sh[1] D.updateDilationMatrix(iterStartPoint._getDirection(self.approach) - point._getDirection(self.approach), alp = 1.2) g1 = D.getDilatedVector(g1) #g1 = tmp if any(g1): g1 /= p.norm(g1) else: p.istop = 103 if Point(x).isFeas(False) else -103 #raise 0 return #hs = 1 """ Forward line search """ bestPointBeforeTurn = iterStartPoint hs_cumsum = 0 hs_start = hs if not isinstance(g1, ndarray) or isinstance(g1, matrix): g1 = g1.A g1 = g1.flatten() hs_mult = 4.0 for ls in range(p.maxLineSearch): # if ls > 20: # hs_mult = 2.0 # elif ls > 10: # hs_mult = 1.5 # elif ls > 2: # hs_mult = 1.05 assert all(isfinite(g1)) assert all(isfinite(x)) assert isfinite(hs) x -= hs * g1 hs *= hs_mult hs_cumsum += hs newPoint = Point(x) #if ls == 0 else iterStartPoint.linePoint(hs_cumsum/(hs_cumsum-hs), oldPoint) # TODO: take ls into account? if self.show_nnan: p.info('ls: %d nnan: %d' % (ls, newPoint.__nnan__())) if ls == 0: oldPoint = iterStartPoint#prevIter_best_ls_point#prevIterPoint oldoldPoint = oldPoint assert all(isfinite(oldPoint.x)) #if not self.checkTurnByGradient: #TODO: create routine for modifying bestFeasiblePoint if newPoint.isFeas(False) and (bestFeasiblePoint is None or newPoint.f() > bestFeasiblePoint.f()): bestFeasiblePoint = newPoint if newPoint.betterThan(oldPoint, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint): if newPoint.betterThan(bestPoint, altLinInEq=True): bestPoint = newPoint oldoldPoint = oldPoint #assert dot(oldoldPoint._getDirection(self.approach), g1)>= 0 oldPoint, newPoint = newPoint, None else: bestPointBeforeTurn = oldoldPoint if not itn % 4: for fn in ['_lin_ineq', '_lin_eq']: if hasattr(newPoint, fn): delattr(newPoint, fn) break #assert norm(oldoldPoint.x -newPoint.x) > 1e-17 hs /= hs_mult if ls == p.maxLineSearch-1: p.istop, p.msg = IS_LINE_SEARCH_FAILED, 'maxLineSearch (' + str(p.maxLineSearch) + ') has been exceeded' return p.debugmsg('ls_forward: %d' %ls) """ Backward line search """ maxLS = 500 #if ls == 0 else 5 maxDeltaF = p.ftol / 16.0#fTol/4.0 #p.ftol / 16.0 maxDeltaX = p.xtol / 2.0 #if m < 2 else hs / 16.0#Xdist/16.0 ls_backward = 0 #DEBUG # print '!!!!1:', isPointCovered(oldoldPoint, newPoint, bestFeasiblePoint, fTol), '<<<' # print '!!!!2:', isPointCovered(newPoint, oldoldPoint, bestFeasiblePoint, fTol), '<<<' # print '!!!!3:', isPointCovered(iterStartPoint, newPoint, bestFeasiblePoint, fTol), '<<<' # print '!!!!4:', isPointCovered(newPoint, iterStartPoint, bestFeasiblePoint, fTol), '<<<' # raise 0 #DEBUG END #assert p.isUC maxRecNum = 400#4+int(log2(norm(oldoldPoint.x-newPoint.x)/p.xtol)) #assert dot(oldoldPoint.df(), newPoint.df()) < 0 #assert sign(dot(oldoldPoint.df(), g1)) != sign(dot(newPoint.df(), g1)) point1, point2, nLSBackward = LocalizedSearch(oldoldPoint, newPoint, bestFeasiblePoint, fTol, p, maxRecNum, self.approach) #assert sign(dot(point1.df(), g1)) != sign(dot(point2.df(), g1)) best_ls_point = point1 if point1.betterThan(point2, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint) else point2 # if self.doBackwardSearch: # #print '----------------!!!!!!!! norm(oldoldPoint - newPoint)', norm(oldoldPoint.x -newPoint.x) # isOverHalphPi = True # if isOverHalphPi: # best_ls_point, bestPointAfterTurn, ls_backward = \ # getBestPointAfterTurn(oldoldPoint, newPoint, maxLS = maxLS, maxDeltaF = p.ftol / 2.0, #sf = func, # maxDeltaX = p.xtol / 2.0, altLinInEq = True, new_bs = True, checkTurnByGradient = True) # #assert ls_backward != -7 # else: # best_ls_point, bestPointAfterTurn, ls_backward = \ # getBestPointAfterTurn(oldoldPoint, newPoint, maxLS = maxLS, maxDeltaF = p.ftol / 2.0, sf = func, \ # maxDeltaX = p.xtol / 2.0, altLinInEq = True, new_bs = True, checkTurnByGradient = True) # # #assert best_ls_point is not iterStartPoint # g1 = bestPointAfterTurn._getDirection(self.approach, currBestFeasPoint = bestFeasiblePoint) ## best_ls_point, bestPointAfterTurn, ls_backward = \ ## getBestPointAfterTurn(oldoldPoint, newPoint, maxLS = maxLS, maxDeltaF = maxDeltaF, sf = func, \ ## maxDeltaX = maxDeltaX, altLinInEq = True, new_bs = True, checkTurnByGradient = True) # p.debugmsg('ls_backward: %d' % ls_backward) # if bestPointAfterTurn.betterThan(best_ls_point, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint): # best_ls_point = bestPointAfterTurn if oldoldPoint.betterThan(best_ls_point, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint): best_ls_point_with_start = oldoldPoint else: best_ls_point_with_start = best_ls_point # TODO: extract last point from backward search, that one is better than iterPoint if best_ls_point.betterThan(bestPoint, altLinInEq=True): bestPoint = best_ls_point if best_ls_point.isFeas(True) and (bestFeasiblePoint is None or best_ls_point.betterThan(bestFeasiblePoint, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint)): bestFeasiblePoint = best_ls_point # print 'ls_backward', ls_backward # if ls_backward < -4: # fTol /= 2.0 # elif ls > 4: # fTol *= 2.0 # # print 'fTol:', fTol """ Updating hs """ step_x = p.norm(best_ls_point.x - prevIter_best_ls_point.x) step_f = abs(best_ls_point.f() - prevIter_best_ls_point.f()) HS.append(hs_start) assert ls >= 0 LS.append(ls) p.debugmsg('hs before: %0.1e' % hs) # if itn > 3: # mean_ls = (3*LS[-1] + 2*LS[-2]+LS[-3]) / 6.0 # j0 = 3.3 # #print 'mean_ls:', mean_ls # #print 'ls_backward:', ls_backward # if mean_ls > j0: # hs = (mean_ls - j0 + 1)**0.5 * hs_start # else: # #hs = hs_start / 16.0 # if (ls == 0 and ls_backward == -maxLS) or self.zhurb!=0: # shift_x = step_x / p.xtol # shift_f = step_f / p.ftol # # print 'shift_x: %e shift_f: %e' %(shift_x, shift_f) # RD = log10(shift_x+1e-100) # if best_ls_point.isFeas(True) or prevIter_best_ls_point.isFeas(True): # RD = min((RD, log10(shift_f + 1e-100))) # #print 'RD:', RD # if RD > 1.0: # mp = (0.5, (ls/j0) ** 0.5, 1 - 0.2*RD) # hs *= max(mp) prev_hs = hs if step_x != 0: hs = 0.5*step_x # elif ls == 0 and nLSBackward > 4: # hs /= 4.0 # elif ls > 3: # hs *= 2.0 else: hs = max((hs / 10.0, p.xtol/2.0)) #if koeffs is not None: hs = sum(koeffs) p.debugmsg('hs after: %0.1e' % hs) #hs = max((p.xtol/100, 0.5*step_x)) #print 'step_x:', step_x, 'new_hs:', hs, 'prev_hs:', prev_hs, 'ls:', ls, 'nLSBackward:', nLSBackward #if hs < p.xtol/4: hs = p.xtol/4 """ Handling iterPoints """ if itn == 0: p.debugmsg('hs: ' + str(hs)) p.debugmsg('ls: ' + str(ls)) if self.showLS: p.info('ls: ' + str(ls)) if self.show_hs: p.info('hs: ' + str(hs)) if self.show_nnan: p.info('nnan: ' + str(best_ls_point.__nnan__())) if self.showRes: r, fname, ind = best_ls_point.mr(True) p.info(fname+str(ind)) #print '^^^^1:>>', iterStartPoint.f(), '2:>>', best_ls_point_with_start.f() #hs = max((norm(best_ls_point_with_start.x-iterStartPoint.x)/2, 64*p.xtol)) #if p.debug: assert p.isUC prevInnerCycleIterStartPoint = iterStartPoint #if ns > 3: raise 0 if best_ls_point_with_start.betterThan(iterStartPoint, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint): #raise 0 ns = 0 iterStartPoint = best_ls_point_with_start break else: iterStartPoint = best_ls_point_with_start # if id(best_ls_point_with_start) != id(iterStartPoint): # print 'new iter point' # assert iterStartPoint.f() != best_ls_point_with_start.f() # if best_ls_point_with_start.betterThan(iterStartPoint, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint): # #hs = norm(best_ls_point_with_start.x-iterStartPoint.x)/16#max(p.xtol, norm(best_ls_point_with_start.x-iterStartPoint.x)/160.0) # ns = 0 # # assert not iterStartPoint.betterThan(best_ls_point_with_start) # # iterStartPoint = best_ls_point_with_start # # assert p.isUC # if iterStartPoint.f() - best_ls_point_with_start.f() > fTol : # break # else: # raise 0 # !!!! TODO: has it to be outside the loop? # "while ns" loop end isOverHalphPi = product is not None and any(product[indActive].flatten() <= 0) if ns == self.ns and isOverHalphPi: p.istop = 16 p.msg = 'Max linesearch directions number has been exceeded' best_ls_point = best_ls_point_with_start """ Some final things for gsubg main cycle """ prevIter_best_ls_point = best_ls_point_with_start prevIterPoint = iterStartPoint # TODO: mb move it inside inner loop if koeffs is not None: indInactive = where(koeffs < M / 1e7)[0] for k in indInactive.tolist(): inactive[k] += 1 indInactiveToBeRemoved = where(asarray(inactive) > 5)[0].tolist() # print ('indInactiveToBeRemoved:'+ str(indInactiveToBeRemoved) + ' from' + str(nVec)) if p.debug: p.debugmsg('indInactiveToBeRemoved:'+ str(indInactiveToBeRemoved) + ' from' + str(nVec)) if len(indInactiveToBeRemoved) != 0: # elseware error in current Python 2.6 indInactiveToBeRemoved.reverse()# will be sorted in descending order nVec -= len(indInactiveToBeRemoved) for j in indInactiveToBeRemoved: for List in StoredInfo:# + [valDistances.tolist()]: del List[j] """ Call OO iterfcn """ if hasattr(p, '_df'): delattr(p, '_df') if best_ls_point.isFeas(False) and hasattr(best_ls_point, '_df'): p._df = best_ls_point.df().copy() assert all(isfinite(best_ls_point.x)) # print '--------------' # print norm(best_ls_point.x-p.xk) #if norm(best_ls_point.x-p.xk) == 0: raise 0 cond_same_point = array_equal(best_ls_point.x, p.xk) p.iterfcn(best_ls_point) #p.iterfcn(bestPointBeforeTurn) """ Check stop criteria """ if cond_same_point and not p.istop: #raise 0 p.istop = 14 p.msg = 'X[k-1] and X[k] are same' p.stopdict[SMALL_DELTA_X] = True return s2 = 0 if p.istop and not p.userStop: if p.istop not in p.stopdict: p.stopdict[p.istop] = True # it's actual for converters, TODO: fix it if SMALL_DF in p.stopdict: if best_ls_point.isFeas(False): s2 = p.istop p.stopdict.pop(SMALL_DF) if SMALL_DELTA_F in p.stopdict: # TODO: implement it more properly if best_ls_point.isFeas(False) and prevIter_best_ls_point.f() != best_ls_point.f(): s2 = p.istop p.stopdict.pop(SMALL_DELTA_F) if SMALL_DELTA_X in p.stopdict: if best_ls_point.isFeas(False) or not prevIter_best_ls_point.isFeas(False) or cond_same_point: s2 = p.istop p.stopdict.pop(SMALL_DELTA_X) # if s2 and (any(isnan(best_ls_point.c())) or any(isnan(best_ls_point.h()))) \ # and not p.isNaNInConstraintsAllowed\ # and not cond_same_point: # s2 = 0 if not s2 and any(p.stopdict.values()): for key, val in p.stopdict.iteritems(): if val == True: s2 = key break p.istop = s2 for key, val in p.stopdict.iteritems(): if key < 0 or key in set([FVAL_IS_ENOUGH, USER_DEMAND_STOP, BUTTON_ENOUGH_HAS_BEEN_PRESSED]): #p.iterfcn(bestPoint) return """ If stop required """ if p.istop: #p.iterfcn(bestPoint) return isPointCovered2 = lambda pointWithSubGradient, pointToCheck, bestFeasiblePoint, fTol, contol:\ pointWithSubGradient.f() - bestFeasiblePoint.f() + 0.75*fTol > dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient.df()) def isPointCovered3(pointWithSubGradient, pointToCheck, bestFeasiblePoint, fTol, contol): if bestFeasiblePoint is not None \ and pointWithSubGradient.f() - bestFeasiblePoint.f() + 0.75*fTol > dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient.df()): return True if not pointWithSubGradient.isFeas(True) and \ pointWithSubGradient.mr_alt(bestFeasPoint = bestFeasiblePoint) + 1e-15 > \ dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient._getDirection('all active', currBestFeasPoint = bestFeasiblePoint)): return True return False def isPointCovered4(pointWithSubGradient, pointToCheck, bestFeasiblePoint, fTol, contol): #print 'isFeas:', pointWithSubGradient.isFeas(True) # if pointWithSubGradient.sum_of_all_active_constraints() != 0 and any(pointWithSubGradient.sum_of_all_active_constraints_gradient()): # return pointWithSubGradient.sum_of_all_active_constraints() + 0.75*contol > \ # dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient.sum_of_all_active_constraints_gradient()) # # return pointWithSubGradient.f() - bestFeasiblePoint.f() + 0.75*fTol > dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient.df()) ############################## if pointWithSubGradient.isFeas(True): # assert bestFeasiblePoint is not None return pointWithSubGradient.f() - bestFeasiblePoint.f() + 0.75*fTol > dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient.df()) elif pointWithSubGradient.sum_of_all_active_constraints() + 0.75*contol > \ dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient.sum_of_all_active_constraints_gradient()): return True #return pointWithSubGradient.f() - bestFeasiblePoint.f() + 0.75*fTol > dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient.df()) return False # return pointWithSubGradient.mr_alt(bestFeasiblePoint = bestFeasiblePoint) + 0.25*contol > \ # dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient._getDirection('all active', currBestFeasPoint = bestFeasiblePoint)) ###################### # # if bestFeasiblePoint is not None \ # and pointWithSubGradient.f() - bestFeasiblePoint.f() + 0.75*fTol > dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient.df()): return True # # return pointWithSubGradient.mr_alt(bestFeasiblePoint = bestFeasiblePoint) + 0.25*contol > \ # dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient._getDirection('all active', currBestFeasPoint = bestFeasiblePoint)) ###################### # isFeas = pointWithSubGradient.isFeas(True) # if isFeas: # return pointWithSubGradient.f() - bestFeasiblePoint.f() + 0.75*fTol > dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient.df()) # else: # return pointWithSubGradient.mr_alt(bestFeasiblePoint = bestFeasiblePoint) + 0.25*contol > \ # dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient._getDirection('all active', currBestFeasPoint = bestFeasiblePoint)) ###################### # isCoveredByConstraints = pointWithSubGradient.mr_alt(bestFeasiblePoint = bestFeasiblePoint) + 0.25*contol > \ # dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient._getDirection('all active', currBestFeasPoint = bestFeasiblePoint)) \ # if not pointWithSubGradient.isFeas(True) else True # # isCoveredByObjective = pointWithSubGradient.f() - bestFeasiblePoint.f() + 0.75*fTol > dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient.df())\ # if bestFeasiblePoint is not None else True # # return isCoveredByConstraints and isCoveredByObjective ###################### # if not pointWithSubGradient.isFeas(True): # return True if pointWithSubGradient.mr_alt(bestFeasiblePoint = bestFeasiblePoint) + 0.25*contol > \ # dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient._getDirection('all active', currBestFeasPoint = bestFeasiblePoint)) else False # #, currBestFeasPoint = bestFeasiblePoint)): # # if pointWithSubGradient.f() - bestFeasiblePoint.f() + 0.75*fTol > dot(pointWithSubGradient.x - pointToCheck.x, pointWithSubGradient.df()): # # if pointWithSubGradient is feas (i.e. not 1st case) than bestFeasiblePoint is not None # return True # # return False isPointCovered = isPointCovered4 def LocalizedSearch(point1, point2, bestFeasiblePoint, fTol, p, maxRecNum, approach): # bestFeasiblePoint = None contol = p.contol for i in range(maxRecNum): if p.debug: p.debugmsg('req num: %d from %d' % (i, maxRecNum)) new = 0 if new: if point1.betterThan(point2, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint) and isPointCovered(point2, point1, bestFeasiblePoint, fTol) \ or point2.betterThan(point1, altLinInEq=True, bestFeasiblePoint = bestFeasiblePoint) and isPointCovered(point1, point2, bestFeasiblePoint, fTol): break else: isPoint1Covered = isPointCovered(point2, point1, bestFeasiblePoint, fTol, contol) isPoint2Covered = isPointCovered(point1, point2, bestFeasiblePoint, fTol, contol) #print 'isPoint1Covered:', isPoint1Covered, 'isPoint2Covered:', isPoint2Covered if isPoint1Covered and isPoint2Covered:# and i != 0: break # TODO: prevent small numerical errors accumulation point = point1.linePoint(0.5, point2) #point = p.point((point1.x + point2.x)/2.0) if point.isFeas(False) and (bestFeasiblePoint is None or bestFeasiblePoint.f() > point.f()): bestFeasiblePoint = point #if p.debug: assert p.isUC if dot(point._getDirection(approach, currBestFeasPoint = bestFeasiblePoint), point1.x-point2.x) < 0: point2 = point else: point1 = point return point1, point2, i ######################33 # from scipy.sparse import eye # from openopt import QP # projection2 = QP(eye(p.n, p.n), zeros_like(x), A=polyedr, b = -valDistances).solve('cvxopt_qp', iprint = -1).xf # g1 = projection2 openopt-0.38+svn1589/openopt/solvers/UkrOpt/ii_engine.py000066400000000000000000000122751175775750500232200ustar00rootroot00000000000000from interalgLLR import * from interalgT import r42 from numpy import inf, prod, searchsorted, all, sum def r14IP(p, nlhc, residual, definiteRange, y, e, vv, asdf1, C, CBKPMV, itn, g, nNodes, \ frc, fTol, Solutions, varTols, _in, dataType, \ maxNodes, _s, indTC, xRecord): required_sigma = p.ftol * 0.99 # to suppress roundoff effects m, n = y.shape if 1: ip = func10(y, e, vv) ip.dictOfFixedFuncs = p.dictOfFixedFuncs o, a, definiteRange = func8(ip, asdf1, dataType) else: vv = p._freeVarsList o, a, definiteRange = func82(y, e, vv, asdf1, dataType, p) if not all(definiteRange): p.err(''' numerical integration with interalg is implemented for definite (real) range only, no NaN values in integrand are allowed''') o, a = o.reshape(2*n, m).T, a.reshape(2*n, m).T r42(o, a) if itn == 0: # TODO: fix it #_s = atleast_1d(nanmax(a-o)) _s = atleast_1d(inf) nodes = func11(y, e, None, indTC, None, o, a, _s, p) #OLD # nodes.sort(key = lambda obj: obj.key) # #nodes.sort(key = lambda obj: obj.volumeResidual, reverse=True) # # if len(_in) == 0: # an = nodes # else: # arr1 = [node.key for node in _in] # arr2 = [node.key for node in nodes] ## arr1 = -array([node.volumeResidual for node in _in]) ## arr2 = -array([node.volumeResidual for node in nodes]) # # r10 = searchsorted(arr1, arr2) # an = insert(_in, r10, nodes) #NEW #nodes.sort(key = lambda obj: obj.key) #nodes.sort(key = lambda obj: obj.volumeResidual, reverse=True) if len(_in) == 0: an = nodes else: an = hstack((_in, nodes)).tolist() if 1: an.sort(key = lambda obj: obj.key, reverse=False) #an.sort(key = lambda obj: obj.minres, reverse=False) else: an.sort(key=lambda obj: obj.volumeResidual, reverse=False) ao_diff = array([node.key for node in an]) volumes = array([node.volume for node in an]) if 1: r10 = ao_diff <= 0.5*(required_sigma-p._residual) / (prod(p.ub-p.lb) - p._volume) #r10 = nanmax(a-o, 1) <= required_sigma / prod(p.ub-p.lb) ind = where(r10)[0] # TODO: use true_sum #print sum(array([an[i].F for i in ind]) * array([an[i].volume for i in ind])) #print 'p._F:', p._F, 'delta:', sum(array([an[i].F for i in ind]) * array([an[i].volume for i in ind])) v = volumes[ind] p._F += sum(array([an[i].F for i in ind]) * v) residuals = ao_diff[ind] * v p._residual += residuals.sum() p._volume += v.sum() # print '1: %e' % v.sum() volume_0 = p._volume #print 'iter:', p.iter, 'nNodes:', len(an), 'F:', p._F, 'div:', ao_diff / (required_sigma / prod(p.ub-p.lb)) an = asarray(an, object) an = an[where(logical_not(r10))[0]] # changes if 0: minres = array([node.minres for node in an]) r10 = minres <= 0.5*(required_sigma-p._residual) / (prod(p.ub-p.lb) - p._volume) ind = where(r10)[0] for i in ind: node = an[i] minres_ind = node.minres_ind minres = node.minres node_volume = prod(node.e-node.y) # TODO: get rid of cycle here minres_residual = node.a[minres_ind] - node.o[minres_ind] minres_F = 0.5*(node.a[minres_ind] + node.o[minres_ind]) p._residual += 0.5 * minres_residual * node_volume p._F += 0.5 * minres_F * node_volume p._volume += 0.5 * node_volume node.volume *= 0.5 node.minres = inf if minres_ind < n: node.y[minres_ind] += 0.5 * (node.e[minres_ind] - node.y[minres_ind]) #node.key = min((node.key, node.a[minres_ind-n] - node.o[minres_ind-n])) else: node.e[minres_ind-n] -= 0.5 * (node.e[minres_ind-n] - node.y[minres_ind-n]) #node.key = min((node.key, node.a[minres_ind] - node.o[minres_ind])) node.minres = node.complementary_minres # if ind.size != 0 : print '2: %e' % (p._volume - volume_0) # changes end else: residuals = ao_diff * volumes p._residual = 0.5*sum(residuals) #print 'sum(residuals): ', sum(residuals) if p._residual < required_sigma: p._F = sum(array([node.F for node in an]) * v) an = [] #p._Residual = p._residual + sum(asarray([node.volume for node in an]) * asarray([node.key for node in an])) nNodes.append(len(an)) p.iterfcn(xk=array(nan), fk=p._F, rk = 0)#TODO: change rk to something like p._r0 - p._residual if p.istop != 0: ao_diff = array([node.key for node in an]) volumes = array([node.volume for node in an]) p._residual += sum(ao_diff * volumes) _s = None #an, g = func9(an, fo, g, 'IP') #nn = 1 if asdf1.isUncycled and all(isfinite(a)) and all(isfinite(o)) and p._isOnlyBoxBounded else maxNodes #an, g = func5(an, nn, g) return an, g, inf, _s, Solutions, xRecord, frc, CBKPMV openopt-0.38+svn1589/openopt/solvers/UkrOpt/interalgCons.py000066400000000000000000000246201175775750500237170ustar00rootroot00000000000000from numpy import empty, where, logical_and, logical_not, take, logical_or, isnan, zeros, log2, isfinite, \ int8, int16, int32, int64, inf, isinf, asfarray, hstack, vstack, prod, all, any, asarray, tile, zeros_like from interalgLLR import func8, func10 from interalgT import adjustDiscreteVarBounds from FuncDesigner import oopoint from FuncDesigner.ooFun import getSmoothNLH from FuncDesigner.Interval import adjust_lx_WithDiscreteDomain, adjust_ux_WithDiscreteDomain try: from bottleneck import nanargmin, nanmin, nanargmax, nanmax except ImportError: from numpy import nanmin, nanargmin, nanargmax, nanmax def processConstraints(C0, y, e, p, dataType): n = p.n m = y.shape[0] r15 = empty(m, bool) nlh = zeros((m, 2*n)) r15.fill(True) DefiniteRange = True if len(p._discreteVarsNumList): adjustDiscreteVarBounds(y, e, p) for f, r16, r17, tol in C0: if p.solver.dataHandling == 'sorted': tol = 0 ip = func10(y, e, p._freeVarsList) ip.dictOfFixedFuncs = p.dictOfFixedFuncs o, a, definiteRange = func8(ip, f, dataType) DefiniteRange = logical_and(DefiniteRange, definiteRange) o, a = o.reshape(2*n, m).T, a.reshape(2*n, m).T if not f.isUncycled: r42(o, a) lf1, lf2, uf1, uf2 = o[:, 0:n], o[:, n:2*n], a[:, 0:n], a[:, n:2*n] o_ = where(logical_or(lf1>lf2, isnan(lf1)), lf2, lf1) a_ = where(logical_or(uf1>uf2, isnan(uf2)), uf1, uf2) om, am = nanmin(o_, 1), nanmax(a_, 1) ind = logical_and(am >= r16, om <= r17) r15 = logical_and(r15, ind) aor20 = a - o if dataType in [int8, int16, int32, int64, int]: aor20 = asfarray(aor20) #aor20[aor20 > 1e200] = 1e200 a_t, o_t = a.copy(), o.copy() if dataType in [int8, int16, int32, int64, int]: a_t, o_t = asfarray(a_t), asfarray(o_t) if r16 == r17: val = r17 a_t[a_t > val + tol] = val + tol o_t[o_t < val - tol] = val - tol r24 = a_t - o_t tmp = r24 / aor20 tmp[logical_or(isinf(o), isinf(a))] = 1e-10 # (to prevent inf/inf=nan); TODO: rework it tmp[r24 == 0.0] = 1.0 # may be encountered if a == o, especially for integer probs tmp[tmp<1e-300] = 1e-300 # TODO: improve it #nlh += log2(aor20)# TODO: mb use other #nlh -= log2(a-r17) + log2(r16-o) #nlh += log2((a-r17)/ aor20) + log2((r16-o)/ aor20) # TODO: for non-exact interval quality increase nlh while moving from 0.5*(e-y) tmp[val > a] = 0 tmp[val < o] = 0 elif isfinite(r16) and not isfinite(r17): tmp = (a - r16 + tol) / aor20 tmp[logical_and(isinf(o), logical_not(isinf(a)))] = 1e-10 # (to prevent inf/inf=nan); TODO: rework it tmp[isinf(a)] = 1-1e-10 # (to prevent inf/inf=nan); TODO: rework it #tmp = (a - r16) / aor20 #NEW # o_t[o_t < r16 - tol] = r16 - tol # #ind = a_t>o # #a_t[ind] = o[ind] # #o_t[o_t < r16 - tol] = r16 - tol # r24 = a - o_t # tmp = r24 / aor20 #tmp = (a - r16) / aor20f tmp[tmp<1e-300] = 1e-300 # TODO: improve it tmp[tmp>1.0] = 1.0 tmp[r16 > a] = 0 #tmp[r16 - tol <= o] = 1 tmp[r16 <= o] = 1 elif isfinite(r17) and not isfinite(r16): tmp = (r17-a+tol) / aor20 tmp[isinf(o)] = 1-1e-10 # (to prevent inf/inf=nan);TODO: rework it tmp[logical_and(isinf(a), logical_not(isinf(o)))] = 1e-10 # (to prevent inf/inf=nan); TODO: rework it #tmp = (r17-o) / aor20 #NEW # a_t[a_t > r17 + tol] = r17 + tol # # #r24 = a - r17 # r24 = a_t - o # #r24[r24<0] = 0.0 # tmp = r24 / aor20 tmp[tmp<1e-300] = 1e-300 # TODO: improve it tmp[tmp>1.0] = 1.0 tmp[r17 < o] = 0 #tmp[r17+tol >= a] = 1 tmp[r17 >= a] = 1 else: p.err('this part of interalg code is unimplemented for double-box-bound constraints yet') nlh -= log2(tmp) ind = where(r15)[0] lj = ind.size if lj != m: y = take(y, ind, axis=0, out=y[:lj]) e = take(e, ind, axis=0, out=e[:lj]) nlh = take(nlh, ind, axis=0, out=nlh[:lj]) return y, e, nlh, None, DefiniteRange, None# indT ; todo: rework it! def processConstraints2(C0, y, e, p, dataType): n = p.n m = y.shape[0] nlh = zeros((m, 2*n)) nlh_0 = zeros(m) DefiniteRange = True indT = empty(m, bool) indT.fill(False) if len(p._discreteVarsNumList): adjustDiscreteVarBounds(y, e, p) for c, f, lb, ub, tol in C0: m = y.shape[0] # is changed in the cycle if m == 0: return y.reshape(0, n), e.reshape(0, n), nlh.reshape(0, 2*n), None, True, False #return y.reshape(0, n), e.reshape(0, n), nlh.reshape(0, 2*n), residual.reshape(0, 2*n), True, False if p.solver.dataHandling == 'sorted': tol = 0 New = 1 if New: # for v in p._discreteVarsList: # adjust_ux_WithDiscreteDomain(e, v) # adjust_lx_WithDiscreteDomain(y, v) T0, res, DefiniteRange2 = c.nlh(y, e, p, dataType) DefiniteRange = logical_and(DefiniteRange, DefiniteRange2) # TODO: rework it #T0 = -log2(T0) assert T0.ndim <= 1 #T02 = hstack((T0, T0)) nlh_0 += T0 # TODO: rework it for case len(p._freeVarsList) >> 1 for j, v in enumerate(p._freeVarsList): tmp = res.get(v, None) if tmp is None: pass else: #tmp = -log2(tmp) nlh[:, n+j] += tmp[:, tmp.shape[1]/2:].flatten() - T0 nlh[:, j] += tmp[:, :tmp.shape[1]/2].flatten() - T0 else: domain = oopoint([(v, (y[:, k], e[:, k])) for k, v in enumerate(p._freeVarsList)], skipArrayCast=True) domain.isMultiPoint = True domain.dictOfFixedFuncs = p.dictOfFixedFuncs r, r0 = f.iqg(domain, dataType) dep = f._getDep().intersection(domain.keys()) # TODO: Improve it o, a = r0.lb, r0.ub # using tile to make shape like it was divided into 2 boxes # todo: optimize it tmp = getSmoothNLH(tile(o, (2, 1)), tile(a, (2, 1)), lb, ub, tol, m, dataType) #T02 = tmp #tmp, res0 = getNLH(tile(o, (2, 1)), tile(a, (2, 1)), lb, ub, tol, m, zeros((m, 2)), dataType) T0 = -log2(tmp[:, tmp.shape[1]/2:].flatten()) #isFiniteT0 = all(isfinite(T0)) for j, v in enumerate(p._freeVarsList): if v in dep: o, a = vstack((r[v][0].lb, r[v][1].lb)), vstack((r[v][0].ub, r[v][1].ub)) # TODO: 1) FIX IT it for matrix definiteRange # 2) seems like DefiniteRange = (True, True) for any variable is enough for whole range to be defined in the involved node DefiniteRange = logical_and(DefiniteRange, r[v][0].definiteRange) DefiniteRange = logical_and(DefiniteRange, r[v][1].definiteRange) tmp = -log2(getSmoothNLH(o, a, lb, ub, tol, m, dataType)) nlh[:, n+j] += tmp[:, tmp.shape[1]/2:].flatten() - T0 nlh[:, j] += tmp[:, :tmp.shape[1]/2].flatten() - T0 # if isFiniteT0: # nlh[:, n+j] -= T0 # nlh[:, j] -= T0 #nlh[:, n+j] += (tmp[:, tmp.shape[1]/2:]-T0).flatten() #nlh[:, j] += (tmp[:, :tmp.shape[1]/2]-T0).flatten() # residual[:, n+j] += res[:, 0] # residual[:, j] += res[:, 1] else:#if not isFiniteT0: #pass # TODO: get rid of it nlh[:, j] += T0.flatten() nlh[:, n+j] += T0.flatten() # residual[:, n+j] += res0[:, 0] # residual[:, j] += res0[:, 0] # if isFiniteT0: # nlh[:, j] += T0.flatten() # nlh[:, n+j] += T0.flatten() ind = where(logical_and(any(isfinite(nlh), 1), isfinite(nlh_0)))[0] lj = ind.size if lj != m: y = take(y, ind, axis=0, out=y[:lj]) e = take(e, ind, axis=0, out=e[:lj]) nlh = take(nlh, ind, axis=0, out=nlh[:lj]) nlh_0 = nlh_0[ind] # residual = take(residual, ind, axis=0, out=residual[:lj]) indT = indT[ind] if asarray(DefiniteRange).size != 1: DefiniteRange = take(DefiniteRange, ind, axis=0, out=DefiniteRange[:lj]) ind = logical_not(isfinite((nlh))) if any(ind): indT[any(ind, 1)] = True ind_l, ind_u = ind[:, :ind.shape[1]/2], ind[:, ind.shape[1]/2:] tmp_l, tmp_u = 0.5 * (y[ind_l] + e[ind_l]), 0.5 * (y[ind_u] + e[ind_u]) y[ind_l], e[ind_u] = tmp_l, tmp_u # TODO: mb implement it if len(p._discreteVarsNumList): if tmp_l.ndim > 1: adjustDiscreteVarBounds(tmp_l, tmp_u, p) else: adjustDiscreteVarBounds(y, e, p) # adjustDiscreteVarBounds(y, e, p) nlh_l, nlh_u = nlh[:, nlh.shape[1]/2:], nlh[:, :nlh.shape[1]/2] # copy() is used because += and -= operators are involved on nlh in this cycle and probably some other computations nlh_l[ind_u], nlh_u[ind_l] = nlh_u[ind_u].copy(), nlh_l[ind_l].copy() if New: # !! matrix - vector nlh += nlh_0.reshape(-1, 1) # print nlh # from numpy import diff # print diff(nlh) residual = None return y, e, nlh, residual, DefiniteRange, indT #def updateNLH(c, y, e, nlh, p): openopt-0.38+svn1589/openopt/solvers/UkrOpt/interalgLLR.py000066400000000000000000000677111175775750500234560ustar00rootroot00000000000000from numpy import tile, isnan, array, atleast_1d, asarray, logical_and, all, logical_or, any, nan, isinf, \ arange, vstack, inf, where, logical_not, take, argmax, argmin, abs, hstack, empty, insert, isfinite, append, atleast_2d, \ prod, sqrt, int16, int32, int64, log2, log, searchsorted, cumprod from FuncDesigner import oopoint from interalgT import * try: from bottleneck import nanargmin, nanmin, nanargmax, nanmax except ImportError: from numpy import nanmin, nanargmin, nanargmax, nanmax #def func82(y, e, vv, f, dataType, pool=None, nProc=1): # if pool is None: # return func82_seq(y, e, vv, f, dataType) # from numpy import array_split # yl, el = array_split(y, nProc), array_split(e, nProc) # Args = [(yl[i], el[i], vv, lf, uf) for s in ss] # R = func82_seq(y, e, vv, f, dataType) def func82(y, e, vv, f, dataType, p): domain = oopoint([(v, (y[:, i], e[:, i])) for i, v in enumerate(vv)], skipArrayCast=True, isMultiPoint=True) domain.dictOfFixedFuncs = p.dictOfFixedFuncs r, r0 = f.iqg(domain, dataType) dep = f._getDep() # TODO: Rework it for fixed vars o_l, o_u, a_l, a_u = [], [], [], [] definiteRange = r0.definiteRange for v in vv: # !!!! TODO: rework and optimize it if v in dep: o_l.append(r[v][0].lb) o_u.append(r[v][1].lb) a_l.append(r[v][0].ub) a_u.append(r[v][1].ub) definiteRange = logical_and(definiteRange, r[v][0].definiteRange) definiteRange = logical_and(definiteRange, r[v][1].definiteRange) else: o_l.append(r0.lb) o_u.append(r0.lb) a_l.append(r0.ub) a_u.append(r0.ub) #definiteRange = logical_and(definiteRange, r0.definiteRange) o, a = hstack(o_l+o_u), hstack(a_l+a_u) return o, a, definiteRange def func10(y, e, vv): m, n = y.shape LB = [[] for i in range(n)] UB = [[] for i in range(n)] r4 = (y + e) / 2 # TODO: remove the cycle #T1, T2 = tile(y, (2*n,1)), tile(e, (2*n,1)) for i in range(n): t1, t2 = tile(y[:, i], 2*n), tile(e[:, i], 2*n) #t1, t2 = T1[:, i], T2[:, i] #T1[(n+i)*m:(n+i+1)*m, i] = T2[i*m:(i+1)*m, i] = r4[:, i] t1[(n+i)*m:(n+i+1)*m] = t2[i*m:(i+1)*m] = r4[:, i] # if vv[i].domain is bool: # indINQ = y[:, i] != e[:, i] # tmp = t1[(n+i)*m:(n+i+1)*m] # tmp[indINQ] = 1 # tmp = t2[i*m:(i+1)*m] # tmp[indINQ] = 0 # if vv[i].domain is bool: # t1[(n+i)*m:(n+i+1)*m] = 1 # t2[i*m:(i+1)*m] = 0 # else: # t1[(n+i)*m:(n+i+1)*m] = t2[i*m:(i+1)*m] = r4[:, i] LB[i], UB[i] = t1, t2 #### LB[i], UB[i] = T1[:, i], T2[:, i] # sh1, sh2, inds = [], [], [] # for i in range(n): # sh1+= arange((n+i)*m, (n+i+1)*m).tolist() # inds += [i]*m # sh2 += arange(i*m, (i+1)*m).tolist() # sh1, sh2, inds = asdf(m, n) # asdf2(T1, T2, r4, sh1, sh2, inds) #domain = dict([(v, (T1[:, i], T2[:, i])) for i, v in enumerate(vv)]) domain = dict([(v, (LB[i], UB[i])) for i, v in enumerate(vv)]) domain = oopoint(domain, skipArrayCast = True) domain.isMultiPoint = True return domain def func8(domain, func, dataType): TMP = func.interval(domain, dataType) #assert TMP.lb.dtype == dataType return asarray(TMP.lb, dtype=dataType), asarray(TMP.ub, dtype=dataType), TMP.definiteRange def getr4Values(vv, y, e, tnlh, func, C, contol, dataType, p): #print where(y), where(e!=1) n = y.shape[1] # TODO: rework it wrt nlh #cs = dict([(key, asarray((val[0]+val[1])/2, dataType)) for key, val in domain.items()]) if tnlh is None:# or p.probType =='MOP': wr4 = (y+e) / 2 adjustr4WithDiscreteVariables(wr4, p) #cs = dict([(oovar, asarray((y[:, i]+e[:, i])/2, dataType)) for i, oovar in enumerate(vv)]) cs = dict([(oovar, asarray(wr4[:, i], dataType)) for i, oovar in enumerate(vv)]) else: tnlh = tnlh.copy() tnlh[atleast_1d(tnlh<1e-300)] = 1e-300 # to prevent division by zero tnlh[atleast_1d(isnan(tnlh))] = inf #- check it! tnlh_l_inv, tnlh_u_inv = 1.0 / tnlh[:, :n], 1.0 / tnlh[:, n:] wr4 = (y * tnlh_l_inv + e * tnlh_u_inv) / (tnlh_l_inv + tnlh_u_inv) ind = tnlh_l_inv == tnlh_u_inv # especially important for tnlh_l_inv == tnlh_u_inv = 0 wr4[ind] = (y[ind] + e[ind]) / 2 adjustr4WithDiscreteVariables(wr4, p) cs = dict([(oovar, asarray(wr4[:, i], dataType)) for i, oovar in enumerate(vv)]) cs = oopoint(cs, skipArrayCast = True) cs.isMultiPoint = True cs.update(p.dictOfFixedFuncs) m = y.shape[0] if len(C) != 0: r15 = empty(m, bool) r15.fill(True) for _c, f, r16, r17 in C: c = f(cs) ind = logical_and(c >= r16, c <= r17) # here r16 and r17 are already shifted by required tolerance r15 = logical_and(r15, ind) else: r15 = True isMOP = p.probType =='MOP' if not any(r15): F = empty(m, dataType) F.fill(2**31-2 if dataType in (int32, int64, int) else nan) if isMOP: FF = [F for k in range(p.nf)] elif all(r15): if isMOP: FF = [fun(cs) for fun in func] else: F = func(cs) else: #cs = dict([(oovar, (y[r15, i] + e[r15, i])/2) for i, oovar in enumerate(vv)]) #cs = ooPoint(cs, skipArrayCast = True) #cs.isMultiPoint = True if isMOP: FF = [] for fun in func: tmp = fun(cs) F = empty(m, dataType) F.fill(2**31-15 if dataType in (int32, int64, int) else nan) F[r15] = tmp[r15] FF.append(F) else: tmp = asarray(func(cs), dataType) F = empty(m, dataType) F.fill(2**31-15 if dataType in (int16, int32, int64, int) else nan) F[r15] = tmp[r15] if isMOP: return array(FF).T.reshape(m, len(func)).tolist(), wr4.tolist() else: #print F return atleast_1d(F) , wr4 def adjustr4WithDiscreteVariables(wr4, p): for i in p._discreteVarsNumList: v = p._freeVarsList[i] if v.domain is bool or v.domain is 'bool': wr4[:, i] = where(wr4[:, i]<0.5, 0, 1) else: tmp = wr4[:, i] d = v.domain ind = searchsorted(d, tmp, side='left') ind2 = searchsorted(d, tmp, side='right') ind3 = where(ind!=ind2)[0] Tmp = tmp[ind3].copy() ind[ind==d.size] -= 1 # may be due to roundoff errors ind[ind==1] = 0 ind2[ind2==d.size] -=1 ind2[ind2==0] = 1 # may be due to roundoff errors tmp1 = asarray(d[ind], p.solver.dataType) tmp2 = asarray(d[ind2], p.solver.dataType) if Tmp.size!=0: if str(tmp1.dtype).startswith('int'): Tmp = asarray(Tmp, p.solver.dataType) tmp2[ind3] = Tmp.copy() tmp1[ind3] = Tmp.copy() tmp = where(abs(tmp-tmp1) maxActiveNodes: an1, _in = an[:maxActiveNodes], an[maxActiveNodes:] else: an1, _in = an, array([], object) # Changes! l0 = len(an1) if getattr(an1[0], 'tnlh_curr_best', None) is not None: #t0 = an1[0].tnlh_curr_best tnlh_curr_best_values = asarray([node.tnlh_curr_best for node in an1]) #changes tmp = 2 ** (-tnlh_curr_best_values) Tmp = -cumprod(1.0-tmp) ind2 = searchsorted(Tmp, -0.05) #changes end # ind = min((ind, ind2)) ind = ind2 # ind = maxActiveNodes #M = max((5, maxActiveNodes/2, ind)) #M = ind n = an[0].y.size M = max((5, int(maxActiveNodes/n), ind)) M = ind # M = max((5, maxActiveNodes/5, ind)) #if M == 0: M = 1 tmp1, tmp2 = an1[:M], an1[M:] an1 = tmp1 _in = hstack((tmp2, _in)) l1 = len(an1) # changes end #print maxActiveNodes, len(an1), len(_in) return an1, _in def func1(tnlhf, tnlhf_curr, residual, y, e, o, a, _s_prev, p, indT): m, n = y.shape w = arange(m) if p.probType == 'IP': oc_modL, oc_modU = o[:, :n], o[:, n:] ac_modL, ac_modU = a[:, :n], a[:, n:] # # TODO: handle nans mino = where(oc_modL < oc_modU, oc_modL, oc_modU) maxa = where(ac_modL < ac_modU, ac_modU, ac_modL) # Prev tmp = a[:, 0:n]-o[:, 0:n]+a[:, n:]-o[:, n:] t = nanargmin(tmp,1) d = 0.5*tmp[w, t] #New # tmp = a - o # t_ = nanargmin(tmp,1) # t = t_% n # d = tmp[w, t_] # ind = 2**(-n) >= (_s_prev - d)/asarray(d, 'float64') ind = 2**(1.0/n) * d >= _s_prev #new # ind = 2**(1.0/n) * d >= nanmax(maxa-mino, 1) #ind = 2**(-n) >= (_s_prev - _s)/asarray(_s, 'float64') #s2 = nanmin(maxa - mino, 1) #print (abs(s2/_s)) # Prev _s = nanmin(maxa - mino, 1) # New #_s = nanmax(maxa - mino, 1) # _s = nanmax(a - o, 1) #ind = _s_prev <= _s + ((2**-n / log(2)) if n > 15 else log2(1+2**-n)) indD = logical_not(ind) indD = ind indD = None #print len(where(indD)[0]), len(where(logical_not(indD))[0]) # elif p.probType == 'MOP': # # raise 'unimplemented' else: if p.solver.dataHandling == 'sorted': _s = func13(o, a) t = nanargmin(a, 1) % n d = nanmax([a[w, t] - o[w, t], a[w, n+t] - o[w, n+t]], 0) ## !!!! Don't replace it by (_s_prev /d- 1) to omit rounding errors ### #ind = 2**(-n) >= (_s_prev - d)/asarray(d, 'float64') #NEW ind = d >= _s_prev / 2 ** (1.0e-12/n) #ind = d >= _s_prev / 2 ** (1.0/n) indD = empty(m, bool) indD.fill(True) #ind.fill(False) ################################################### elif p.solver.dataHandling == 'raw': if p.probType == 'MOP': t = p._t[:m] p._t = p._t[m:] d = _s = p.__s[:m] p.__s = p.__s[m:] else: # tnlh_1, tnlh_2 = tnlhf[:, 0:n], tnlhf[:, n:] # TNHLF_min = where(logical_or(tnlh_1 > tnlh_2, isnan(tnlh_1)), tnlh_2, tnlh_1) # # Set _s # _s = nanmin(TNHLF_min, 1) T = tnlhf_curr tnlh_curr_1, tnlh_curr_2 = T[:, 0:n], T[:, n:] TNHL_curr_min = where(logical_or(tnlh_curr_1 < tnlh_curr_2, isnan(tnlh_curr_2)), tnlh_curr_1, tnlh_curr_2) t = nanargmin(TNHL_curr_min, 1) T = tnlhf d = nanmin(vstack(([T[w, t], T[w, n+t]])), 0) _s = d #OLD #!#!#!#! Don't replace it by _s_prev - d <= ... to omit inf-inf = nan !#!#!# #ind = _s_prev <= d + ((2**-n / log(2)) if n > 15 else log2(1+2**-n)) #ind = _s_prev - d <= ((2**-n / log(2)) if n > 15 else log2(1+2**-n)) #NEW if any(_s_prev < d): pass ind = _s_prev <= d + 1.0/n # T = TNHL_curr_min #ind2 = nanmin(TNHL_curr_min, 0) indQ = d >= _s_prev - 1.0/n #indQ = logical_and(indQ, False) indD = logical_or(indQ, logical_not(indT)) # print _s_prev[:2], d[:2] #print len(where(indD)[0]), len(where(indQ)[0]), len(where(indT)[0]) #print _s_prev - d ################################################### #d = ((tnlh[w, t]* tnlh[w, n+t])**0.5) else: assert 0 if any(ind): # print _s_prev # print ((_s_prev -d)*n)[r10] # print('ind length: %d' % len(where(ind)[0])) # print where(ind)[0].size bs = e[ind] - y[ind] t[ind] = nanargmax(bs, 1) # ordinary numpy.argmax can be used as well #print t, _s return t, _s, indD def func13(o, a): m, n = o.shape n /= 2 # if case == 1: # U1, U2 = a[:, :n].copy(), a[:, n:] # #TODO: mb use nanmax(concatenate((U1,U2),3),3) instead? # U1 = where(logical_or(U1= node.o[I]: # print '1' # else: # print i, I, node.o[n+I] , node.o[I], node.key, node.a[n+I] , node.a[I], node.nlhc[n+I], node.nlhc[I] node.key = node.o[n+I] node._s = _s[i] if isRaw: node.tnlh_curr[I] = node.tnlh_curr[n+I] node.tnlh_curr_best = nanmin(node.tnlh_curr) #assert node.o[n+I] >= node.o[I] #lx, ux = node.y, node.e lx, ux = yc[i], ec[i] if nn: #node.o[I], node.a[I] = node.o[n+I], node.a[n+I] node.o[I], node.a[I] = node.o[n+I], node.a[n+I] node.o[node.onode.a[n+I]] = node.o[n+I], node.a[n+I] else: node.o[n+I], node.a[n+I] = node.o[I], node.a[I] node.o[node.onode.a[I]] = node.o[I], node.a[I] # if p.solver.dataHandling == 'raw': for Attr in ('nlhf','nlhc', 'tnlhf', 'tnlh_curr', 'tnlh_all'): r = getattr(node, Attr, None) if r is not None: if nn: r[I] = r[n+I] else: r[n+I] = r[I] mx = ux.copy() mx[I] = Midles[i]#0.5*(lx[I] + ux[I]) list_lx.append(lx) list_ux.append(mx) node.y = lx.copy() node.y[I] = Midles[i]#0.5*(lx[I] + ux[I]) if updateTC: node.indtc = True _s_new.append(node._s) sn.append(node) for i in tag_2: node = an1Candidates[i] I = t[i] node.key = node.o[I] node._s = _s[i] # for raw only if isRaw: node.tnlh_curr[n+I] = node.tnlh_curr[I] node.tnlh_curr_best = nanmin(node.tnlh_curr) #assert node.o[I] >= node.o[n+I] #lx, ux = node.y, node.e lx, ux = yc[i], ec[i] if nn: node.o[n+I], node.a[n+I] = node.o[I], node.a[I] node.o[node.onode.a[I]] = node.o[I], node.a[I] else: node.o[I], node.a[I] = node.o[n+I], node.a[n+I] node.o[node.onode.a[n+I]] = node.o[n+I], node.a[n+I] for Attr in ('nlhf','nlhc', 'tnlhf', 'tnlh_curr', 'tnlh_all'): r = getattr(node, Attr, None) if r is not None: if nn: r[n+I] = r[I] else: r[I] = r[n+I] mx = lx.copy() mx[I] = Midles[i]#0.5*(lx[I] + ux[I]) list_lx.append(mx) list_ux.append(ux) node.e = ux.copy() node.e[I] = Midles[i]#0.5*(lx[I] + ux[I]) if updateTC: node.indtc = True _s_new.append(node._s) sn.append(node) for i in tag_all: node = an1Candidates[i] I = t[i] #lx, ux = node.y, node.e lx, ux = yc[i], ec[i] mx = ux.copy() mx[I] = Midles[i]#0.5 * (lx[I] + ux[I]) list_lx.append(lx) list_ux.append(mx) mx = lx.copy() mx[I] = Midles[i]#0.5 * (lx[I] + ux[I]) #mx[n+ t] = 0.5 * (lx[n + t] + ux[n + t]) list_lx.append(mx) list_ux.append(ux) #_s_new += [_s[i]] * 2 _s_new.append(_s[i]) _s_new.append(_s[i]) # print 'y_new:', vstack(list_lx) # print 'e_new:', vstack(list_ux) # print '_s_new:', hstack(_s) _in = sn + _in.tolist() if p.solver.dataHandling == 'sorted': _in.sort(key = lambda obj: obj.key) else: #pass _in.sort(key = lambda obj: obj.tnlh_curr_best) # print 'tag 1:', len(tag_1), 'tag 2:', len(tag_2), 'tag all:', len(tag_all) # print 'lx:', list_lx # print 'sn lx:', [node.y for node in sn] # print 'ux:', list_ux # print 'sn ux:', [node.e for node in sn] # print '-'*10 #print '!', vstack(list_lx), vstack(list_ux), hstack(_s_new) NEW_lx, NEW_ux, NEW__in, NEW__s = \ vstack(list_lx), vstack(list_ux), array(_in), hstack(_s_new) return NEW_lx, NEW_ux, NEW__in, NEW__s NewD = 1 if NewD and indD is not None: s4d = _s[indD] sf = _s[logical_not(indD)] _s = hstack((s4d, s4d, sf)) yf, ef = yc[logical_not(indD)], ec[logical_not(indD)] yc, ec = yc[indD], ec[indD] t = t[indD] else: _s = tile(_s, 2) yc, ec, tnlhf_curr_local = func2(yc, ec, t, vv, tnlhf_curr) if NewD and indD is not None: yc = vstack((yc, yf)) ec = vstack((ec, ef)) if maxSolutions == 1 or len(solutions) == 0: y, e, Tnlhf_curr_local = yc, ec, tnlhf_curr_local break # TODO: change cycle variable if len(solutions) >> maxActiveNodes for i in range(len(solutions)): ind = logical_and(all(yc >= r11[i], 1), all(ec <= r12[i], 1)) if any(ind): j = where(logical_not(ind))[0] lj = j.size yc = take(yc, j, axis=0, out=yc[:lj]) ec = take(ec, j, axis=0, out=ec[:lj]) _s = _s[j] if tnlhf_curr_local is not None: tnlhf_curr_local = tnlhf_curr_local[j] y.append(yc) e.append(ec) S.append(_s) #Tnlhf_curr_local.append(tnlhf_curr_local) N += yc.shape[0] if len(_in) == 0 or N >= maxActiveNodes: y, e, _s = vstack(y), vstack(e), hstack(S) #Tnlhf_curr_local = hstack(Tnlhf_curr_local) break # if Tnlhf_curr_local is not None and len(Tnlhf_curr_local) != 0 and Tnlhf_curr_local[0] is not None: # #print len(where(isfinite(Tnlhf_curr_local))[0]), Tnlhf_curr_local.size # pass # print 'y_prev:', y # print 'e_prev:', e # print '_s_prev:', hstack(_s) #print 'prev!', y, e, _s # from numpy import array_equal # if not array_equal(NEW_lx.sort(), y.sort()): # pass # if not array_equal(NEW_ux.sort(), e.sort()): # pass # if not array_equal(NEW__s.sort(), _s.sort()): # pass #, NEW_ux, NEW__in, NEW__s return y, e, _in, _s Fields = ['key', 'y', 'e', 'nlhf','nlhc', 'indtc','residual','o', 'a', '_s'] MOP_Fields = ['y', 'e', 'nlhf','nlhc', 'indtc','residual','o', 'a', '_s'] #FuncValFields = ['key', 'y', 'e', 'nlhf','nlhc', 'o', 'a', '_s','r18', 'r19'] IP_fields = ['key', 'minres', 'minres_ind', 'complementary_minres', 'y', 'e', 'o', 'a', '_s','F', 'volume', 'volumeResidual'] def func11(y, e, nlhc, indTC, residual, o, a, _s, p): m, n = y.shape if p.probType == "IP": w = arange(m) # TODO: omit recalculation from func1 ind = nanargmin(a[:, 0:n] - o[:, 0:n] + a[:, n:] - o[:, n:], 1) sup_inf_diff = 0.5*(a[w, ind] - o[w, ind] + a[w, n+ind] - o[w, n+ind]) diffao = a - o minres_ind = nanargmin(diffao, 1) minres = diffao[w, minres_ind] complementary_minres = diffao[w, where(minres_ind ff if any(ind): t1 = a[ind] t2 = o[ind] # TODO: check discrete cases Tmp = (ff-t2) / (t1-t2) Tmp[t1==t2] = 0.0 # for discrete cases tmp[ind] *= Tmp tmp[ff - ff) _lf = _lf[ind] _uf = _uf[ind] _lf[_lf>ff] = ff _lf[_lf<-ff] = -ff _uf[_uf<-ff] = -ff _uf[_uf>ff] = ff r20 = a[ind] - o[ind] Tmp = 1.0 - (_uf - _lf) / r20 Tmp[r20==0] = 0.0 # for discrete cases tmp[ind] *= Tmp #raise('unimplemented yet') # if any(tmp<0) or any(tmp>1): # raise 0 # debug # s1, s2 = tmp[tmp==0].size, tmp[tmp==1].size # s1, s2 = s1 / float(tmp.size), s2 / float(tmp.size) # print 'size 0: %0.2f size 1: %0.2f rest: %0.2f' % (s1, s2, 1-s1-s2) # debug end new = 0 if new: ind_0 = tmp == 0.0 ind_1 = tmp == 1.0 r[ind_1] = inf ind_m = logical_not(logical_and(ind_0, ind_1)) #r[ind_m] -= log1p(-tmp[ind_m]) * 1.4426950408889634 r[ind_m] -= log1p(-tmp[ind_m]) * 1.4426950408889634 #r20 = log2(1-tmp[ind_m]) #* 1.4426950408889634 else: r -= log1p(-tmp) * 1.4426950408889634 # log2(e) #r -= r20 return r from multiprocessing import Pool def r43(targets, SolutionsF, lf, uf, pool, nProc): lf, uf = asarray(lf), asarray(uf) target_vals = [t.val for t in targets] target_tols = [t.tol for t in targets] if nProc == 1 or len(SolutionsF) <= 1: return r43_seq((target_vals, target_tols, SolutionsF, lf, uf)) splitBySolutions = True #if len(SolutionsF) > max((4*nProc, )) if splitBySolutions: ss = array_split(SolutionsF, nProc) Args = [(target_vals, target_tols, s, lf, uf) for s in ss] result = pool.imap_unordered(r43_seq, Args)#, callback = cb) r = [elem for elem in result if elem is not None] return PythonSum(r) else: lf2 = array_split(lf, nProc) uf2 = array_split(uf, nProc) Args = [(target_vals, target_tols, SolutionsF, lf2[i], uf2[i]) for i in range(nProc)] result = pool.map(r43_seq, Args) r = [elem for elem in result if elem is not None] return vstack(r) def r14MOP(p, nlhc, residual, definiteRange, y, e, vv, asdf1, C, r40, itn, g, nNodes, \ r41, fTol, Solutions, varTols, _in, dataType, \ maxNodes, _s, indTC, xRecord): assert p.probType == 'MOP' if len(p._discreteVarsNumList): adjustDiscreteVarBounds(y, e, p) if itn == 0: # TODO: change for constrained probs _s = atleast_1d(inf) if p.nProc != 1: p.pool = Pool(processes = p.nProc) else: p.pool = None ol, al = [], [] targets = p.targets # TODO: check it m, n = y.shape ol, al = [[] for k in range(m)], [[] for k in range(m)] for i, t in enumerate(targets): o, a, definiteRange = func82(y, e, vv, t.func, dataType, p) o, a = o.reshape(2*n, m).T, a.reshape(2*n, m).T for j in range(m): ol[j].append(o[j]) al[j].append(a[j]) #ol.append(o.reshape(2*n, m).T.tolist()) #al.append(a.reshape(2*n, m).T.tolist()) nlhf = r43(targets, Solutions.F, ol, al, p.pool, p.nProc) fo_prev = 0 # TODO: remove NaN nodes here if y.size == 0: return _in, g, fo_prev, _s, Solutions, xRecord, r41, r40 nodes = func11(y, e, nlhc, indTC, residual, ol, al, _s, p) #y, e = func4(y, e, o, a, fo) newNLH = False assert p.solver.dataHandling == 'raw', '"sorted" mode is unimplemented for MOP yet' if nlhf is None: tnlh_curr = nlhc elif nlhc is None: tnlh_curr = nlhf else: tnlh_curr = nlhf + nlhc asdf1 = [t.func for t in p.targets] r5F, r5Coords = getr4Values(vv, y, e, tnlh_curr, asdf1, C, p.contol, dataType, p) nIncome, nOutcome = r44(Solutions, r5Coords, r5F, targets, p.solver.sigma) fo = 0 # unused for MOP # TODO: better of nlhc for unconstrained probs if len(_in) != 0: an = hstack((nodes, _in)) else: an = atleast_1d(nodes) # if nIncome != 0 or not hasattr(an[0], 'tnlh_all'): hasNewParetoNodes = False if nIncome == 0 else True if hasNewParetoNodes: ol2 = [node.o for node in an] al2 = [node.a for node in an] nlhc2 = [node.nlhc for node in an] nlhf2 = r43(targets, Solutions.F, ol2, al2, p.pool, p.nProc) tnlh_all = asarray(nlhc2) if nlhf2 is None else nlhf2 if nlhc2[0] is None else asarray(nlhc2) + nlhf2 else: tnlh_all = vstack([tnlh_curr] + [node.tnlh_all for node in _in]) if len(_in) != 0 else tnlh_curr for i, node in enumerate(nodes): node.tnlh_all = tnlh_all[i] r10 = logical_not(any(isfinite(tnlh_all), 1)) if any(r10): ind = where(logical_not(r10))[0] #an = take(an, ind, axis=0, out=an[:ind.size]) an = asarray(an[ind]) tnlh_all = take(tnlh_all, ind, axis=0, out=tnlh_all[:ind.size]) # else: # tnlh_all = hstack([node.tnlh_all for node in an]) T1, T2 = tnlh_all[:, :tnlh_all.shape[1]/2], tnlh_all[:, tnlh_all.shape[1]/2:] T = where(logical_or(T1 < T2, isnan(T2)), T1, T2) t = nanargmin(T, 1) w = arange(t.size) NN = T[w, t].flatten() for i, node in enumerate(an): node.tnlh_all = tnlh_all[i] node.tnlh_curr_best = NN[i] astnlh = argsort(NN) an = an[astnlh] p._t = t # TODO: form _s in other level (for active nodes only), to reduce calculations if len(an) != 0: nlhf_fixed = asarray([node.nlhf for node in an]) nlhc_fixed = asarray([node.nlhc for node in an]) T = nlhf_fixed + nlhc_fixed if nlhc_fixed[0] is not None else nlhf_fixed p.__s = \ nanmin(vstack(([T[w, t], T[w, n+t]])), 0) else: p.__s = array([]) # p._nObtainedSolutions = len(solutions) # if p._nObtainedSolutions > maxSolutions: # solutions = solutions[:maxSolutions] # p.istop = 0 # p.msg = 'user-defined maximal number of solutions (p.maxSolutions = %d) has been exeeded' % p.maxSolutions # return an, g, fo, None, solutions, coords, xRecord, r41, r40 # TODO: fix it p._frontLength = len(Solutions.F) p._nIncome = nIncome p._nOutcome = nOutcome p.iterfcn(p.x0) #print('iter: %d (%d) frontLenght: %d' %(p.iter, itn, len(Solutions.coords))) if p.istop != 0: return an, g, fo, None, Solutions, xRecord, r41, r40 #an, g = func9(an, fo, g, p) nn = maxNodes#1 if asdf1.isUncycled and all(isfinite(o)) and p._isOnlyBoxBounded and not p.probType.startswith('MI') else maxNodes an, g = func5(an, nn, g, p) nNodes.append(len(an)) return an, g, fo, _s, Solutions, xRecord, r41, r40 def r44(Solutions, r5Coords, r5F, targets, sigma): # print Solutions.F # if len(Solutions.F) != Solutions.coords.shape[0]: # raise 0 # TODO: rework it #sf = asarray(Solutions.F) nIncome, nOutcome = 0, 0 m= len(r5Coords) n = len(r5Coords[0]) # TODO: mb use inplace r5Coords / r5F modification instead? for j in range(m): if isnan(r5F[0][0]): continue if Solutions.coords.size == 0: Solutions.coords = array(r5Coords[j]).reshape(1, -1) Solutions.F.append(r5F[0]) nIncome += 1 continue M = Solutions.coords.shape[0] r47 = empty(M, bool) r47.fill(False) # r48 = empty(M, bool) # r48.fill(False) for i, target in enumerate(targets): f = r5F[j][i] # TODO: rewrite it F = asarray([Solutions.F[k][i] for k in range(M)]) #d = f - F # vector-matrix val, tol = target.val, target.tol Tol = sigma * tol if val == inf: r52 = f > F + Tol # r36olution_better = f <= F#-tol elif val == -inf: r52 = f < F - Tol # r36olution_better = f >= F#tol else: r52 = abs(f - val) < abs(F - val) - Tol # r36olution_better = abs(f - val) >= abs(Solutions.F[i] - val)#-tol # abs(Solutions.F[i] - target) < abs(f[i] - target) + tol r47 = logical_or(r47, r52) # r48 = logical_or(r48, r36olution_better) accept_c = all(r47) #print sum(asarray(Solutions.F))/asarray(Solutions.F).size if accept_c: nIncome += 1 #new r48 = empty(M, bool) r48.fill(False) for i, target in enumerate(targets): f = r5F[j][i] F = asarray([Solutions.F[k][i] for k in range(M)]) val, tol = target.val, target.tol if val == inf: r36olution_better = f < F elif val == -inf: r36olution_better = f > F else: r36olution_better = abs(f - val) > abs(F - val) #assert 0, 'unimplemented yet' r48 = logical_or(r48, r36olution_better) r49 = logical_not(r48) remove_s = any(r49) if remove_s:# and False : r50 = where(r49)[0] nOutcome += r50.size Solutions.coords[r50[0]] = r5Coords[j] Solutions.F[r50[0]] = r5F[j] if r50.size > 1: r49[r50[0]] = False indLeft = logical_not(r49) indLeftPositions = where(indLeft)[0] newSolNumber = Solutions.coords.shape[0] - r50.size + 1 Solutions.coords = take(Solutions.coords, indLeftPositions, axis=0, out = Solutions.coords[:newSolNumber]) solutionsF2 = asarray(Solutions.F, object) solutionsF2 = take(solutionsF2, indLeftPositions, axis=0, out = solutionsF2[:newSolNumber]) Solutions.F = solutionsF2.tolist() else: Solutions.coords = vstack((Solutions.coords, r5Coords[j])) Solutions.F.append(r5F[j]) return nIncome, nOutcome #r43 = lambda targets, SolutionsF, lf, uf: r43_seq([t.val for t in targets], [t.tol for t in targets], SolutionsF, lf, uf) #parallel_r43(targets, SolutionsF, lf, uf, 2) #def r43(targets, Solutions, lf, uf): # lf, uf = asarray(lf), asarray(uf) # solutionsF = Solutions.F # S = len(solutionsF) # if S == 0: return None # # #print '!', asarray(lf).shape, asarray(uf).shape # #lf, uf = asarray(lf), asarray(uf) # # m = len(lf) # n = lf[0][0].size/2 # r = zeros((m, 2*n)) # # ss = asarray(solutionsF) # tmp = ones((S, m, 2*n)) # for i, t in enumerate(targets): # val, tol = t.val, t.tol # # #TODO: mb optimize it # o, a = tile(lf[:, i], (S, 1, 1)), tile(uf[:, i], (S, 1, 1)) # # if val == inf: # ff = s[i] + tol # ind = a > ff # if any(ind): # t1 = a[ind] # t2 = o[ind] # # # TODO: check discrete cases # Tmp = (ff-t2) / (t1-t2) # Tmp[t1==t2] = 0.0 # for discrete cases # tmp[ind] *= Tmp # tmp[ff - ff) # _lf = _lf[ind] # _uf = _uf[ind] # _lf[_lf>ff] = ff # _lf[_lf<-ff] = -ff # _uf[_uf<-ff] = -ff # _uf[_uf>ff] = ff # # r20 = a[ind] - o[ind] # Tmp = 1.0 - (_uf - _lf) / r20 # Tmp[r20==0] = 0.0 # for discrete cases # tmp[ind] *= Tmp # #raise('unimplemented yet') ## if any(tmp<0) or any(tmp>1): ## raise 0 # r -= log1p(-sum(tmp, axis=0)) * 1.4426950408889634 # log2(e) # return r openopt-0.38+svn1589/openopt/solvers/UkrOpt/interalgMisc.py000066400000000000000000000275511175775750500237160ustar00rootroot00000000000000from numpy import tile, isnan, array, atleast_1d, asarray, logical_and, all, searchsorted, logical_or, any, nan, isinf, \ arange, vstack, inf, where, logical_not, take, argmax, argmin, min, abs, hstack, empty, insert, isfinite, append, atleast_2d, \ prod, logical_xor, argsort, asfarray from interalgLLR import * try: from bottleneck import nanargmin, nanmin, nanargmax, nanmax except ImportError: from numpy import nanmin, nanargmin, nanargmax, nanmax # o = hstack([r[v][0].lb for v in vv] + [r[v][1].lb for v in vv]) # a = hstack([r[v][0].ub for v in vv] + [r[v][1].ub for v in vv]) # definiteRange = hstack([r[v][0].definiteRange for v in vv] + [r[v][1].definiteRange for v in vv]) # # TODO: rework all(definiteRange) # return o, a, all(definiteRange) def r14(p, nlhc, residual, definiteRange, y, e, vv, asdf1, C, r40, itn, g, nNodes, \ r41, fTol, Solutions, varTols, _in, dataType, \ maxNodes, _s, indTC, xRecord): isSNLE = p.probType in ('NLSP', 'SNLE') maxSolutions, solutions, coords = Solutions.maxNum, Solutions.solutions, Solutions.coords if len(p._discreteVarsNumList): adjustDiscreteVarBounds(y, e, p) if itn == 0: # TODO: change for constrained probs _s = atleast_1d(inf) o, a, r41 = r45(y, e, vv, p, asdf1, dataType, r41, nlhc) fo_prev = float(0 if isSNLE else min((r41, r40 - (fTol if maxSolutions == 1 else 0)))) if fo_prev > 1e300: fo_prev = 1e300 y, e, o, a, _s, nlhc, residual = func7(y, e, o, a, _s, nlhc, residual) if y.size == 0: return _in, g, fo_prev, _s, Solutions, xRecord, r41, r40 nodes = func11(y, e, nlhc, indTC, residual, o, a, _s, p) #nodes, g = func9(nodes, fo_prev, g, p) #y, e = func4(y, e, o, a, fo) if p.solver.dataHandling == 'raw': tmp = o.copy() tmp[tmp > fo_prev] = -inf M = atleast_1d(nanmax(tmp, 1)) for i, node in enumerate(nodes): node.th_key = M[i] if not isSNLE: for node in nodes: node.fo = fo_prev if nlhc is not None: for i, node in enumerate(nodes): node.tnlhf = node.nlhf + node.nlhc else: for i, node in enumerate(nodes): node.tnlhf = node.nlhf # TODO: improve it an = hstack((nodes, _in)) #tnlh_fixed = vstack([node.tnlhf for node in an]) tnlh_fixed_local = vstack([node.tnlhf for node in nodes])#tnlh_fixed[:len(nodes)] tmp = a.copy() tmp[tmp>fo_prev] = fo_prev tnlh_curr = tnlh_fixed_local - log2(tmp - o) tnlh_curr_best = nanmin(tnlh_curr, 1) for i, node in enumerate(nodes): node.tnlh_curr = tnlh_curr[i] node.tnlh_curr_best = tnlh_curr_best[i] # TODO: use it instead of code above #tnlh_curr = tnlh_fixed_local - log2(where() - o) else: tnlh_curr = None # TODO: don't calculate PointVals for zero-p regions PointVals, PointCoords = getr4Values(vv, y, e, tnlh_curr, asdf1, C, p.contol, dataType, p) if PointVals.size != 0: xk, Min = r2(PointVals, PointCoords, dataType) else: # all points have been removed by func7 xk = p.xk Min = nan if r40 > Min: r40 = Min xRecord = xk.copy()# TODO: is copy required? if r41 > Min: r41 = Min fo = float(0 if isSNLE else min((r41, r40 - (fTol if maxSolutions == 1 else 0)))) if p.solver.dataHandling == 'raw': if fo == inf or isSNLE: tnlh_curr = vstack([node.tnlhf for node in an])#tnlh_fixed else: if fo != fo_prev: fos = array([node.fo for node in an]) #prev #ind_update = where(fos > fo + 0.01* fTol)[0] #new th_keys = array([node.th_key for node in an]) delta_fos = fos - fo ind_update = where(10 * delta_fos > fos - th_keys)[0] nodesToUpdate = an[ind_update] update_nlh = True if ind_update.size != 0 else False # print 'o MB:', float(o_tmp.nbytes) / 1e6 # print 'percent:', 100*float(ind_update.size) / len(an) if update_nlh: # from time import time # tt = time() updateNodes(nodesToUpdate, fo) # if not hasattr(p, 'Time'): # p.Time = time() - tt # else: # p.Time += time() - tt tmp = asarray([node.key for node in an]) r10 = where(tmp > fo)[0] if r10.size != 0: mino = [an[i].key for i in r10] mmlf = nanmin(asarray(mino)) g = nanmin((g, mmlf)) #an = an[where(logical_not(ind0))[0]] NN = atleast_1d([node.tnlh_curr_best for node in an]) r10 = logical_or(isnan(NN), NN == inf) if any(r10): ind = where(logical_not(r10))[0] an = an[ind] #tnlh = take(tnlh, ind, axis=0, out=tnlh[:ind.size]) #NN = take(NN, ind, axis=0, out=NN[:ind.size]) NN = NN[ind] if not isSNLE or p.maxSolutions == 1: astnlh = argsort(NN) an = an[astnlh] else: #if p.solver.dataHandling == 'sorted': if isSNLE and p.maxSolutions != 1: an = hstack((nodes, _in)) else: nodes.sort(key = lambda obj: obj.key) if len(_in) == 0: an = nodes else: arr1 = [node.key for node in _in] arr2 = [node.key for node in nodes] r10 = searchsorted(arr1, arr2) an = insert(_in, r10, nodes) # if p.debug: # arr = array([node.key for node in an]) # #print arr[0] # assert all(arr[1:]>= arr[:-1]) if maxSolutions != 1: Solutions = r46(o, a, PointCoords, PointVals, fTol, varTols, Solutions) p._nObtainedSolutions = len(solutions) if p._nObtainedSolutions > maxSolutions: solutions = solutions[:maxSolutions] p.istop = 0 p.msg = 'user-defined maximal number of solutions (p.maxSolutions = %d) has been exeeded' % p.maxSolutions return an, g, fo, None, Solutions, xRecord, r41, r40 #p.iterfcn(xk, Min) p.iterfcn(xRecord, r40) if p.istop != 0: return an, g, fo, None, Solutions, xRecord, r41, r40 if isSNLE and maxSolutions == 1 and Min <= fTol: # TODO: rework it for nonlinear systems with non-bound constraints p.istop, p.msg = 1000, 'required solution has been obtained' return an, g, fo, None, Solutions, xRecord, r41, r40 # print 'p.iter:', p.iter # print '1:', len(an) # print min([node.key for node in an]) # print 'p.iter:',p.iter, 'fo:', fo, 'g:', g # print 'min(keys):', min([node.key for node in an]) an, g = func9(an, fo, g, p) # print 'g_new:', g # print '2:', len(an) nn = maxNodes#1 if asdf1.isUncycled and all(isfinite(o)) and p._isOnlyBoxBounded and not p.probType.startswith('MI') else maxNodes an, g = func5(an, nn, g, p) nNodes.append(len(an)) return an, g, fo, _s, Solutions, xRecord, r41, r40 def r46(o, a, PointCoords, PointVals, fTol, varTols, Solutions): solutions, coords = Solutions.solutions, Solutions.coords n = o.shape[1] / 2 #L1, L2 = o[:, :n], o[:, n:] #omin = where(logical_or(L1 > L2, isnan(L1)), L2, L1) #r5Ind = where(logical_and(PointVals < fTol, nanmax(omin, 1) == 0.0))[0] r5Ind = where(PointVals < fTol)[0] r5 = PointCoords[r5Ind] for c in r5: if len(solutions) == 0 or not any(all(abs(c - coords) < varTols, 1)): solutions.append(c) #coords = asarray(solutions) Solutions.coords = append(Solutions.coords, c.reshape(1, -1), 0) return Solutions def r45(y, e, vv, p, asdf1, dataType, r41, nlhc): Case = p.solver.intervalObtaining if Case == 1: ip = func10(y, e, vv) #o, a = func8(ip, asdf1 + 1e10*p._cons_obj if p._cons_obj is not None else asdf1, dataType) o, a, definiteRange = func8(ip, asdf1, dataType) elif Case == 2: # o2, a2, definiteRange2 = func82(y, e, vv, asdf1 + p._cons_obj if p._cons_obj is not None else asdf1, dataType) # o, a, definiteRange = o2, a2, definiteRange2 f = asdf1 o, a, definiteRange = func82(y, e, vv, f, dataType, p) elif Case == 3: # Used for debug ip = func10(y, e, vv) o, a, definiteRange = func8(ip, asdf1, dataType) f = asdf1 o2, a2, definiteRange2 = func82(y, e, vv, f, dataType, p) from numpy import allclose lf, lf2 = o.copy(), o2.copy() lf[isnan(lf)] = 0.123 lf2[isnan(lf2)] = 0.123 if not allclose(lf, lf2, atol=1e-10): raise 0 uf, uf2 = a.copy(), a2.copy() uf[isnan(uf)] = 0.123 uf2[isnan(uf2)] = 0.123 if not allclose(uf, uf2, atol=1e-10): raise 0 if p.debug and any(a + 1e-15 < o): p.warn('interval lower bound exceeds upper bound, it seems to be FuncDesigner kernel bug') if p.debug and any(logical_xor(isnan(o), isnan(a))): p.err('bug in FuncDesigner intervals engine') m, n = e.shape o, a = o.reshape(2*n, m).T, a.reshape(2*n, m).T if asdf1.isUncycled and p.probType not in ('SNLE', 'NLSP') and not p.probType.startswith('MI') \ and len(p._discreteVarsList)==0:# for SNLE fo = 0 # TODO: # handle constraints with restricted domain and matrix definiteRange if all(definiteRange): # TODO: if o has at least one -inf => prob is unbounded tmp1 = o[nlhc==0] if nlhc is not None else o if tmp1.size != 0: tmp1 = nanmin(tmp1) ## to prevent roundoff issues ## tmp1 += 1e-14*abs(tmp1) if tmp1 == 0: tmp1 = 1e-300 ###################### r41 = nanmin((r41, tmp1)) else: pass return o, a, r41 def updateNodes(nodesToUpdate, fo): if len(nodesToUpdate) == 0: return a_tmp = array([node.a for node in nodesToUpdate]) Tmp = a_tmp Tmp[Tmp>fo] = fo o_tmp = array([node.o for node in nodesToUpdate]) Tmp -= o_tmp tnlh_all_new = - log2(Tmp) del Tmp, a_tmp tnlh_all_new += vstack([node.tnlhf for node in nodesToUpdate])#tnlh_fixed[ind_update] tnlh_curr_best = nanmin(tnlh_all_new, 1) o_tmp[o_tmp > fo] = -inf M = atleast_1d(nanmax(o_tmp, 1)) for j, node in enumerate(nodesToUpdate): node.fo = fo node.tnlh_curr = tnlh_all_new[j] node.tnlh_curr_best = tnlh_curr_best[j] node.th_key = M[j] # return tnlh_all_new, tnlh_curr_best, M #from multiprocessing import Pool #from numpy import array_split #def updateNodes(nodesToUpdate, fo, p): # if p.nProc == 1: # Chunks = [nodesToUpdate] # result = [updateNodesEngine((nodesToUpdate, fo))] # else: # Chunks = array_split(nodesToUpdate, p.nProc) # if not hasattr(p, 'pool'): # p.pool = Pool(processes = p.nProc) # #result = p.pool.imap(updateNodesEngine, [(c, fo) for c in Chunks]) # result = p.pool.map(updateNodesEngine, [(c, fo) for c in Chunks]) # for i, elem in enumerate(result): # if elem is None: continue # tnlh_all_new, tnlh_curr_best, M = elem # for j, node in enumerate(Chunks[i]): # node.fo = fo # node.tnlh_curr = tnlh_all_new[j] # node.tnlh_curr_best = tnlh_curr_best[j] # node.th_key = M[j] openopt-0.38+svn1589/openopt/solvers/UkrOpt/interalgODE.py000066400000000000000000000146161175775750500234300ustar00rootroot00000000000000from numpy import asfarray, cumsum, diff, empty, hstack, asscalar, linspace, asarray, max, abs, floor, atleast_1d, where, \ logical_not, argsort, logical_and, vstack, any, sum, array, nan, all from numpy.linalg import norm from openopt import NLP from FuncDesigner import oopoint def interalg_ODE_routine(p, solver): isIP = p.probType == 'IP' isODE = p.probType == 'ODE' if isODE: f, y0, t, r30, ftol = p.equations, p.x0, p.timeVariable, p.times, p.ftol assert len(f) == 1, 'multiple ODE equations are unimplemented for FuncDesigner yet' f = list(f.values())[0] elif isIP: assert p.n == 1 and p.__isNoMoreThanBoxBounded__() f, y0, ftol = p.user.f[0], 0.0, p.ftol if p.fTol is not None: ftol = p.fTol t = list(f._getDep())[0] r30 = p.domain[t] p.iterfcn(p.point([nan]*p.n)) else: p.err('incorrect prob type for interalg ODE routine') eq_var = list(p._x0.keys())[0] dataType = solver.dataType if type(ftol) == int: ftol = float(ftol) # e.g. someone set ftol = 1 # Currently ftol is scalar, in future it can be array of same length as timeArray if len(r30) < 2: p.err('length ot time array must be at least 2') # if any(r30[1:] < r30[:-1]): # p.err('currently interalg can handle only time arrays sorted is ascending order') # if any(r30 < 0): # p.err('currently interalg can handle only time arrays with positive values') # if p.times[0] != 0: # p.err('currently solver interalg requires times start from zero') r37 = abs(r30[-1] - r30[0]) r28 = asarray(atleast_1d(r30[0]), dataType) r29 = asarray(atleast_1d(r30[-1]), dataType) storedr28 = [] r27 = [] r31 = [] r32 = [] r33 = ftol F = 0.0 p._Residual = 0 # Main cycle for itn in range(p.maxIter+1): if r30[-1] > r30[0]: mp = oopoint({t: [r28, r29]}, skipArrayCast = True) else: mp = oopoint({t: [r29, r28]}, skipArrayCast = True) mp.isMultiPoint = True delta_y = f.interval(mp, dataType) if not all(delta_y.definiteRange): p.err(''' solving ODE with interalg is implemented for definite (real) range only, no NaN values in integrand are allowed''') # TODO: perform check on NaNs r34 = atleast_1d(delta_y.ub) r35 = atleast_1d(delta_y.lb) r36 = atleast_1d(r34 - r35 <= 0.95 * r33 / r37) ind = where(r36)[0] if isODE: storedr28.append(r28[ind]) r27.append(r29[ind]) r31.append(r34[ind]) r32.append(r35[ind]) else: assert isIP F += 0.5 * sum((r29[ind]-r28[ind])*(r34[ind]+r35[ind])) #p._Residual = p._residual + 0.5*sum((abs(r34) +abs(r35)) * (r29 - r28)) if ind.size != 0: tmp = abs(r29[ind] - r28[ind]) Tmp = sum((r34[ind] - r35[ind]) * tmp) r33 -= Tmp if isIP: p._residual += Tmp r37 -= sum(tmp) ind = where(logical_not(r36))[0] if ind.size == 0: p.istop = 1000 p.msg = 'problem has been solved according to required tolerance' break # OLD # for i in ind: # t0, t1 = r28[i], r29[i] # t_m = 0.5 * (t0+t1) # newr28.append(t0) # newr28.append(t_m) # newr29.append(t_m) # newr29.append(t1) # NEW r38, r39 = r28[ind], r29[ind] r40 = 0.5 * (r38 + r39) r28 = vstack((r38, r40)).flatten() r29 = vstack((r40, r39)).flatten() # !!! unestablished !!! if isODE: p.iterfcn(fk = r33/ftol) elif isIP: p.iterfcn(xk=array(nan), fk=F, rk = 0) else: p.err('bug in interalgODE.py') if p.istop != 0 : break #print(itn, r28.size) if isODE: t0, t1, lb, ub = hstack(storedr28), hstack(r27), hstack(r32), hstack(r31) ind = argsort(t0) if r30[0] > r30[-1]: ind = ind[::-1] # reverse t0, t1, lb, ub = t0[ind], t1[ind], lb[ind], ub[ind] lb, ub = y0+(lb*(t1-t0)).cumsum(), y0+(ub*(t1-t0)).cumsum() #y_var = p._x0.keys()[0] #p.xf = p.xk = 0.5*(lb+ub) p.extras = {'startTimes': t0, 'endTimes': t1, eq_var:{'infinums': lb, 'supremums': ub}} return t0, t1, lb, ub elif isIP: P = p.point([nan]*p.n) P._f = F P._mr = r33 P._mrName = 'None' P._mrInd = 0 # p.xk = array([nan]*p.n) # p.rk = r33 # p.fk = F #p._Residual = p.iterfcn(asarray([nan]*p.n), fk=F, rk=0) else: p.err('incorrect prob type in interalg ODE routine') # for i in range(len(T)-1): # TODO: is or is not T0 = 0? # delta_y = f.interval({t: [T[i], T[i+1]]}) # delta_y_supremum[i] = delta_y.ub # delta_y_infinum[i] = delta_y.lb # diffTime = diff(T) # y_supremums, y_infinums = cumsum(delta_y_supremum*diffTime), cumsum(delta_y_infinum*diffTime) # # #!!!! Currently for all time points ub-lb <= ftol is required, not only for those from timeArray # # if y_supremums[-1] - y_infinums[-1] < ftol: # # hence prob is solved # if p.debug: # assert all(y_supremums - y_infinums < ftol) # break # # d = (y_supremums - y_infinums) / ftol # minNewPoints = int(2*(y_supremums[-1] - y_infinums[-1])/ftol) + 1000 # #print(itn, minNewPoints) # tmp = diff(d) # tmp /= max(tmp) # ff = lambda x: abs(floor(x*tmp).sum() - minNewPoints) ## def ff(x): ## #print x ## return abs(floor(x*tmp).sum() - minNewPoints) # P = NLP(ff, 0, lb = 1, ub = minNewPoints+1, iprint = -1) # R = P.solve('goldenSection', ftol = max((2, 0.1*minNewPoints)), xtol = 0.0) # if p.debug: assert R.stopCase == 1 # tmp = floor(R.xf * tmp) # D = asarray(hstack((0, tmp)) , int) # # newT = [] # for i in range(len(T)-1): # m = 1 + D[i] # newT.append(linspace(T[i], T[i+1], m, False)) # newT.append(T[-1]) # #print('new T len - prev T len = ', len(hstack(newT)) - len(T)) # T = hstack(newT) ## ind = where(d > ftol) openopt-0.38+svn1589/openopt/solvers/UkrOpt/interalgT.py000066400000000000000000000146061175775750500232230ustar00rootroot00000000000000from numpy import isnan, take, any, all, logical_or, logical_and, logical_not, atleast_1d, where, \ asarray, inf, nan, argmin, argsort, tile, searchsorted, isfinite from bisect import bisect_right from FuncDesigner.Interval import adjust_lx_WithDiscreteDomain, adjust_ux_WithDiscreteDomain try: from bottleneck import nanargmin, nanmin, nanargmax, nanmax except ImportError: from numpy import nanmin, nanargmin, nanargmax, nanmax def r42(o, a): # n_where_lx_2 = where(y <=-0.5)[0].size # n_where_ux_2 = where(e >=-0.5)[0].size # nn = n_where_lx_2 + n_where_ux_2 m, N = o.shape n = N / 2 o_l, o_u = o[:, :n], o[:, n:] a_l, a_u = a[:, :n], a[:, n:] o_m = where(logical_or(o_l < o_u, isnan(o_u)), o_l, o_u) a_m = where(logical_or(a_l < a_u, isnan(a_l)), a_u, a_l) o_M = nanmax(o_m, 1) a_M = nanmin(a_m, 1) # TODO: make it matrix-vector componentwise o_M = tile(o_M.reshape(m, 1), (1, 2*n)) ind = o < o_M if any(ind): o[ind] = o_M[ind] a_M = tile(a_M.reshape(m, 1), (1, 2*n)) ind = a > a_M if any(ind): a[ind] = a_M[ind] # n_where_lx_2 = where(y <=-0.5)[0].size # n_where_ux_2 = where(e >=-0.5)[0].size # nn2 = n_where_lx_2 + n_where_ux_2 # print nn, nn2 # assert nn == nn2 def adjustDiscreteVarBounds(y, e, p): n = p.n # TODO: remove the cycle, use vectorization for i in p._discreteVarsNumList: v = p._freeVarsList[i] adjust_lx_WithDiscreteDomain(y[:, i], v) adjust_ux_WithDiscreteDomain(e[:, i], v) ind = any(y>e, 1) if any(ind): ind = where(logical_not(ind))[0] s = ind.size y = take(y, ind, axis=0, out=y[:s]) e = take(e, ind, axis=0, out=e[:s]) def func7(y, e, o, a, _s, nlhc, residual): r10 = logical_and(all(isnan(o), 1), all(isnan(a), 1)) if any(r10): j = where(logical_not(r10))[0] lj = j.size y = take(y, j, axis=0, out=y[:lj]) e = take(e, j, axis=0, out=e[:lj]) o = take(o, j, axis=0, out=o[:lj]) a = take(a, j, axis=0, out=a[:lj]) _s = _s[j] if nlhc is not None: nlhc = take(nlhc, j, axis=0, out=nlhc[:lj]) if residual is not None: residual = take(residual, j, axis=0, out=residual[:lj]) return y, e, o, a, _s, nlhc, residual def func9(an, fo, g, p): #ind = searchsorted(ar, fo, side='right') if p.probType in ('NLSP', 'SNLE') and p.maxSolutions != 1: mino = atleast_1d([node.key for node in an]) ind = mino > 0 if not any(ind): return an, g else: g = nanmin((g, nanmin(mino[ind]))) ind2 = where(logical_not(ind))[0] #an = take(an, ind2, axis=0, out=an[:ind2.size]) an = asarray(an[ind2]) return an, g elif p.solver.dataHandling == 'sorted': #OLD mino = [node.key for node in an] ind = bisect_right(mino, fo) if ind == len(mino): return an, g else: g = nanmin((g, nanmin(atleast_1d(mino[ind])))) return an[:ind], g elif p.solver.dataHandling == 'raw': #NEW mino = [node.key for node in an] mino = atleast_1d(mino) r10 = mino > fo if not any(r10): return an, g else: ind = where(r10)[0] g = nanmin((g, nanmin(atleast_1d(mino)[ind]))) an = asarray(an) ind2 = where(logical_not(r10))[0] #an = take(an, ind2, axis=0, out=an[:ind2.size]) an = asarray(an[ind2]) return an, g # NEW 2 # curr_tnlh = [node.tnlh_curr for node in an] # import warnings # warnings.warn('! fix g') return an, g else: assert 0, 'incorrect nodes remove approach' def func5(an, nn, g, p): m = len(an) if m <= nn: return an, g mino = [node.key for node in an] if nn == 1: # box-bound probs with exact interval analysis ind = argmin(mino) assert ind in (0, 1), 'error in interalg engine' g = nanmin((mino[1-ind], g)) an = atleast_1d([an[ind]]) elif m > nn: if p.solver.dataHandling == 'raw': ind = argsort(mino) th = mino[ind[nn]] ind2 = where(mino < th)[0] g = nanmin((th, g)) #an = take(an, ind2, axis=0, out=an[:ind2.size]) an = an[ind2] else: g = nanmin((mino[nn], g)) an = an[:nn] return an, g def func4(p, y, e, o, a, fo, tnlhf_curr = None): if fo is None and tnlhf_curr is None: return # used in IP cs = (y + e)/2 n = y.shape[1] if tnlhf_curr is not None: tnlh_modL = tnlhf_curr[:, 0:n] ind = logical_not(isfinite(tnlh_modL)) else: s = o[:, 0:n] ind = logical_or(s > fo, isnan(s)) # TODO: assert isnan(s) is same to isnan(a_modL) indT = any(ind, 1) if any(ind): y[ind] = cs[ind] # Changes # ind = logical_and(ind, logical_not(isnan(a[:, n:2*n]))) ## ii = len(where(ind)[0]) ## if ii != 0: print ii if p.probType != 'MOP': a[:, 0:n][ind] = a[:, n:2*n][ind] o[:, 0:n][ind] = o[:, n:2*n][ind] if tnlhf_curr is not None: tnlhf_curr[:, 0:n][ind] = tnlhf_curr[:, n:2*n][ind] # for arr in arrays: # if arr is not None: # arr[:, 0:n][ind] = arr[:, n:2*n][ind] if tnlhf_curr is not None: tnlh_modU = tnlhf_curr[:, n:2*n] ind = logical_not(isfinite(tnlh_modU)) else: q = o[:, n:2*n] ind = logical_or(q > fo, isnan(q)) # TODO: assert isnan(q) is same to isnan(a_modU) indT = logical_or(any(ind, 1), indT) if any(ind): # copy is used to prevent y and e being same array, that may be buggy with discret vars e[ind] = cs[ind].copy() # Changes # ind = logical_and(ind, logical_not(isnan(a[:, n:]))) ## ii = len(where(ind)[0]) ## if ii != 0: print ii if p.probType != 'MOP': a[:, n:2*n][ind] = a[:, 0:n][ind] o[:, n:2*n][ind] = o[:, 0:n][ind] if tnlhf_curr is not None: tnlhf_curr[:, n:2*n][ind] = tnlhf_curr[:, 0:n][ind] # for arr in arrays: # if arr is not None: # arr[:, n:2*n][ind] = arr[:, 0:n][ind] return indT openopt-0.38+svn1589/openopt/solvers/UkrOpt/interalg_oo.py000066400000000000000000000412461175775750500235740ustar00rootroot00000000000000import numpy from numpy import isfinite, all, argmax, where, delete, array, asarray, inf, argmin, hstack, vstack, arange, amin, \ logical_and, float64, ceil, amax, inf, ndarray, isinf, any, logical_or, nan, logical_not, asanyarray, searchsorted, \ logical_xor, empty from numpy.linalg import norm, solve, LinAlgError from openopt.kernel.setDefaultIterFuncs import SMALL_DELTA_X, SMALL_DELTA_F, MAX_NON_SUCCESS, IS_NAN_IN_X from openopt.kernel.baseSolver import * from openopt.kernel.Point import Point from openopt.solvers.UkrOpt.interalgMisc import * from FuncDesigner import sum as fd_sum, abs as fd_abs, max as fd_max, oopoint from ii_engine import * from interalgCons import processConstraints, processConstraints2 from interalgODE import interalg_ODE_routine from interalgMOP import r14MOP from interalgLLR import adjustr4WithDiscreteVariables bottleneck_is_present = False try: from bottleneck import nanargmin, nanargmax, nanmin bottleneck_is_present = True except ImportError: from numpy import nanmin, nanargmin, nanargmax class interalg(baseSolver): __name__ = 'interalg' __license__ = "BSD" __authors__ = "Dmitrey" __alg__ = "" __optionalDataThatCanBeHandled__ = ['lb', 'ub', 'c', 'h', 'A', 'Aeq', 'b', 'beq', 'discreteVars'] iterfcnConnected = True fStart = None dataType = float64 #maxMem = '150MB' maxNodes = 150000 maxActiveNodes = 150 sigma = 0.1 # for MOP, unestablished _requiresBestPointDetection = True __isIterPointAlwaysFeasible__ = lambda self, p: \ p.__isNoMoreThanBoxBounded__() or p.probType in ('MOP', 'IP') #and p.probType != 'IP' _requiresFiniteBoxBounds = True def __init__(self): self.dataHandling = 'auto' self.intervalObtaining = 'auto' def __solver__(self, p): isMOP = p.probType == 'MOP' isOpt = p.probType in ['NLP', 'NSP', 'GLP', 'MINLP'] isODE = p.probType == 'ODE' isSNLE = p.probType in ('NLSP', 'SNLE') if self.intervalObtaining == 'auto': self.intervalObtaining=2 if not p.__isFiniteBoxBounded__() and not isODE: p.err(''' solver %s requires finite lb, ub: lb <= x <= ub (you can use "implicitBoounds") ''' % self.__name__) # if p.fixedVars is not None: # p.err('solver %s cannot handle FuncDesigner problems with some variables declared as fixed' % self.__name__) if p.probType in ('LP', 'MILP'): p.err("the solver can't handle problems of type " + p.probType) if not p.isFDmodel: p.err('solver %s can handle only FuncDesigner problems' % self.__name__) isIP = p.probType == 'IP' if isIP: pb = r14IP p._F = asarray(0, self.dataType) p._residual = 0.0 f_int = p.user.f[0].interval(p.domain, self.dataType) p._r0 = prod(p.ub-p.lb) * (f_int.ub - f_int.lb) p._volume = 0.0 p.kernelIterFuncs.pop(IS_NAN_IN_X) elif isMOP: pb = r14MOP else: pb = r14 for val in p._x0.values(): if isinstance(val, (list, tuple, ndarray)) and len(val) > 1: p.pWarn(''' solver %s currently can handle only single-element variables, use oovars(n) instead of oovar(size=n), elseware correct result is not guaranteed '''% self.__name__) vv = list(p._freeVarsList) x0 = dict([(v, p._x0[v]) for v in vv]) for val in x0.values(): if isinstance(val, (list, tuple, ndarray)) and len(val) > 1: p.err(''' solver %s currently can handle only single-element variables, use oovars(n) instead of oovar(size=n)'''% self.__name__) point = p.point p.kernelIterFuncs.pop(SMALL_DELTA_X, None) p.kernelIterFuncs.pop(SMALL_DELTA_F, None) p.kernelIterFuncs.pop(MAX_NON_SUCCESS, None) if not bottleneck_is_present and not isODE: p.pWarn(''' installation of Python module "bottleneck" (http://berkeleyanalytics.com/bottleneck, available via easy_install, takes several minutes for compilation) could speedup the solver %s''' % self.__name__) n = p.n maxSolutions = p.maxSolutions if maxSolutions == 0: maxSolutions = 10**50 if maxSolutions != 1 and p.fEnough != -inf: p.warn(''' using the solver interalg with non-single solutions mode is not ajusted with fEnough stop criterium yet, it will be omitted ''') p.kernelIterFuncs.pop(FVAL_IS_ENOUGH) nNodes = [] p.extras['nNodes'] = nNodes nActiveNodes = [] p.extras['nActiveNodes'] = nActiveNodes Solutions = Solution() Solutions.maxNum = maxSolutions Solutions.solutions = [] Solutions.coords = array([]).reshape(0, n) p.solutions = Solutions dataType = self.dataType if type(dataType) == str: if not hasattr(numpy, dataType): p.pWarn('your architecture has no type "%s", float64 will be used instead') dataType = 'float64' dataType = getattr(numpy, dataType) lb, ub = asarray(p.lb, dataType).copy(), asarray(p.ub, dataType).copy() fTol = p.fTol if isIP or isODE: if p.ftol is None: if fTol is not None: p.ftol = fTol else: p.err('interalg requires user-supplied ftol (required precision)') if fTol is None: fTol = p.ftol elif fTol != p.ftol: p.err('you have provided both ftol and fTol') if fTol is None and not isMOP: # TODO: require tols for MOP fTol = 1e-7 p.warn('solver %s require p.fTol value (required objective function tolerance); 10^-7 will be used' % self.__name__) xRecord = 0.5 * (lb + ub) adjustr4WithDiscreteVariables(xRecord.reshape(1, -1), p) r40 = inf y = lb.reshape(1, -1) e = ub.reshape(1, -1) r41 = inf # TODO: maybe rework it, especially for constrained case fStart = self.fStart # TODO: remove it after proper SNLE handling implementation if isSNLE: r41 = 0.0 eqs = [fd_abs(elem) for elem in p.user.f] asdf1 = fd_sum(eqs) # TODO: check it, for reducing calculations #C.update([elem == 0 for elem in p.user.f]) elif isMOP: asdf1 = p.user.f Solutions.F = [] if point(p.x0).isFeas(altLinInEq=False): Solutions.solutions.append(p.x0.copy()) Solutions.coords = asarray(Solutions.solutions) Solutions.F.append(p.f(p.x0)) p._solutions = Solutions elif not isODE: asdf1 = p.user.f[0] if p.fOpt is not None: fOpt = p.fOpt if p.goal in ('max', 'maximum'): asdf1 = -asdf1 if p.fOpt is not None: fOpt = -p.fOpt if fStart is not None and fStart < r40: r41 = fStart for X0 in [point(xRecord), point(p.x0)]: if X0.isFeas(altLinInEq=False) and X0.f() < r40: r40 = X0.f() if p.isFeas(p.x0): tmp = asdf1(p._x0) if tmp < r41: r41 = tmp if p.fOpt is not None: if p.fOpt > r41: p.warn('user-provided fOpt seems to be incorrect, ') r41 = p.fOpt if isSNLE: if self.dataHandling == 'raw': p.pWarn(''' this interalg data handling approach ("%s") is unimplemented for SNLE yet, dropping to "sorted"'''%self.dataHandling) # handles 'auto' as well self.dataHandling ='sorted' domain = oopoint([(v, [p.lb[i], p.ub[i]]) for i, v in enumerate(vv)], skipArrayCast=True) domain.dictOfFixedFuncs = p.dictOfFixedFuncs from FuncDesigner.ooFun import BooleanOOFun, SmoothFDConstraint if self.dataHandling == 'auto': if isIP or isODE: self.dataHandling = 'sorted' elif isMOP or p.hasLogicalConstraints: self.dataHandling = 'raw' else: r = p.user.f[0].interval(domain, self.dataType) M = max((max(atleast_1d(abs(r.lb))), max(atleast_1d(abs(r.ub))))) for (c, func, lb, ub, tol) in p._FD.nonBoxCons:#[Elem[1] for Elem in p._FD.nonBoxCons]: if isinstance(c, BooleanOOFun) and not isinstance(c, SmoothFDConstraint): continue r = func.interval(domain, self.dataType) M = max((M, max(atleast_1d(abs(r.lb))))) M = max((M, max(atleast_1d(abs(r.ub))))) self.dataHandling = 'raw' if M < 1e5 else 'sorted' #print M #self.dataHandling = 'sorted' if isIP or (p.__isNoMoreThanBoxBounded__() and n < 50) else 'raw' # TODO: is it required yet? if not isMOP and not p.hasLogicalConstraints: p._isOnlyBoxBounded = p.__isNoMoreThanBoxBounded__() if isODE or (asdf1.isUncycled and p._isOnlyBoxBounded and all(isfinite(p.user.f[0].interval(domain).lb))): #maxNodes = 1 self.dataHandling = 'sorted' if self.dataHandling == 'sorted' and p.hasLogicalConstraints: p.warn("interalg: for general logical constraints only dataHandling='raw' mode works") self.dataHandling = 'raw' self.maxActiveNodes = int(self.maxActiveNodes) # if self.maxActiveNodes < 2: # p.warn('maxActiveNodes should be at least 2 while you have provided %d. Setting it to 2.' % self.maxActiveNodes) self.maxNodes = int(self.maxNodes) _in = array([], object) g = inf C = p._FD.nonBoxConsWithTolShift C0 = p._FD.nonBoxCons # if isOpt: # r = [] # for (elem, lb, ub, tol) in C0: # if tol == 0: tol = p.contol # if lb == ub: # r.append(fd_max((fd_abs(elem-lb)-tol, 0)) * (fTol/tol)) # elif lb == -inf: # r.append(fd_max((0, elem-ub-tol)) * (fTol/tol)) # elif ub == inf: # r.append(fd_max((0, lb-elem-tol)) * (fTol/tol)) # else: # p.err('finite box constraints are unimplemented for interalg yet') #p._cons_obj = 1e100 * fd_sum(r) if len(r) != 0 else None #p._cons_obj = fd_sum(r) if len(r) != 0 else None if isSNLE: C += [(elem==0, elem, -(elem.tol if elem.tol != 0 else p.ftol), (elem.tol if elem.tol != 0 else p.ftol)) for elem in p.user.f] C0 += [(elem==0, elem, 0, 0, (elem.tol if elem.tol != 0 else p.ftol)) for elem in p.user.f] # TODO: hanlde fixed variables here varTols = p.variableTolerances if Solutions.maxNum != 1: if not isSNLE: p.err(''' "search several solutions" mode is unimplemented for the prob type %s yet''' % p.probType) if any(varTols == 0): p.err(''' for the mode "search all solutions" you have to provide all non-zero tolerances for each variable (oovar) ''') pnc = 0 an = [] maxNodes = self.maxNodes _s = nan if isODE or (isIP and p.n == 1): interalg_ODE_routine(p, self) return for itn in range(p.maxIter+10): if len(C0) != 0: Func = processConstraints if self.intervalObtaining == 1 else processConstraints2 y, e, nlhc, residual, definiteRange, indT = Func(C0, y, e, p, dataType) else: nlhc, residual, definiteRange, indT = None, None, True, None if y.size != 0: an, g, fo, _s, Solutions, xRecord, r41, r40 = \ pb(p, nlhc, residual, definiteRange, y, e, vv, asdf1, C, r40, itn, g, \ nNodes, r41, fTol, Solutions, varTols, _in, \ dataType, maxNodes, _s, indT, xRecord) if _s is None: break else: an = _in fo = 0.0 if isSNLE or isMOP else min((r41, r40 - (fTol if Solutions.maxNum == 1 else 0.0))) pnc = max((len(atleast_1d(an)), pnc)) if isIP: y, e, _in, _s = \ func12(an, self.maxActiveNodes, p, Solutions, vv, varTols, inf) else: y, e, _in, _s = \ func12(an, self.maxActiveNodes, p, Solutions, vv, varTols, fo) nActiveNodes.append(y.shape[0]/2) if y.size == 0: if len(Solutions.coords) > 1: p.istop, p.msg = 1001, 'all solutions have been obtained' else: p.istop, p.msg = 1000, 'solution has been obtained' break ############# End of main cycle ############### if not isSNLE and not isIP and not isMOP: if p._bestPoint.betterThan(p.point(p.xk)): p.iterfcn(p._bestPoint) else: p.iterfcn(p.xk) ff = p.fk # ff may be not assigned yet # ff = p._bestPoint.f() # p.xk = p._bestPoint.x if isIP: p.xk = array([nan]*p.n) p.rk = p._residual p.fk = p._F isFeas = len(Solutions.F) != 0 if isMOP else p.isFeas(p.xk) if not isIP else p.rk < fTol if not isFeas and p.istop > 0: p.istop, p.msg = -1000, 'no feasible solution has been obtained' o = asarray([t.o for t in an]) if o.size != 0: g = nanmin([nanmin(o), g]) if not isMOP: p.extras['isRequiredPrecisionReached'] = \ True if ff - g < fTol and isFeas else False # and (k is False or (isSNLE and (p._nObtainedSolutions >= maxSolutions or maxSolutions==1))) if not isMOP and not p.extras['isRequiredPrecisionReached'] and p.istop > 0: p.istop = -1 p.msg = 'required precision is not guarantied' # TODO: simplify it if not isMOP: tmp = [nanmin(hstack((ff, g, o.flatten()))), numpy.asscalar(array((ff)))] if p.goal in ['max', 'maximum']: tmp = (-tmp[1], -tmp[0]) p.extras['extremumBounds'] = tmp if not isIP else 'unimplemented for IP yet' p.solutions = [p._vector2point(s) for s in Solutions.coords] if not isMOP else \ MOPsolutions([p._vector2point(s) for s in Solutions.coords]) if isMOP: for i, s in enumerate(p.solutions): s.useAsMutable = True for j, goal in enumerate(p.user.f): s[goal] = Solutions.F[i][j] s.useAsMutable = False p.solutions.values = asarray(Solutions.F) p.solutions.coords = Solutions.coords if not isMOP and p.maxSolutions == 1: delattr(p, 'solutions') if isSNLE and p.maxSolutions != 1: for v in p._categoricalVars: for elem in r.solutions: elem.useAsMutable = True elem[v] = v.aux_domain[elem[v]] elem.useAsMutable = False if p.iprint >= 0 and not isMOP: # s = 'Solution with required tolerance %0.1e \n is%s guarantied (obtained precision: %0.1e)' \ # %(fTol, '' if p.extras['isRequiredPrecisionReached'] else ' NOT', tmp[1]-tmp[0]) s = 'Solution with required tolerance %0.1e \n is%s guarantied' \ %(fTol, '' if p.extras['isRequiredPrecisionReached'] else ' NOT') if not isIP and p.maxSolutions == 1: s += ' (obtained precision: %0.1e)' % abs(tmp[1]-tmp[0]) if not p.extras['isRequiredPrecisionReached'] and pnc == self.maxNodes: s += '\nincrease maxNodes (current value %d)' % self.maxNodes p.info(s) class Solution: pass class MOPsolutions(list): pass openopt-0.38+svn1589/openopt/solvers/UkrOpt/lincher_oo.py000066400000000000000000000422551175775750500234140ustar00rootroot00000000000000__docformat__ = "restructuredtext en" from numpy import diag, ones, inf, any, copy, sqrt, vstack, concatenate, asarray, nan, where, array, zeros, exp, isfinite from openopt.kernel.baseSolver import * from openopt import LP, QP, NLP, LLSP, NSP from openopt.kernel.ooMisc import WholeRepr2LinConst #from scipy.optimize import line_search as scipy_optimize_linesearch #from scipy.optimize.linesearch import line_search as scipy_optimize_linesearch_f from numpy import arange, sign, hstack from UkrOptMisc import getDirectionOptimPoint, getConstrDirection import os class lincher(baseSolver): __name__ = 'lincher' __license__ = "BSD" __authors__ = "Dmitrey" __alg__ = "a linearization-based solver written in Cherkassy town, Ukraine" __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] __isIterPointAlwaysFeasible__ = lambda self, p: p.__isNoMoreThanBoxBounded__() iterfcnConnected = True def __init__(self): pass def __solver__(self, p): n = p.n x0 = copy(p.x0) xPrev = x0.copy() xf = x0.copy() xk = x0.copy() p.xk = x0.copy() f0 = p.f(x0) fk = f0 ff = f0 p.fk = fk df0 = p.df(x0) ##################################################################### ## #handling box-bounded problems ## if p.__isNoMoreThanBoxBounded__(): ## for k in range(int(p.maxIter)): ## ## #end of handling box-bounded problems isBB = p.__isNoMoreThanBoxBounded__() ## isBB = 0 H = diag(ones(p.n)) if not p.userProvided.c: p.c = lambda x : array([]) p.dc = lambda x : array([]).reshape(0, p.n) if not p.userProvided.h: p.h = lambda x : array([]) p.dh = lambda x : array([]).reshape(0, p.n) p.use_subproblem = 'QP' #p.use_subproblem = 'LLSP' for k in range(p.maxIter+4): if isBB: f0 = p.f(xk) df = p.df(xk) direction = -df f1 = p.f(xk+direction) ind_l = direction<=p.lb-xk direction[ind_l] = (p.lb-xk)[ind_l] ind_u = direction>=p.ub-xk direction[ind_u] = (p.ub-xk)[ind_u] ff = p.f(xk + direction) ## print 'f0', f0, 'f1', f1, 'ff', ff else: mr = p.getMaxResidual(xk) if mr > p.contol: mr_grad = p.getMaxConstrGradient(xk) lb = p.lb - xk #- p.contol/2 ub = p.ub - xk #+ p.contol/2 c, dc, h, dh, df = p.c(xk), p.dc(xk), p.h(xk), p.dh(xk), p.df(xk) A, Aeq = vstack((dc, p.A)), vstack((dh, p.Aeq)) b = concatenate((-c, p.b-p.matmult(p.A,xk))) #+ p.contol/2 beq = concatenate((-h, p.beq-p.matmult(p.Aeq,xk))) if b.size != 0: isFinite = isfinite(b) ind = where(isFinite)[0] A, b = A[ind], b[ind] if beq.size != 0: isFinite = isfinite(beq) ind = where(isFinite)[0] Aeq, beq = Aeq[ind], beq[ind] if p.use_subproblem == 'LP': #linear linprob = LP(df, A=A, Aeq=Aeq, b=b, beq=beq, lb=lb, ub=ub) linprob.iprint = -1 r2 = linprob.solve('cvxopt_glpk') # TODO: replace lpSolve by autoselect if r2.istop <= 0: p.istop = -12 p.msg = "failed to solve LP subproblem" return elif p.use_subproblem == 'QP': #quadratic qp = QP(H=H,f=df, A=A, Aeq=Aeq, b=b, beq=beq, lb=lb, ub = ub) qp.iprint = -1 r2 = qp.solve('cvxopt_qp') # TODO: replace solver by autoselect #r2 = qp.solve('qld') # TODO: replace solver by autoselect if r2.istop <= 0: for i in range(4): if p.debug: p.warn("iter " + str(k) + ": attempt Num " + str(i) + " to solve QP subproblem has failed") #qp.f += 2*N*sum(qp.A,0) A2 = vstack((A, Aeq, -Aeq)) b2 = concatenate((b, beq, -beq)) + pow(10,i)*p.contol qp = QP(H=H,f=df, A=A2, b=b2, iprint = -5) qp.lb = lb - pow(10,i)*p.contol qp.ub = ub + pow(10,i)*p.contol # I guess lb and ub don't matter here try: r2 = qp.solve('cvxopt_qp') # TODO: replace solver by autoselect except: r2.istop = -11 if r2.istop > 0: break if r2.istop <= 0: p.istop = -11 p.msg = "failed to solve QP subproblem" return elif p.use_subproblem == 'LLSP': direction_c = getConstrDirection(p, xk, regularization = 1e-7) else: p.err('incorrect or unknown subproblem') if isBB: X0 = xk.copy() N = 0 result, newX = chLineSearch(p, X0, direction, N, isBB) elif p.use_subproblem != 'LLSP': duals = r2.duals N = 1.05*abs(duals).sum() direction = r2.xf X0 = xk.copy() result, newX = chLineSearch(p, X0, direction, N, isBB) else: # case LLSP direction_f = -df p2 = NSP(LLSsubprobF, [0.8, 0.8], ftol=0, gtol=0, xtol = 1e-5, iprint = -1) p2.args.f = (xk, direction_f, direction_c, p, 1e20) r_subprob = p2.solve('ralg') alpha = r_subprob.xf newX = xk + alpha[0]*direction_f + alpha[1]*direction_c # dw = (direction_f * direction_c).sum() # cos_phi = dw/p.norm(direction_f)/p.norm(direction_c) # res_0, res_1 = p.getMaxResidual(xk), p.getMaxResidual(xk+1e-1*direction_c) # print cos_phi, res_0-res_1 # res_0 = p.getMaxResidual(xk) # optimConstrPoint = getDirectionOptimPoint(p, p.getMaxResidual, xk, direction_c) # res_1 = p.getMaxResidual(optimConstrPoint) # # maxConstrLimit = p.contol #xk = getDirectionOptimPoint(p, p.f, optimConstrPoint, -optimConstrPoint+xk+direction_f, maxConstrLimit = maxConstrLimit) #print 'res_0', res_0, 'res_1', res_1, 'res_2', p.getMaxResidual(xk) #xk = getDirectionOptimPoint(p, p.f, xk, direction_f, maxConstrLimit) #newX = xk.copy() result = 0 # x_0 = X0.copy() # N = j = 0 # while p.getMaxResidual(x_0) > Residual0 + 0.1*p.contol: # j += 1 # x_0 = xk + 0.75**j * (X0-xk) # X0 = x_0 # result, newX = 0, X0 # print 'newIterResidual = ', p.getMaxResidual(x_0) if result != 0: p.istop = result p.xf = newX return xk = newX.copy() fk = p.f(xk) p.xk, p.fk = copy(xk), copy(fk) #p._df = p.df(xk) #################### p.iterfcn() if p.istop: p.xf = xk p.ff = fk #p._df = g FIXME: implement me return class lineSearchFunction(object): def __init__(self, p, x0, N): self.p = p self.x0 = x0 self.N = N def __call__(self, x): return float(self.p.f(x)+self.N*max(self.p.getMaxResidual(x), 0.999*self.p.contol)) def gradient_numerical(self, x): g = zeros(self.p.n) f0 = self.__call__(x) for i in range(self.p.n): x[i] += self.p.diffInt g[i] = self.__call__(x) - f0 x[i] -= self.p.diffInt g /= self.p.diffInt return g def gradient(self, x): N = self.N g = self.p.df(x) + N * self.p.getMaxConstrGradient(x) return g def LLSsubprobF(alpha, x, direction_f, direction_c, p, S=1e30): x2 = x + alpha[0] * direction_f + alpha[1] * direction_c constr = p.getMaxResidual(x2) fval = p.f(x2) return max(constr-p.contol, 0)*S + fval # if constr > p.contol: return S * constr # else: return p.f(x2) def chLineSearch(p, x0, direction, N, isBB): lsF = lineSearchFunction(p, x0, N) c1, c2 = 1e-4, 0.9 result = 0 #ls_solver = 'scipy.optimize.line_search' #ls_solver = 'Matthieu.optimizers.StrongWolfePowellRule' #ls_solver = 'Matthieu.optimizers.BacktrackingSearch' ls_solver = 'Armijo_modified' ## if p.use_subproblem == 'LLSP': ## ls_solver = 'Armijo_modified3' ## else: ## ls_solver = 'Armijo_modified' #debug ## M, K = 1000000, 4 ## x0 = array(1.) ## class example(): ## def __init__(self): pass ## #def __call__(self, x): return M * max(x,array(0.))**K ## def __call__(self, x): return 1e-5*x ## def gradient(self, x): return array(1e-5) ## #def gradient(self, x): return M*K*max(x,array(0.))**(K-1) ## ff = example() ## state = {'direction' : array(-5.5), 'gradient': M*K*x0**(K-1)} ## mylinesearch = line_search.StrongWolfePowellRule(sigma = 0.001) ## destination = mylinesearch(function = ff, origin = x0, step = array(-5.5), state = state) #debug end if ls_solver == 'scipy.optimize.line_search':#TODO: old_fval, old_old_fval old_fval = p.dotmult(lsF.gradient(x0), direction).sum() # just to make old_old_fval = old_fval / 2.0 # alpha0 from scipy line_search 1 results = scipy_optimize_linesearch(lsF, lsF.gradient, x0, direction, lsF.gradient(x0), old_fval, old_old_fval, c1=c1, c2=c2) alpha = results[0] ## results_f = scipy_optimize_linesearch_f(lsF, lsF.gradient, x0, direction, lsF.gradient(x0), old_fval, old_old_fval, c1=c1, c2=c2) ## alpha = results_f[0] destination = x0+alpha*direction elif ls_solver == 'Matthieu.optimizers.BacktrackingSearch': #state = {'direction' : direction} state = {'direction' : direction, 'gradient': lsF.gradient(x0)} mylinesearch = line_search.BacktrackingSearch() destination = mylinesearch(function = lsF, origin = x0, step = direction, state = state) elif ls_solver == 'Matthieu.optimizers.StrongWolfePowellRule': state = {'direction' : direction, 'gradient': lsF.gradient(x0)} mylinesearch = line_search.StrongWolfePowellRule() destination = mylinesearch(function = lsF, origin = x0, step = direction, state = state) elif ls_solver == 'Armijo_modified3': alpha, alpha_min = 1.0, 0.45*p.xtol / p.norm(direction) lsF_x0 = lsF(x0) C1 = abs(c1 * (p.norm(direction)**2).sum()) iterValues.r0 = p.getMaxResidual(x0) #counter = 1 while 1: print 'stage 1' if lsF(x0 + direction*alpha) <= lsF_x0 - alpha * C1 and p.getMaxResidual(x0 + direction*alpha) <= max(p.contol, iterValues.r0): assert alpha>=0 #print counter, C1 break alpha /= 2.0 #counter += 1 if alpha < alpha_min: if p.debug: p.warn('alpha less alpha_min') break if alpha == 1.0: print 'stage 2' K = 1.5 lsF_prev = lsF_x0 for i in range(p.maxLineSearch): lsF_new = lsF(x0 + K * direction*alpha) newConstr = p.getMaxResidual(x0 + K * direction*alpha) if lsF_new > lsF_prev or newConstr > max(p.contol, iterValues.r0): break else: alpha *= K lsF_prev = lsF_new destination = x0 + direction*alpha elif ls_solver == 'Armijo_modified': alpha, alpha_min = 1.0, 0.15*p.xtol / p.norm(direction) grad_x0 = lsF.gradient(x0) #C1 = abs(c1 * p.dotmult(direction, grad_x0).sum()) #if p.debug: print p.dotmult(direction, grad_x0).sum(), p.norm(direction)**2 C1 = abs(c1 * (p.norm(direction)**2).sum()) lsF_x0 = lsF(x0) #counter = 1 while 1: ## print 'stage 11' ## print 'alpha', alpha, 'lsF', lsF(x0 + direction*alpha), 'f', p.f(x0 + direction*alpha), 'maxC', p.getMaxResidual(x0 + direction*alpha) if lsF(x0 + direction*alpha) <= lsF_x0 - alpha * C1: assert alpha>=0 ## print '11 out: alpha = ', alpha break alpha /= 2.0 if alpha < alpha_min: if p.debug: p.warn('alpha less alpha_min') break destination = x0 + direction*alpha #TODO: check lb-ub here? if alpha == 1.0 and not isBB: K = 1.5 lsF_prev = lsF_x0 for i in range(p.maxLineSearch): x_new = x0 + K * direction*alpha ## ind_u, ind_l = x_new>p.ub, x_new= lsF_prev:# - K * alpha * C1: ## print '22 out: alpha = ', alpha break else: destination = x_new alpha *= K lsF_prev = lsF_new elif ls_solver == 'Armijo_modified2': grad_objFun_x0 = p.df(x0) grad_iterValues.r_x0 = p.getMaxConstrGradient(x0) C1_objFun = c1 * p.dotmult(direction, grad_objFun_x0).sum() C1_constr = c1 * p.dotmult(direction, grad_iterValues.r_x0).sum() f0 = p.f(x0) f_prev = f0 allowedConstr_start = max(0.999*p.contol, p.getMaxResidual(x0)) #currConstr = allowedConstr_start + 1.0 alpha, alpha_min = 1.0, 1e-11 isConstrAccepted = False isObjFunAccepted = False #debug ## if p.iter == 100: ## pass while alpha >= alpha_min: x_new = x0 + direction*alpha if not isConstrAccepted: currConstr = p.getMaxResidual(x_new) if currConstr > allowedConstr_start + alpha * C1_constr: #print 'case bigger:', currConstr, allowedConstr #allowedConstr = max(0.999*p.contol, min(allowedConstr, currConstr)) alpha /= 2.0; continue else: AcceptedConstr = max(0.999*p.contol, currConstr) isConstrAccepted = True if not isObjFunAccepted: currConstr = p.getMaxResidual(x_new) #if currConstr > allowedConstr_start + alpha * C1_constr:#min(AcceptedConstr, 0.1*allowedConstr_start): #AllowedConstr2 = 1.2 * AcceptedConstr if currConstr > p.contol and (currConstr > 1.3*AcceptedConstr or currConstr > allowedConstr_start + alpha * C1_constr):# or currConstr > AllowedConstr2): isObjFunAccepted = True alpha = min(1.0, 2.0*alpha)#i.e. return prev alpha value break f_new = p.f(x_new) #if f_new > f_prev: if f_new > f0 + alpha * C1_objFun: alpha /= 2.0 f_prev = f_new continue else: isObjFunAccepted = True # and continue break #print '!!!!!!!!!', alpha #print currConstr, allowedConstr_start, allowedConstr_start + alpha * C1_constr ## else: ## #print 'allowedConstr:', allowedConstr, ' currConstr:', currConstr ## allowedConstr = max(0.999*p.contol, min(allowedConstr, currConstr)) ## print '33' ## alpha /= 2.0 ## continue ## elif p.f(x_new) <= f0 - alpha * C1 and currConstr <= allowedConstr: ## # accept the alpha value ## assert alpha>=0 ## allowedConstr = max(0.99*p.contol, currConstr) ## break if p.debug and alpha < alpha_min: p.warn('alpha less alpha_min') if alpha == 1.0: K = 1.5 f_prev = f0 allowedConstr = allowedConstr_start for i in range(p.maxLineSearch): x_new = x0 + K*direction*alpha f_new = p.f(x_new) if f_new > f_prev or p.getMaxResidual(x_new) > allowedConstr:# - K * alpha * C1: break else: allowedConstr = max(0.99*p.contol, min(allowedConstr, currConstr)) alpha *= K f_new = f_prev destination = x0 + direction*alpha #print 'alpha:', alpha else: p.error('unknown line-search optimizer') return result, destination openopt-0.38+svn1589/openopt/solvers/UkrOpt/nsmm_oo.py000066400000000000000000000036671175775750500227460ustar00rootroot00000000000000from numpy import asfarray, argmax, inf, log10, max from numpy.linalg import norm from openopt.kernel.baseSolver import baseSolver from openopt import NSP from string import rjust class nsmm(baseSolver): __name__ = 'nsmm' __license__ = "BSD" __authors__ = 'Dmitrey Kroshko' __alg__ = "based on Naum Z. Shor r-alg" iterfcnConnected = True __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] __info__ = """ Solves mini-max problem via minimizing max (F[i]) using NSP solver (default UkrOpt.ralg). Can handle user-supplied gradient/subradient (p.df field) If the one is not available - splitting equations to separate functions is recommended (to speedup calculations): f = [func1, func2, ...] or f = ([func1, func2, ...) """ def __init__(self):pass def __solver__(self, p): f = lambda x: max(p.f(x)) def df(x): F = p.f(x) ind = argmax(F) return p.df(x, ind) def iterfcn(*args, **kwargs): p2.primalIterFcn(*args, **kwargs) p.xk = p2.xk.copy() p.fk = p2.fk p.rk = p2.rk p.istop = p2.istop if p.istop and p2.rk <= p2.contol: p.msg = p2.msg p.iterfcn() p2 = NSP(f, p.x0, df=df, xtol = p.xtol, ftol = p.ftol, gtol = p.gtol,\ A=p.A, b=p.b, Aeq=p.Aeq, beq=p.beq, lb=p.lb, ub=p.ub, \ maxFunEvals = p.maxFunEvals, fEnough = p.fEnough, maxIter=p.maxIter, iprint = -1, \ maxtime = p.maxTime, maxCPUTime = p.maxCPUTime, noise = p.noise) if p.userProvided.c: p2.c, p2.dc = p.c, p.dc if p.userProvided.h: p2.h, p2.dh = p.h, p.dh p2.primalIterFcn, p2.iterfcn = p2.iterfcn, iterfcn r2 = p2.solve('ralg') xf = r2.xf p.xk = p.xf = xf p.fk = p.ff = max(p.f(xf)) #p.istop is defined in iterfcn openopt-0.38+svn1589/openopt/solvers/UkrOpt/nssolve_oo.py000066400000000000000000000100171175775750500234500ustar00rootroot00000000000000from numpy import asfarray, argmax, sign, inf, log10, dot from openopt.kernel.ooMisc import norm from openopt.kernel.baseSolver import baseSolver from openopt import NSP from openopt.kernel.setDefaultIterFuncs import IS_MAX_FUN_EVALS_REACHED, FVAL_IS_ENOUGH, SMALL_DELTA_X, SMALL_DELTA_F class nssolve(baseSolver): __name__ = 'nssolve' __license__ = "BSD" __authors__ = 'Dmitrey Kroshko' __alg__ = "based on Naum Z. Shor r-alg" iterfcnConnected = True __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] __isIterPointAlwaysFeasible__ = lambda self, p: p.isUC nspSolver = 'autoselect' __info__ = """ Solves system of non-smooth or noisy equations via (by default) minimizing max residual using NSP solver (default UkrOpt.ralg). Can handle user-supplied gradient/subradient (p.df field) If the one is not available - splitting equations to separate functions is recommended (to speedup calculations): f = [func1, func2, ...] or f = ([func1, func2, ...) ns- can be interpreted as NonSmooth or NoiSy or Naum Shor (Ukrainian academician, my teacher, r-algorithm inventor) """ def __init__(self):pass def __solver__(self, p): if SMALL_DELTA_X in p.kernelIterFuncs.keys(): p.kernelIterFuncs.pop(SMALL_DELTA_X) if SMALL_DELTA_F in p.kernelIterFuncs.keys(): p.kernelIterFuncs.pop(SMALL_DELTA_F) if self.nspSolver == 'autoselect': nspSolver = 'amsg2p' if p.isUC else 'ralg' else: nspSolver = self.nspSolver # nspSolver = 'ralg' way = 3 if nspSolver == 'ralg' else 2 if way == 1: use2 = False f = lambda x: sum(abs(p.f(x))) def df(x): return dot(p.df(x), sign(p.f(x))) elif way == 2: use2 = True f = lambda x: sum(p.f(x)**2) def df(x): return 2.0*dot(p.f(x), p.df(x)) elif way == 3: use2 = False f = lambda x: max(abs(p.f(x))) def df(x): F = p.f(x) ind = argmax(abs(F)) return p.df(x, ind) * sign(F[ind]) FTOL = p.ftol**2 if use2 else p.ftol def iterfcn(*args, **kwargs): p2.primalIterFcn(*args, **kwargs) p.xk = p2.xk.copy() Fk = norm(p.f(p.xk), inf) p.rk = p.getMaxResidual(p.xk) #TODO: ADD p.rk if p.nEvals['f'] > p.maxFunEvals: p.istop = p2.istop = IS_MAX_FUN_EVALS_REACHED elif p2.istop!=0: if Fk < FTOL and p.rk < p.contol: p.istop = 15 msg_contol = '' if p.isUC else 'and contol ' p.msg = 'solution with required ftol ' + msg_contol+ 'has been reached' else: p.istop = p2.istop p.iterfcn() return p.istop p2 = NSP(f, p.x0, df=df, xtol = p.xtol/1e16, gtol = p.gtol/1e16,\ A=p.A, b=p.b, Aeq=p.Aeq, beq=p.beq, lb=p.lb, ub=p.ub, \ maxFunEvals = p.maxFunEvals, fEnough = FTOL, maxIter=p.maxIter, iprint = -1, \ maxtime = p.maxTime, maxCPUTime = p.maxCPUTime, noise = p.noise, fOpt = 0.0) if p.userProvided.c: p2.c, p2.dc = p.c, p.dc if p.userProvided.h: p2.h, p2.dh = p.h, p.dh p2.primalIterFcn, p2.iterfcn = p2.iterfcn, iterfcn if p.debug: p2.iprint = 1 if nspSolver == 'ralg': if p.isUC: p2.ftol = p.ftol / 1e16 else: p2.ftol = 0.0 else: p2.ftol = 0.0 p2.xtol = 0.0 p2.gtol = 0.0 if use2: p2.fTol = 0.5*p.ftol ** 2 else: p2.fTol = 0.5*p.ftol r2 = p2.solve(nspSolver) #xf = fsolve(p.f, p.x0, fprime=p.df, xtol = p.xtol, maxfev = p.maxFunEvals) xf = r2.xf p.xk = p.xf = xf p.fk = p.ff = asfarray(norm(p.f(xf), inf)).flatten() #p.istop is defined in iterfcn openopt-0.38+svn1589/openopt/solvers/UkrOpt/ralg_oo.py000066400000000000000000001156561175775750500227230ustar00rootroot00000000000000from numpy import diag, array, sqrt, eye, ones, inf, any, copy, zeros, dot, where, all, tile, sum, nan, isfinite, float64, isnan, log10, \ max, sign, array_equal, nonzero, ix_, arctan, pi, logical_not, logical_and, atleast_2d, matrix from openopt.kernel.ooMisc import norm try: from numpy.linalg import solve, LinAlgError except ImportError: LinAlgError = Exception def solve(*args, **kw): print('ralg with equality constraints is unimplemented yet') raise Exception('ralg with equality constraints is unimplemented yet') from openopt.kernel.nonOptMisc import scipyAbsentMsg, scipyInstalled, isPyPy import openopt #try: # from numpy.linalg import cond #except: # print 'warning: no cond in numpy.linalg, matrix B rejuvenation check will be omitted' # cond = lambda Matrix: 1 from openopt.kernel.baseSolver import * from openopt.kernel.Point import Point from openopt.kernel.ooMisc import economyMult, Len from openopt.kernel.setDefaultIterFuncs import * from openopt.solvers.UkrOpt.UkrOptMisc import getBestPointAfterTurn class ralg(baseSolver): __name__ = 'ralg' __license__ = "BSD" __authors__ = "Dmitrey" __alg__ = "Naum Z. Shor R-algorithm with adaptive space dilation & some modifications" __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] iterfcnConnected = True _canHandleScipySparse = True #ralg default parameters B = None # if provided it should be square matrix of shape nVars x nVars alp, h0, nh, q1, q2 = 2.0, 1.0, 3, 'default:0.9 for NLP, 1.0 for NSP', 1.1 hmult = 0.5 S = 0 T = float64 dilationType = 'plain difference' showLS = False show_hs = False showRej = False showRes = False show_nnan = False doBackwardSearch = True approach = 'all active' newLinEq = True new_bs = True skipPrevIterNaNsInDilation = True innerState = None penalties = False # True means for nonlinear equalities only #new_s = False def needRej(self, p, b, g, g_dilated): # r = log10(1e15 * p.norm(g_dilated) / p.norm(g)) # if isfinite(r): # p.debugmsg('%d' % int(r)) #p.debugmsg('%0.2g'%(p.norm(g_dilated) / p.norm(g))) return 1e14 * p.norm(g_dilated) < p.norm(g) #checkTurnByGradient = True def __init__(self): pass def __solver__(self, p): alp, h0, nh, q1, q2 = self.alp, self.h0, self.nh, self.q1, self.q2 if isPyPy and not p.isUC: p.err("ralg hasn't been ported to PyPy for constrained problems yet") if type(q1) == str: if p.probType== 'NLP' and p.isUC: q1 = 0.9 else: q1 = 1.0 T = self.T # alternatively instead of alp=self.alp etc you can use directly self.alp etc n = p.n x0 = p.x0 if p.nbeq == 0 or any(abs(p._get_AeqX_eq_Beq_residuals(x0))>p.contol): # TODO: add "or Aeqconstraints(x0) out of contol" x0[x0p.ub] = p.ub[x0>p.ub] ind_box_eq = where(p.lb==p.ub)[0] nEQ = ind_box_eq.size if nEQ != 0: initLenBeq = p.nbeq Aeq, beq, nbeq = copy(p.Aeq), copy(p.beq), p.nbeq p.Aeq = zeros([Len(p.beq) + nEQ, p.n]) p.beq = zeros(Len(p.beq) + nEQ) p.beq[:Len(beq)] = beq p.Aeq[:Len(beq)] = Aeq for i in range(len(ind_box_eq)): p.Aeq[initLenBeq+i, ind_box_eq[i]] = 1 p.beq[initLenBeq+i] = p.lb[ind_box_eq[i]] # = p.ub[indEQ[i]], because they are the same p.nbeq += nEQ if not self.newLinEq or p.nbeq == 0: needProjection = False B0 = eye(n, dtype=T) restoreProb = lambda *args: 0 Aeq_r, beq_r, nbeq_r = None, None, 0 else: needProjection = True B0 = self.getPrimevalDilationMatrixWRTlinEqConstraints(p) #Aeq, beq, nbeq = p.Aeq, p.beq, p.nbeq if any(abs(p._get_AeqX_eq_Beq_residuals(x0))>p.contol/16.0): #p.debugmsg('old point Aeq residual:'+str(norm(dot(Aeq, x0)-beq))) try: x0 = self.linEqProjection(x0, p.Aeq, p.beq) except LinAlgError: s = 'Failed to obtain projection of start point to linear equality constraints subspace, probably the system is infeasible' p.istop, p.msg = -25, s return #p.debugmsg('new point Aeq residual:'+str(norm(dot(Aeq, x0)-beq))) if nEQ == 0: Aeq_r, beq_r, nbeq_r = p.Aeq, p.beq, p.nbeq else: Aeq_r, beq_r, nbeq_r = Aeq, beq, nbeq p.Aeq, p.beq, p.nbeq = None, None, 0 # TODO: return prob with unmodified Aeq, beq def restoreProb(): p.Aeq, p.beq, p.nbeq = Aeq_r, beq_r, nbeq_r #if nEQ != 0: restore lb, ub b = B0.copy() if self.B is None else self.B # B_f = diag(ones(n)) # B_constr = diag(ones(n)) hs = asarray(h0, T) if self.innerState is not None: hs = self.innerState['hs'] b = self.innerState['B'] ls_arr = [] w = asarray(1.0/alp-1.0, T) """ Shor r-alg engine """ bestPoint = p.point(array(copy(x0).tolist(), T)) # tolist() for PyPy compatibility prevIter_best_ls_point = bestPoint prevIter_PointForDilation = bestPoint g = bestPoint._getDirection(self.approach) prevDirectionForDilation = g moveDirection = g if not any(g) and all(isfinite(g)): # TODO: create ENUMs p.iterfcn(bestPoint) restoreProb() p.istop = 14 if bestPoint.isFeas(False) else -14 p.msg = 'move direction has all-zero coords' return HS = [] LS = [] SwitchEncountered = False selfNeedRej = False doScale = False #directionVectorsList = [] # #pass-by-ref! not copy! # if p.isFeas(p.x0): b = B_f # else: b = B_constr # if p.debug and hasattr(p, 'x_opt'): # import scipy # exactDirection = x0-p.x_opt # asdf_0 = exactDirection * (0.2+scipy.rand(n)) # #asdf = asdf_0.copy() fTol = p.fTol if p.fTol is not None else 15*p.ftol # CHANGES if self.penalties: oldVal = p.f(p.x0) newVal = inf x = p.x0 #H, DH = p.h, p.dh if p.nh != 0: #S = 1.0 _Aeq = p.dh(x) _beq = -p.h(x) df = p.df(x) if n>=150 and not scipyInstalled: p.pWarn(scipyAbsentMsg) if n>100 and scipyInstalled: from scipy.sparse import eye as Eye # to prevent numpy.eye overwrite HH = Eye(n, n) else: HH = eye(n) qp = openopt.QP(H=HH, f=df, Aeq=_Aeq, beq=_beq) # print ('len(_beq): %d' % len(_beq)) # assert len(_beq) != 0 QPsolver = openopt.oosolver('cvxopt_qp', iprint=-1) if not QPsolver.isInstalled: #p.pWarn('to use ') S = None else: r = qp.solve(QPsolver) #S = 2.0*abs(r.duals).sum() if r.istop > 0 else 0 S = 10.0*sum(abs(r.duals)) if r.istop > 0 else None while any(p.h(x)) > p.contol: if S is not None: p2 = getattr(openopt, p.probType)(p.f, x) p.inspire(p2) p2.x0 = x p2.h = p2.dh = None p2.userProvided.h = p2.userProvided.dh = False p2.nh = 0 p2.f = lambda *args, **kwargs: p.f(*args, **kwargs) + sum(abs(S * p.h(*args, **kwargs))) p2.df = lambda *args, **kwargs: p.df(*args, **kwargs) + dot(S * sign(p.h(*args, **kwargs)), p.dh(*args, **kwargs)) #p2.iterfcn = p.iterfcn # def df2(*args, **kwargs): # r1 = p.df(*args, **kwargs) # r2 = S * dot(p.dh(*args, **kwargs).reshape(-1, 1), sign(p.h(*args, **kwargs))).flatten() # #raise 0 # return r1+r2 # #p2.df = lambda *args, **kwargs: p.df(*args, **kwargs) + S * dot(p.dh(x).reshape(-1, 1), sign(p.h(*args, **kwargs))).flatten() # p2.df = df2 # #raise 0 r2 = p2.solve(p.solver, iprint=10) if r2.stopcase >= 0: x = r2.xf p.solver.innerState = r2.extras['innerState'] oldVal, newVal = newVal, r2.ff else: if r2.istop == IS_LINE_SEARCH_FAILED: # TODO: custom S as raising penalties pass if p.isFeas(p2.xk): p.xf = p.xk = p2.xk p.istop, p.msg = p2.istop, p2.msg return else: S *= 50 #print('max residual:%0.2e'% r2.rf) else: # failed to solve QP break #print 'b:', b, '\nhs:', hs # CHANGES END """ Ralg main cycle """ for itn in range(p.maxIter+10): doDilation = True lastPointOfSameType = None # to prevent possible bugs alp_addition = 0.0 iterStartPoint = prevIter_best_ls_point x = iterStartPoint.x.copy() g_tmp = economyMult(b.T, moveDirection) if any(g_tmp): g_tmp /= p.norm(g_tmp) g1 = p.matmult(b, g_tmp) # norm_moveDirection = p.norm(g1) # if doScale: # g1 *= (norm_moveDirection_prev/norm_moveDirection) ** 0.5 # norm_moveDirection_prev = norm_moveDirection # if p.debug and hasattr(p, 'x_opt'): # cos_phi_0 = p.matmult(moveDirection, prevIter_best_ls_point.x - p.x_opt)/p.norm(moveDirection)/p.norm(prevIter_best_ls_point.x - p.x_opt) # cos_phi_1 = p.matmult(g1, prevIter_best_ls_point.x - p.x_opt)/p.norm(g1)/p.norm(prevIter_best_ls_point.x - p.x_opt) # print('beforeDilation: %f afterDilation: %f' % (cos_phi_0, cos_phi_1) ) # asdf = asdf_0.copy() # g_tmp = economyMult(b.T, asdf) # # #g_tmp = p.matmult(b.T, asdf) # # if any(g_tmp): g_tmp /= p.norm(g_tmp) # asdf = p.matmult(b, g_tmp) # cos_phi = dot(asdf, exactDirection) / p.norm(asdf) / p.norm(exactDirection) # p.debugmsg('cos_phi:%f' % cos_phi) # assert cos_phi >0 """ Forward line search """ hs_cumsum = 0 hs_start = hs for ls in range(p.maxLineSearch): hs_mult = 1.0 if ls > 20: hs_mult = 2.0 elif ls > 10: hs_mult = 1.5 elif ls > 2: hs_mult = 1.05 hs *= hs_mult x -= hs * g1 hs_cumsum += hs newPoint = p.point(x) if ls == 0 else iterStartPoint.linePoint(hs_cumsum/(hs_cumsum-hs), oldPoint) # TODO: take ls into account? if not p.isUC: if newPoint.isFeas(True) == iterStartPoint.isFeas(True): lastPointOfSameType = newPoint if self.show_nnan: p.info('ls: %d nnan: %d' % (ls, newPoint.__nnan__())) if ls == 0: oldPoint = prevIter_best_ls_point#prevIterPoint oldoldPoint = oldPoint #if not self.checkTurnByGradient: if newPoint.betterThan(oldPoint, altLinInEq=True): if newPoint.betterThan(bestPoint, altLinInEq=False): bestPoint = newPoint oldoldPoint = oldPoint oldPoint, newPoint = newPoint, None else: if not itn % 4: for fn in ['_lin_ineq', '_lin_eq']: if hasattr(newPoint, fn): delattr(newPoint, fn) break hs /= hs_mult if ls == p.maxLineSearch-1: p.istop, p.msg = IS_LINE_SEARCH_FAILED, 'maxLineSearch (' + str(p.maxLineSearch) + ') has been exceeded, the problem seems to be unbounded' restoreProb() return #iterPoint = newPoint PointForDilation = newPoint #best_ls_point = newPoint if ls == 0 else oldPoint #if p.debug and ls != 0: assert not oldPoint.betterThan(best_ls_point) """ Backward line search """ mdx = max((150, 1.5*p.n))*p.xtol if itn == 0: mdx = max((hs / 128.0, 128*p.xtol )) # TODO: set it after B rej as well ls_backward = 0 maxLS = 3 if ls == 0 else 1 # if ls <=3 or ls > 20: if self.doBackwardSearch: if self.new_bs: best_ls_point, PointForDilation, ls_backward = \ getBestPointAfterTurn(oldoldPoint, newPoint, maxLS = maxLS, maxDeltaF = 150*p.ftol, \ maxDeltaX = mdx, altLinInEq = True, new_bs = True) if PointForDilation.isFeas(True) == iterStartPoint.isFeas(True): lastPointOfSameType = PointForDilation # elif best_ls_point.isFeas(altLinInEq=True) == iterStartPoint.isFeas(altLinInEq=True): # lastPointOfSameType = best_ls_point else: best_ls_point, ls_backward = \ getBestPointAfterTurn(oldoldPoint, newPoint, maxLS = maxLS, altLinInEq = True, new_bs = False) PointForDilation = best_ls_point # TODO: extract last point from backward search, that one is better than iterPoint if best_ls_point.betterThan(bestPoint): bestPoint = best_ls_point #p.debugmsg('ls_backward:%d' % ls_backward) if ls == 0 and ls_backward == -maxLS: #pass alp_addition += 0.25 #hs *= 0.9 if ls_backward <= -1 and itn != 0: # TODO: mb use -1 or 0 instead? pass #alp_addition -= 0.25*ls_backward # ls_backward less than zero #hs *= 2 ** min((ls_backward+1, 0)) else: pass #hs *= 0.95 best_ls_point = PointForDilation # elseware lots of difficulties """ Updating hs """ step_x = p.norm(PointForDilation.x - prevIter_PointForDilation.x) step_f = abs(PointForDilation.f() - prevIter_PointForDilation.f()) HS.append(hs_start) assert ls >= 0 LS.append(ls) if itn > 3: mean_ls = (3*LS[-1] + 2*LS[-2]+LS[-3]) / 6.0 j0 = 3.3 if mean_ls > j0: hs = (mean_ls - j0 + 1)**0.5 * hs_start else: #hs = (ls/j0) ** 0.5 * hs_start hs = hs_start if ls == 0 and ls_backward == -maxLS: shift_x = step_x / p.xtol RD = log10(shift_x+1e-100) if PointForDilation.isFeas(True) or prevIter_PointForDilation.isFeas(True): RD = min((RD, asscalar(asarray(log10(step_f / p.ftol + 1e-100))))) if RD > 1.0: mp = (0.5, (ls/j0) ** 0.5, 1 - 0.2*RD) hs *= max(mp) #from numpy import argmax #print argmax(mp), mp """ Handling iterPoints """ best_ls_point = PointForDilation #if not SwitchEncountered and p.nh != 0 and PointForDilation.isFeas(altLinInEq=False) != prevIter_PointForDilation.isFeas(altLinInEq=False): #SwitchEncountered = True #selfNeedRej = True involve_lastPointOfSameType = False if lastPointOfSameType is not None and PointForDilation.isFeas(True) != prevIter_PointForDilation.isFeas(True): # TODO: add middle point for the case ls = 0 assert self.dilationType == 'plain difference' #directionForDilation = lastPointOfSameType._getDirection(self.approach) PointForDilation = lastPointOfSameType involve_lastPointOfSameType = True #directionForDilation = newPoint.__getDirection__(self.approach) # used for dilation direction obtaining # if not self.new_bs or ls != 0: # moveDirection = iterPoint.__getDirection__(self.approach) # else: # moveDirection = best_ls_point.__getDirection__(self.approach) #directionForDilation = pointForDilation.__getDirection__(self.approach) # cos_phi = -p.matmult(moveDirection, prevIterPoint.__getDirection__(self.approach)) # assert cos_phi.size == 1 # if cos_phi> 0: # g2 = moveDirection#pointForDilation.__getDirection__(self.approach) # else: # g2 = pointForDilation.__getDirection__(self.approach) if itn == 0: p.debugmsg('hs: ' + str(hs)) p.debugmsg('ls: ' + str(ls)) if self.showLS: p.info('ls: ' + str(ls)) if self.show_hs: p.info('hs: ' + str(hs)) if self.show_nnan: p.info('nnan: ' + str(best_ls_point.__nnan__())) if self.showRes: r, fname, ind = best_ls_point.mr(True) p.info(fname+str(ind)) """ Set dilation direction """ #if sum(p.dotmult(g, g2))>0: #p.debugmsg('ralg warning: slope angle less than pi/2. Mb dilation for the iter will be omitted.') #doDilation = False # CHANGES # if lastPointOfSameType is None: # if currIterPointIsFeasible and not prevIterPointIsFeasible: # alp_addition += 0.1 # elif prevIterPointIsFeasible and not currIterPointIsFeasible: # alp_addition -= 0.0 # CHANGES END # r_p, ind_p, fname_p = prevIter_best_ls_point.mr(1) # r_, ind_, fname_ = PointForDilation.mr(1) #else: #print itn,'>>>>>>>>>', currIterPointIsFeasible """ Excluding derivatives switched to/from NaN """ if self.skipPrevIterNaNsInDilation: c_prev, c_current = prevIter_PointForDilation.c(), PointForDilation.c() h_prev, h_current = prevIter_PointForDilation.h(), PointForDilation.h() """ Handling switch to NaN """ NaN_derivatives_excluded = False if self.skipPrevIterNaNsInDilation: assert self.approach == 'all active' if not prevIter_PointForDilation.isFeas(True): """ processing NaNs in nonlin inequality constraints """ ind_switch_ineq_to_nan = where(logical_and(isnan(c_current), c_prev>0))[0] if len(ind_switch_ineq_to_nan) != 0: NaN_derivatives_excluded = True tmp = prevIter_PointForDilation.dc(ind_switch_ineq_to_nan) if hasattr(tmp, 'toarray'): tmp = tmp.A if len(ind_switch_ineq_to_nan)>1: tmp *= (c_prev[ind_switch_ineq_to_nan] /sqrt((tmp**2).sum(1))).reshape(-1, 1) else: tmp *= c_prev[ind_switch_ineq_to_nan] / norm(tmp) if tmp.ndim>1: tmp = tmp.sum(0) if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix #print '1: excluded:', norm(tmp), norm(prevDirectionForDilation) prevDirectionForDilation -= tmp #print '1: result=', norm(prevDirectionForDilation) """ processing NaNs in nonlin equality constraints """ ind_switch_eq_to_nan = where(logical_and(isnan(h_current), h_prev>0))[0] if len(ind_switch_eq_to_nan) != 0: NaN_derivatives_excluded = True tmp = prevIter_PointForDilation.dh(ind_switch_eq_to_nan) if tmp.ndim>1: tmp = tmp.sum(0) if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix prevDirectionForDilation -= tmp ind_switch_eq_to_nan = where(logical_and(isnan(h_current), h_prev<0))[0] if len(ind_switch_eq_to_nan) != 0: NaN_derivatives_excluded = True tmp = prevIter_PointForDilation.dh(ind_switch_eq_to_nan) if tmp.ndim>1: tmp = tmp.sum(0) if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix prevDirectionForDilation += tmp directionForDilation = PointForDilation._getDirection(self.approach) """ Handling switch from NaN """ if self.skipPrevIterNaNsInDilation: if not PointForDilation.isFeas(True): """ processing NaNs in nonlin inequality constraints """ ind_switch_ineq_from_nan = where(logical_and(isnan(c_prev), c_current>0))[0] if len(ind_switch_ineq_from_nan) != 0: NaN_derivatives_excluded = True tmp = PointForDilation.dc(ind_switch_ineq_from_nan) if hasattr(tmp, 'toarray'): tmp = tmp.A if len(ind_switch_ineq_from_nan)>1: tmp *= (c_current[ind_switch_ineq_from_nan] /sqrt((tmp**2).sum(1))).reshape(-1, 1) else: tmp *= c_current[ind_switch_ineq_from_nan] / norm(tmp) if tmp.ndim>1: tmp = tmp.sum(0) if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix #print '2: excluded:', norm(tmp), norm(directionForDilation) directionForDilation -= tmp #print '2: result=', norm(directionForDilation) """ processing NaNs in nonlin equality constraints """ ind_switch_eq_from_nan = where(logical_and(isnan(h_prev), h_current>0))[0] if len(ind_switch_eq_from_nan) != 0: NaN_derivatives_excluded = True tmp = PointForDilation.dh(ind_switch_eq_from_nan) if tmp.ndim>1: tmp = tmp.sum(0) if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix directionForDilation -= tmp ind_switch_eq_from_nan = where(logical_and(isnan(h_prev), h_current<0))[0] if len(ind_switch_eq_from_nan) != 0: NaN_derivatives_excluded = True tmp = PointForDilation.dh(ind_switch_eq_from_nan) if tmp.ndim>1: tmp = tmp.sum(0) if not isinstance(tmp, ndarray) or isinstance(tmp, matrix): tmp = tmp.A.flatten() # dense or sparse matrix directionForDilation += tmp # # CHANGES # gn = g2/norm(g2) # if len(directionVectorsList) == 0 or n < 3: pass # else: # if len(directionVectorsList) == 1 or abs(dot(directionVectorsList[-1], directionVectorsList[-2]))>0.999: # projectionComponentLenght = abs(dot(directionVectorsList[-1], gn)) # restLength = sqrt(1 - min((1, projectionComponentLenght))**2) # else: # e1 = directionVectorsList[-1] # e2 = directionVectorsList[-2] - dot(directionVectorsList[-1], directionVectorsList[-2]) * directionVectorsList[-1] # e2 /= norm(e2) # # proj1, proj2 = dot(e1, gn), dot(e2, gn) # rest = gn - proj1 * e1 - proj2 * e2 # restLength = norm(rest) # if restLength > 1+1e-5: p.pWarn('possible error in ralg solver: incorrect restLength, exceeds 1.0') # # # TODO: make it parameters of ralg # commonCoeff, alp_add_coeff = 0.5, 1.0 # # if restLength < commonCoeff * (n - 2.0) / n: # #pass # alpAddition = 0.5+(arctan((n - 2.0) / (n * restLength)) - pi / 4.0) / (pi / 2.0) * alp_add_coeff # #p.debugmsg('alpAddition:' + str(alpAddition)) # assert alpAddition > 0 # if someone incorrectly modifies commonCoeff it can be less than zero # alp_addition += alpAddition # #p.debugmsg('alp_addition:' + str(alp_addition)) # # directionVectorsList.append(gn) # if len(directionVectorsList) > 2: directionVectorsList = directionVectorsList[:-2] # # CHANGES END if self.dilationType == 'normalized' and (not fname_p in ('lb', 'ub', 'lin_eq', 'lin_ineq') \ or not fname_ in ('lb', 'ub', 'lin_eq', 'lin_ineq')) and (fname_p != fname_ or ind_p != ind_): G2, G = directionForDilation/norm(directionForDilation), prevDirectionForDilation/norm(prevDirectionForDilation) else: G2, G = directionForDilation, prevDirectionForDilation if prevIter_PointForDilation.isFeas(True) == PointForDilation.isFeas(True): g1 = G2 - G elif prevIter_PointForDilation.isFeas(True): g1 = G2.copy() else: g1 = G.copy() alp_addition += 0.05 #print p.getMaxResidual(PointForDilation.x, 1) ############################################## # the case may be occured when # 1) lastPointOfSameType is used # or # 2) some NaN from constraints have been excluded if norm(G2 - G) < 1e-12 * min((norm(G2), norm(G))) and (involve_lastPointOfSameType or NaN_derivatives_excluded): p.debugmsg("ralg: 'last point of same type gradient' is used") g1 = G2 ############################################## #g1 = -G.copy() # signum doesn't matter here # changes wrt infeas constraints # if prevIterPoint.nNaNs() != 0: # cp, hp = prevIterPoint.c(), prevIterPoint.h() # ind_infeas_cp, ind_infeas_hp = isnan(cp), isnan(hp) # # c, h = iterPoint.c(), iterPoint.h() # ind_infeas_c, ind_infeas_h = isnan(c), isnan(h) # # ind_goodChange_c = logical_and(ind_infeas_cp, logical_not(ind_infeas_c)) # ind_goodChange_h = logical_and(ind_infeas_hp, logical_not(ind_infeas_h)) # # any_c, any_h = any(ind_goodChange_c), any(ind_goodChange_h) # altDilation = zeros(n) # if any_c: # altDilation += sum(atleast_2d(iterPoint.dc(where(ind_goodChange_c)[0])), 0) # assert not any(isnan(altDilation)) # if any_h: # altDilation += sum(atleast_2d(iterPoint.dh(where(ind_goodChange_h)[0])), 0) # if any_c or any_h: # #print '!>', altDilation # #g1 = altDilation # pass # changes end """ Perform dilation """ # CHANGES # g = economyMult(b.T, g1) # gn = g/norm(g) # if len(directionVectorsList) == 0 or n < 3 or norm(g1) < 1e-20: pass # else: # if len(directionVectorsList) == 1 or abs(dot(directionVectorsList[-1], directionVectorsList[-2]))>0.999: # projectionComponentLenght = abs(dot(directionVectorsList[-1], gn)) # restLength = sqrt(1 - min((1, projectionComponentLenght))**2) # else: # e1 = directionVectorsList[-1] # e2 = directionVectorsList[-2] - dot(directionVectorsList[-1], directionVectorsList[-2]) * directionVectorsList[-1] # print dot(directionVectorsList[-1], directionVectorsList[-2]) # e2 /= norm(e2) # proj1, proj2 = dot(e1, gn), dot(e2, gn) # rest = gn - proj1 * e1 - proj2 * e2 # restLength = norm(rest) # assert restLength < 1+1e-5, 'error in ralg solver: incorrect restLength' # # # TODO: make it parameters of ralg # commonCoeff, alp_add_coeff = 0.5, 1.0 # # if restLength < commonCoeff * (n - 2.0) / n: # #pass # alpAddition = 0.5+(arctan((n - 2.0) / (n * restLength)) - pi / 4.0) / (pi / 2.0) * alp_add_coeff # #p.debugmsg('alpAddition:' + str(alpAddition)) # assert alpAddition > 0 # if someone incorrectly modifies commonCoeff it can be less than zero # alp_addition += alpAddition # #p.debugmsg('alp_addition:' + str(alp_addition)) # # directionVectorsList.append(gn) # if len(directionVectorsList) > 2: directionVectorsList = directionVectorsList[:-2] # CHANGES END if doDilation: g = economyMult(b.T, g1) ng = p.norm(g) if self.needRej(p, b, g1, g) or selfNeedRej: selfNeedRej = False if self.showRej or p.debug: p.info('debug msg: matrix B restoration in ralg solver') b = B0.copy() hs = p.norm(prevIter_best_ls_point.x - best_ls_point.x) # TODO: iterPoint = projection(iterPoint,Aeq) if res_Aeq > 0.75*contol if ng < 1e-40: hs *= 0.9 p.debugmsg('small dilation direction norm (%e), skipping' % ng) if all(isfinite(g)) and ng > 1e-50 and doDilation: g = (g / ng).reshape(-1,1) vec1 = economyMult(b, g).reshape(-1,1)# TODO: remove economyMult, use dot? #if alp_addition != 0: p.debugmsg('alp_addition:' + str(alp_addition)) w = asarray(1.0/(alp+alp_addition)-1.0, T) vec2 = w * g.T b += p.matmult(vec1, vec2) """ Call OO iterfcn """ if hasattr(p, '_df'): delattr(p, '_df') if best_ls_point.isFeas(False) and hasattr(best_ls_point, '_df'): p._df = best_ls_point.df().copy() p.iterfcn(best_ls_point) """ Check stop criteria """ cond_same_point = array_equal(best_ls_point.x, prevIter_best_ls_point.x) if cond_same_point and not p.istop: p.istop = 14 p.msg = 'X[k-1] and X[k] are same' p.stopdict[SMALL_DELTA_X] = True restoreProb() self.innerState = {'B': b, 'hs': hs} return s2 = 0 if p.istop and not p.userStop: if p.istop not in p.stopdict: p.stopdict[p.istop] = True # it's actual for converters, TODO: fix it if SMALL_DF in p.stopdict: if best_ls_point.isFeas(False): s2 = p.istop p.stopdict.pop(SMALL_DF) if SMALL_DELTA_F in p.stopdict: # TODO: implement it more properly if best_ls_point.isFeas(False) and prevIter_best_ls_point.f() != best_ls_point.f(): s2 = p.istop p.stopdict.pop(SMALL_DELTA_F) if SMALL_DELTA_X in p.stopdict: if best_ls_point.isFeas(False) or not prevIter_best_ls_point.isFeas(False) or cond_same_point: s2 = p.istop p.stopdict.pop(SMALL_DELTA_X) # if s2 and (any(isnan(best_ls_point.c())) or any(isnan(best_ls_point.h()))) \ # and not p.isNaNInConstraintsAllowed\ # and not cond_same_point: # s2 = 0 if not s2 and any(p.stopdict.values()): for key, val in p.stopdict.items(): if val == True: s2 = key break p.istop = s2 for key, val in p.stopdict.items(): if key < 0 or key in set([FVAL_IS_ENOUGH, USER_DEMAND_STOP, BUTTON_ENOUGH_HAS_BEEN_PRESSED]): p.iterfcn(bestPoint) self.innerState = {'B': b, 'hs': hs} return """ If stop required """ if p.istop: # if self.needRej(p, b, g1, g) or not feasiblePointWasEncountered: # b = B0.copy() # hs = max((p.norm(prevIter_best_ls_point.x - best_ls_point.x) , 128*p.xtol)) # p.istop = 0 # else: restoreProb() p.iterfcn(bestPoint) #p.istop, p.msg = istop, msg self.innerState = {'B': b, 'hs': hs} return """ Some final things for ralg main cycle """ # p.debugmsg('new point Aeq residual:'+str(norm(dot(Aeq, iterPoint.x)-beq))) # if needProjection and itn!=0: # #pass # x2 = self.linEqProjection(iterPoint.x, Aeq, beq) # p.debugmsg('norm(delta):' + str(norm(iterPoint.x-x2))) # iterPoint = p.point(x2) # p.debugmsg('2: new point Aeq residual:'+str(norm(dot(Aeq, iterPoint.x)-beq))) #p.hs.append(hs) #g = moveDirection.copy() #prevDirectionForDilation = directionForDilation #iterPoint = None #doScale = self.new_s and prevIter_PointForDilation.isFeas(True) != best_ls_point.isFeas(True) #print doScale prevIter_best_ls_point = best_ls_point prevIter_PointForDilation = best_ls_point prevDirectionForDilation = best_ls_point._getDirection(self.approach) moveDirection = best_ls_point._getDirection(self.approach) def getPrimevalDilationMatrixWRTlinEqConstraints(self, p): n, Aeq, beq = p.n, p.Aeq, p.beq nLinEq = len(p.beq) ind_fixed = where(p.lb==p.ub)[0] arr=ones(n, dtype=self.T) arr[ind_fixed] = 0 b = diag(arr) if hasattr(Aeq, 'tocsc'):Aeq = Aeq.tocsc() for i in range(nLinEq): vec = Aeq[i] #raise 0 if hasattr(vec, 'toarray'): vec = vec.toarray().flatten() g = economyMult(b.T, vec) if not any(g): continue #ind_nnz = nonzero(g)[0] ng = norm(g) g = (g / ng).reshape(-1,1) vec1 = p.matmult(b, g)# TODO: remove economyMult, use dot? vec2 = -g.T b += p.matmult(vec1, vec2) # if len(ind_nnz) > 0.7 * g.size: # b += p.matmult(vec1, vec2) # else: # ind_nnz1 = nonzero(vec1)[0] # ind_nnz2 = nonzero(vec2)[1] # r = dot(vec1[ind_nnz1, :], vec2[:, ind_nnz2]) # if p.debug: # assert abs(norm(p.matmult(vec1, vec2).flatten()) - norm(r.flatten())) < 1e-5 # b[ix_(ind_nnz1, ind_nnz2)] += r return b def linEqProjection(self, x, Aeq, beq): # TODO: handle case nbeq = 1 ? if hasattr(Aeq, 'toarray'):Aeq = Aeq.toarray() AeqT = Aeq.T AeqAeqT = dot(Aeq, AeqT) Aeqx = dot(Aeq, x) AeqT_AeqAeqT_inv_Aeqx = dot(AeqT, ravel(solve(AeqAeqT, Aeqx))) AeqT_AeqAeqT_inv_beq = dot(AeqT, ravel(solve(AeqAeqT, beq))) xf = x - AeqT_AeqAeqT_inv_Aeqx + AeqT_AeqAeqT_inv_beq return xf openopt-0.38+svn1589/openopt/solvers/__init__.py000066400000000000000000000000011175775750500215650ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/solvers/lp_solve/000077500000000000000000000000001175775750500213105ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/solvers/lp_solve/__init__.py000066400000000000000000000000021175775750500234110ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/solvers/lp_solve/lpSolve_oo.py000066400000000000000000000035311175775750500240050ustar00rootroot00000000000000from lp_solve import lp_solve as lps #import lp_solve #lp_solve.PRESOLVE_DUALS = 0#524288 + 1048576#10000 from openopt.kernel.baseSolver import baseSolver from numpy import asarray, inf, ones, nan, ravel from openopt.kernel.ooMisc import LinConst2WholeRepr def List(x): if x == None or x.size == 0: return None else: return x.tolist() class lpSolve(baseSolver): __name__ = 'lpSolve' __license__ = "LGPL" __authors__ = "Michel Berkelaar, michel@es.ele.tue.nl" __homepage__ = 'http://sourceforge.net/projects/lpsolve, http://www.cs.sunysb.edu/~algorith/implement/lpsolve/implement.shtml, http://www.nabble.com/lp_solve-f14350i70.html' __alg__ = "lpsolve" __info__ = 'use p.scale = 1 or True to turn scale mode on' __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'intVars'] def __init__(self): pass def __solver__(self, p): LinConst2WholeRepr(p) f = - asarray(p.f) # sign '-' because lp_solve by default searches for maximum, not minimum scalemode = False if p.scale in [1, True]: scalemode = 1 elif not (p.scale in [None, 0, False]): p.warn(self.__name__ + ' requires p.scale from [None, 0, False, 1, True], other value obtained, so scale = 1 will be used') scalemode = 1 [obj, x_opt, duals] = lps(List(f.flatten()), List(p.Awhole), List(p.bwhole.flatten()), List(p.dwhole.flatten()), \ List(p.lb.flatten()), List(p.ub.flatten()), (1+asarray(p.intVars)).tolist(), scalemode) if obj != []: # ! don't involve p.ff - it can be different because of goal and additional constant from FuncDesigner p.xf = ravel(x_opt) p.duals = duals p.istop = 1 else: p.ff = nan p.xf = nan*ones(p.n) p.duals = [] p.istop = -1 openopt-0.38+svn1589/openopt/solvers/nlopt/000077500000000000000000000000001175775750500206215ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/solvers/nlopt/NLOPT_AUX.py000066400000000000000000000102561175775750500226100ustar00rootroot00000000000000#from numpy import asarray, ones, all, isfinite, copy, nan, concatenate, array, dot #from openopt.kernel.ooMisc import WholeRepr2LinConst, xBounds2Matrix from openopt.kernel.setDefaultIterFuncs import SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON, SMALL_DELTA_X, SMALL_DELTA_F from numpy import isfinite, asscalar, asfarray, abs, copy, isinf, ones, array import nlopt def NLOPT_AUX(p, solver, opts=None): def myfunc(x, grad): #if p.istop != 0: raise nlopt.FORCED_STOP if grad.size > 0: grad[:]= p.df(x.copy()) return asscalar(p.f(x)) # TODO: add other local nlopt optimizers that cannot handle equality constraints if solver in [nlopt.LD_MMA] and (p.nbeq != 0 or p.nh != 0): opt = nlopt.opt(nlopt.LD_AUGLAG, p.n) opt2 = nlopt.opt(solver, p.n) setStopCriteria(opt2, p, reduce=10.0) opt.set_local_optimizer(opt2) elif solver == nlopt.G_MLSL_LDS: opt = nlopt.opt(nlopt.G_MLSL_LDS, p.n) opt2 = nlopt.opt(nlopt.LD_TNEWTON_PRECOND_RESTART, p.n) setStopCriteria(opt2, p, reduce=10.0) opt.set_local_optimizer(opt2) else: opt = nlopt.opt(solver, p.n) if opts is not None: for option, val in opts.items(): getattr(opt, option)(val) opt.set_min_objective(myfunc) if any(p.lb==p.ub): p.pWarn('nlopt solvers badly handle problems with variables fixed via setting lb=ub') lb = [elem if isfinite(elem) else float(elem) for elem in p.lb.tolist()] ub = [elem if isfinite(elem) else float(elem) for elem in p.ub.tolist()] if any(isfinite(lb)): opt.set_lower_bounds(lb) if any(isfinite(ub)): opt.set_upper_bounds(ub) # TODO: A, Aeq if p.nc > 0: def c(result, x, grad): if grad.size > 0: grad[:] = p.dc(x.copy()) result[:] = p.c(x) opt.add_inequality_mconstraint(c, array([p.contol]*p.nc).copy()) if p.nb > 0: def c_lin(result, x, grad): if grad.size > 0: grad[:] = p.A.copy() result[:] = p._get_AX_Less_B_residuals(x) opt.add_inequality_mconstraint(c_lin, array([p.contol]*p.nb).copy()) if p.nh > 0: def h(result, x, grad): if grad.size > 0: grad[:] = p.dh(x.copy()) result[:] = p.h(x).copy() opt.add_equality_mconstraint(h, array([p.contol]*p.nh)) if p.nbeq > 0: def h_lin(result, x, grad): if grad.size > 0: grad[:] = p.Aeq.copy() result[:] = p._get_AeqX_eq_Beq_residuals(x) opt.add_equality_mconstraint(h_lin, array([p.contol]*p.nbeq)) setStopCriteria(opt, p) # others like fEnough, maxFunEvals, are handled by OO kernel x0 = asfarray(p.x0).copy() #lb2 = copy(lb) #lb2[isinf(lb2)] = 0 LB = copy(lb) #+ 1e-15*(ones(p.n) + abs(lb2)) ind = x0 <= LB x0[ind] = LB[ind] #ub2 = copy(ub) #ub2[isinf(ub2)] = 0 UB = copy(ub) #- 1e-15*(ones(p.n) + abs(ub2)) ind = x0 >= UB x0[ind] = UB[ind] #x0[ind] = p.lb[ind] + 1e-15*abs((max(1.0, p.lb[x0p.ub] = p.ub[x0>p.ub] - 1e-15*min((1.0, abs(p.ub[x0>p.ub]))) # if p.solver.__name__ == 'auglag': # opt.set_local_optimizer('mma') try: x = opt.optimize(x0.tolist()).copy() #if p.point(x).betterThan(p.point(p.xk)): #p.xk = x except: pass p.xk = p._bestPoint.x #x = p.xk #p.iterfcn(x) iStop = opt.get_stopval() if p.istop == 0: if iStop == nlopt.XTOL_REACHED: p.istop, p.msg = SMALL_DELTA_X, '|| X[k] - X[k-1] || < xtol' elif iStop == nlopt.FTOL_REACHED: p.istop, p.msg = SMALL_DELTA_F, '|| F[k] - F[k-1] || < ftol' else: p.istop = SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON # p._opt = opt def setStopCriteria(opt, p, reduce=1.0): opt.set_xtol_abs(p.xtol/reduce) opt.set_ftol_abs(p.ftol/reduce) opt.set_maxeval(p.maxFunEvals) #opt.set_maxiter(p.maxIter) if isfinite(p.maxTime): opt.set_maxtime(p.maxTime) # opt.set_xtol_rel(1e-1) # opt.set_ftol_rel(1e-1) openopt-0.38+svn1589/openopt/solvers/nlopt/NLOPT_BASE.py000066400000000000000000000003351175775750500226620ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver class NLOPT_BASE(baseSolver): __license__ = "LGPL" __authors__ = "Steven G. Johnson" #__cannotHandleExceptions__ = True _requiresBestPointDetection = True openopt-0.38+svn1589/openopt/solvers/nlopt/__init__.py000066400000000000000000000000021175775750500227220ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/solvers/nlopt/auglag_oo.py000066400000000000000000000007201175775750500231270ustar00rootroot00000000000000from NLOPT_AUX import NLOPT_AUX from NLOPT_BASE import NLOPT_BASE import nlopt class auglag(NLOPT_BASE): __name__ = 'auglag' __alg__ = "Augmented Lagrangian" __optionalDataThatCanBeHandled__ = ['lb', 'ub', 'c', 'h','A', 'b', 'Aeq', 'beq'] #TODO: check it! #_canHandleScipySparse = True #funcForIterFcnConnection = 'f' def __init__(self): pass def __solver__(self, p): NLOPT_AUX(p, nlopt.LD_AUGLAG) openopt-0.38+svn1589/openopt/solvers/nlopt/bobyqa_oo.py000066400000000000000000000010461175775750500231460ustar00rootroot00000000000000from NLOPT_AUX import NLOPT_AUX from NLOPT_BASE import NLOPT_BASE import nlopt class bobyqa(NLOPT_BASE): __name__ = 'bobyqa' __alg__ = 'Bound constrained Optimization BY Quadratic Approximation' __authors__ = 'Michael JD Powell' __optionalDataThatCanBeHandled__ = ['lb', 'ub'] __isIterPointAlwaysFeasible__ = True funcForIterFcnConnection = 'f' def __solver__(self, p): # if p.n < 15: # p.f_iter = 4 # else: # p.f_iter = p.n/4 NLOPT_AUX(p, nlopt.LN_BOBYQA) openopt-0.38+svn1589/openopt/solvers/nlopt/isres_oo.py000066400000000000000000000013751175775750500230230ustar00rootroot00000000000000from NLOPT_AUX import NLOPT_AUX from NLOPT_BASE import NLOPT_BASE import nlopt class isres(NLOPT_BASE): __name__ = 'isres' __alg__ = 'Improved Stochastic Ranking Evolution Strategy' __authors__ = 'S. G. Johnson' __optionalDataThatCanBeHandled__ = ['lb', 'ub', 'A', 'Aeq', 'b', 'beq', 'c', 'h'] funcForIterFcnConnection = 'f' population = 0 #__isIterPointAlwaysFeasible__ = lambda self, p: True __isIterPointAlwaysFeasible__ = True _requiresFiniteBoxBounds = True def __init__(self): pass def __solver__(self, p): nlopt_opts = {'set_population':self.population} if self.population != 0 else {} if self.population != 0: p.f_iter = self.population NLOPT_AUX(p, nlopt.GN_ISRES, nlopt_opts) openopt-0.38+svn1589/openopt/solvers/nlopt/mlsl_oo.py000066400000000000000000000012071175775750500226370ustar00rootroot00000000000000from NLOPT_AUX import NLOPT_AUX from NLOPT_BASE import NLOPT_BASE import nlopt class mlsl(NLOPT_BASE): __name__ = 'mlsl' __alg__ = 'Multi-Level Single-Linkage' __optionalDataThatCanBeHandled__ = ['lb', 'ub'] #funcForIterFcnConnection = 'f' population = 0 __isIterPointAlwaysFeasible__ = True _requiresFiniteBoxBounds = True def __init__(self): pass def __solver__(self, p): nlopt_opts = {'set_population':self.population} if self.population != 0 else {} #if self.population != 0: p.f_iter = self.population #p.f_iter = 4*p.n NLOPT_AUX(p, nlopt.G_MLSL_LDS, nlopt_opts) openopt-0.38+svn1589/openopt/solvers/nlopt/mma_oo.py000066400000000000000000000012271175775750500224440ustar00rootroot00000000000000from NLOPT_AUX import NLOPT_AUX from NLOPT_BASE import NLOPT_BASE import nlopt class mma(NLOPT_BASE): __name__ = 'mma' __alg__ = "Method of Moving Asymptotes" __optionalDataThatCanBeHandled__ = ['lb', 'ub', 'c', 'h','A', 'b', 'Aeq', 'beq'] # TODO: implement 'A', 'Aeq', 'b', 'beq', #__optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] #properTextOutput = True #TODO: check it! #_canHandleScipySparse = True #funcForIterFcnConnection = 'f' def __init__(self): pass def __solver__(self, p): # TODO: CONSTRAINTS! NLOPT_AUX(p, nlopt.LD_MMA) openopt-0.38+svn1589/openopt/solvers/nlopt/ptn_oo.py000066400000000000000000000010061175775750500224660ustar00rootroot00000000000000from NLOPT_AUX import NLOPT_AUX from NLOPT_BASE import NLOPT_BASE import nlopt class ptn(NLOPT_BASE): __name__ = 'ptn' __alg__ = 'Preconditioned truncated Newton' __authors__ = 'Prof. Ladislav Luksan' __isIterPointAlwaysFeasible__ = True __optionalDataThatCanBeHandled__ = ['lb', 'ub'] def __init__(self): pass def __solver__(self, p): NLOPT_AUX(p, nlopt.LD_TNEWTON_PRECOND_RESTART) #NLOPT_AUX(p, nlopt.LD_TNEWTON) #NLOPT_AUX(p, nlopt.LD_TNEWTON_PRECOND) openopt-0.38+svn1589/openopt/solvers/nlopt/sbplx_oo.py000066400000000000000000000011531175775750500230200ustar00rootroot00000000000000from NLOPT_AUX import NLOPT_AUX from NLOPT_BASE import NLOPT_BASE import nlopt class sbplx(NLOPT_BASE): __name__ = 'sbplx' __alg__ = 'a variant of Nelder-Mead that uses Nelder-Mead on a sequence of subspaces' __authors__ = 'Steven G. Johnson' __optionalDataThatCanBeHandled__ = ['lb', 'ub'] __isIterPointAlwaysFeasible__ = lambda self, p: True funcForIterFcnConnection = 'f' def __init__(self): pass def __solver__(self, p): #NLOPT_AUX(p, nlopt.LN_BOBYQA) #NLOPT_AUX(p, nlopt.LN_COBYLA) NLOPT_AUX(p, nlopt.LN_SBPLX) #NLOPT_AUX(p, nlopt.LD_MMA) openopt-0.38+svn1589/openopt/solvers/nlopt/slmvm1_oo.py000066400000000000000000000006601175775750500231110ustar00rootroot00000000000000from NLOPT_AUX import NLOPT_AUX from NLOPT_BASE import NLOPT_BASE import nlopt class slmvm1(NLOPT_BASE): __name__ = 'slmvm1' __alg__ = 'Shifted limited-memory variable-metric, rank 1' __authors__ = 'Prof. Ladislav Luksan' __isIterPointAlwaysFeasible__ = True __optionalDataThatCanBeHandled__ = ['lb', 'ub'] def __init__(self): pass def __solver__(self, p): NLOPT_AUX(p, nlopt.LD_VAR1) openopt-0.38+svn1589/openopt/solvers/nlopt/slmvm2_oo.py000066400000000000000000000006571175775750500231200ustar00rootroot00000000000000from NLOPT_AUX import NLOPT_AUX from NLOPT_BASE import NLOPT_BASE import nlopt class slmvm2(NLOPT_BASE): __name__ = 'slmvm2' __alg__ = 'Shifted limited-memory variable-metric, rank 2' __authors__ = 'Prof. Ladislav Luksan' __isIterPointAlwaysFeasible__ = True __optionalDataThatCanBeHandled__ = ['lb', 'ub'] def __init__(self): pass def __solver__(self, p): NLOPT_AUX(p, nlopt.LD_VAR2) openopt-0.38+svn1589/openopt/solvers/nlopt/stogo_oo.py000066400000000000000000000021461175775750500230260ustar00rootroot00000000000000from NLOPT_AUX import NLOPT_AUX from NLOPT_BASE import NLOPT_BASE import nlopt from numpy import isinf class stogo(NLOPT_BASE): __name__ = 'stogo' __alg__ = "" __optionalDataThatCanBeHandled__ = ['lb', 'ub'] __isIterPointAlwaysFeasible__ = lambda self, p: True _requiresFiniteBoxBounds = True #properTextOutput = True #TODO: check it! #_canHandleScipySparse = True funcForIterFcnConnection = 'f' # _requiresBestPointDetection = True useRand = True __cannotHandleExceptions__ = True def __init__(self): pass def __solver__(self, p): #p.f_iter = 1 p.maxNonSuccess = 1e10 p.maxIter = 1e10 if isinf(p.maxTime): s= """currently due to some Python <-> C++ code connection issues the solver stogo requires finite user-defined maxTime; since you have not provided it, 15 sec will be used""" p.pWarn(s) p.maxTime = 15 solver = nlopt.GD_STOGO_RAND if self.useRand else nlopt.GD_STOGO NLOPT_AUX(p, solver) #NLOPT_AUX(p, nlopt.GD_MLSL_LDS) openopt-0.38+svn1589/openopt/solvers/scipy_optim/000077500000000000000000000000001175775750500220245ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/solvers/scipy_optim/__init__.py000066400000000000000000000000021175775750500241250ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/solvers/scipy_optim/lapack_dgelss_oo.py000066400000000000000000000015111175775750500256650ustar00rootroot00000000000000from scipy.linalg.flapack import dgelss from numpy.linalg import norm from numpy import dot, asfarray, atleast_1d from openopt.kernel.baseSolver import baseSolver class lapack_dgelss(baseSolver): __name__ = 'lapack_dgelss' __license__ = "BSD" __authors__ = 'Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University' #__alg__ = "" __info__ = 'wrapper to LAPACK dgelss routine (double precision), requires scipy & LAPACK 3.0 or newer installed' def __init__(self):pass def __solver__(self, p): res = dgelss(p.C, p.d) x,info = res[1], res[-1] xf = x[:p.C.shape[1]] ff = atleast_1d(asfarray(p.F(xf))) p.xf = p.xk = xf p.ff = p.fk = ff if info == 0: p.istop = 1000 else: p.istop = -1000 openopt-0.38+svn1589/openopt/solvers/scipy_optim/lapack_sgelss_oo.py000066400000000000000000000015121175775750500257050ustar00rootroot00000000000000from scipy.linalg.flapack import sgelss from numpy.linalg import norm from numpy import dot, asfarray, atleast_1d from openopt.kernel.baseSolver import baseSolver class lapack_sgelss(baseSolver): __name__ = 'lapack_sgelss' __license__ = "BSD" __authors__ = 'Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University' #__alg__ = "SVD" __info__ = 'wrapper to LAPACK sgelss routine (single precision), requires scipy & LAPACK 3.0 or newer installed' def __init__(self):pass def __solver__(self, p): res = sgelss(p.C, p.d) x,info = res[1], res[-1] xf = x[:p.C.shape[1]] ff = atleast_1d(asfarray(p.F(xf))) p.xf = p.xk = xf p.ff = p.fk = ff if info == 0: p.istop = 1000 else: p.istop = -1000 openopt-0.38+svn1589/openopt/solvers/scipy_optim/numpy_eig_oo.py000066400000000000000000000016621175775750500250740ustar00rootroot00000000000000from openopt.kernel.baseSolver import baseSolver from openopt.kernel.nonOptMisc import Vstack, isspmatrix from numpy.linalg import eig #from nonOptMisc import Hstack class numpy_eig(baseSolver): __name__ = 'numpy_eig' __license__ = "BSD" __authors__ = '' __alg__ = '' __info__ = """ """ __optionalDataThatCanBeHandled__ = [] _canHandleScipySparse = True #def __init__(self): pass def __solver__(self, p): A = p.C if isspmatrix(A): p.warn('numpy.linalg.eig cannot handle sparse matrices, cast to dense will be performed') A = A.A #M = p.M if p._goal != 'all': p.err('numpy_eig cannot handle the goal "%s" yet' % p._goal) eigenvalues, eigenvectors = eig(A) p.xf = p.xk = Vstack((eigenvalues, eigenvectors)) p.eigenvalues = eigenvalues p.eigenvectors = eigenvectors p.ff = 0 openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_anderson2_oo.py000066400000000000000000000015331175775750500261770ustar00rootroot00000000000000from scipy.optimize import anderson2 from numpy import asfarray from openopt.kernel.baseSolver import baseSolver class scipy_anderson2(baseSolver): __name__ = 'scipy_anderson2' __license__ = "BSD" #__authors__ = #__alg__ = "" __info__ = """ solves system of n non-linear equations with n variables. """ def __init__(self):pass def __solver__(self, p): p.xk = p.x0.copy() p.fk = asfarray(max(abs(p.f(p.x0)))).flatten() p.iterfcn() if p.istop: p.xf, p.ff = p.xk, p.fk return try: xf = anderson2(p.f, p.x0, iter = p.maxIter) except: p.istop = -1000 return p.xk = p.xf = asfarray(xf) p.fk = p.ff = asfarray(max(abs(p.f(xf)))).flatten() p.istop = 1000 p.iterfcn() openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_anderson_oo.py000066400000000000000000000015261175775750500261170ustar00rootroot00000000000000from scipy.optimize import anderson from numpy import asfarray from openopt.kernel.baseSolver import baseSolver class scipy_anderson(baseSolver): __name__ = 'scipy_anderson' __license__ = "BSD" #__authors__ = #__alg__ = "" __info__ = """ solves system of n non-linear equations with n variables. """ def __init__(self):pass def __solver__(self, p): p.xk = p.x0.copy() p.fk = asfarray(max(abs(p.f(p.x0)))).flatten() p.iterfcn() if p.istop: p.xf, p.ff = p.xk, p.fk return try: xf = anderson(p.f, p.x0, iter = p.maxIter) except: p.istop = -1000 return p.xk = p.xf = asfarray(xf) p.fk = p.ff = asfarray(max(abs(p.f(xf)))).flatten() p.istop = 1000 p.iterfcn() openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_bfgs_oo.py000066400000000000000000000015251175775750500252260ustar00rootroot00000000000000from scipy.optimize import fmin_bfgs from openopt.kernel.ooMisc import isSolved from openopt.kernel.baseSolver import baseSolver class scipy_bfgs(baseSolver): __name__ = 'scipy_bfgs' __license__ = "BSD" #__authors__ = __alg__ = "BFGS" __info__ = 'unconstrained NLP solver' iterfcnConnected = True def __init__(self):pass def __solver__(self, p): def iterfcn(x): p.xk, p.fk = x, p.f(x) p.iterfcn() if p.istop: raise isSolved # try: #p.iterfcn(p.x0) p.xk = p.xf = fmin_bfgs(p.f, p.x0, fprime=p.df, disp = 0, gtol=p.gtol, maxiter=p.maxIter, callback=iterfcn) p.istop = 1000 # except isSolved: # xf = p.xk # # ff = p.f(xf) # p.xk = p.xf = xf # p.fk = p.ff = ff # p.istop = 1000 # p.iterfcn() openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_broyden1_oo.py000066400000000000000000000016161175775750500260310ustar00rootroot00000000000000from scipy.optimize import broyden1 from numpy import asfarray from openopt.kernel.baseSolver import baseSolver class scipy_broyden1(baseSolver): __name__ = 'scipy_broyden1' __license__ = "BSD" #__authors__ = __alg__ = "a quasi-Newton-Raphson method for updating an approximate Jacobian and then inverting it" __info__ = """ solves system of n non-linear equations with n variables. """ def __init__(self):pass def __solver__(self, p): p.xk = p.x0.copy() p.fk = asfarray(max(abs(p.f(p.x0)))).flatten() p.iterfcn() if p.istop: p.xf, p.ff = p.xk, p.fk return try: xf = broyden1(p.f, p.x0, iter = p.maxIter) except: return p.xk = p.xf = asfarray(xf) p.fk = p.ff = asfarray(max(abs(p.f(xf)))).flatten() p.istop = 1000 p.iterfcn() openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_broyden2_oo.py000066400000000000000000000016321175775750500260300ustar00rootroot00000000000000from scipy.optimize import broyden2 from numpy import asfarray from openopt.kernel.baseSolver import baseSolver class scipy_broyden2(baseSolver): __name__ = 'scipy_broyden2' __license__ = "BSD" #__authors__ = __alg__ = "a quasi-Newton-Raphson method, updates the inverse Jacobian directly" __info__ = """ solves system of n non-linear equations with n variables. """ def __init__(self):pass def __solver__(self, p): p.xk = p.x0.copy() p.fk = asfarray(max(abs(p.f(p.x0)))).flatten() p.iterfcn() if p.istop: p.xf, p.ff = p.xk, p.fk return try: xf = broyden2(p.f, p.x0, iter = p.maxIter) except: p.istop = -1000 return p.xk = p.xf = asfarray(xf) p.fk = p.ff = asfarray(max(abs(p.f(xf)))).flatten() p.istop = 1000 p.iterfcn() openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_broyden3_oo.py000066400000000000000000000015271175775750500260340ustar00rootroot00000000000000from scipy.optimize import broyden3 from numpy import asfarray from openopt.kernel.baseSolver import baseSolver class scipy_broyden3(baseSolver): __name__ = 'scipy_broyden3' __license__ = "BSD" #__authors__ = #__alg__ = "" __info__ = """ solves system of n non-linear equations with n variables. """ def __init__(self):pass def __solver__(self, p): p.xk = p.x0.copy() p.fk = asfarray(max(abs(p.f(p.x0)))).flatten() p.iterfcn() if p.istop: p.xf, p.ff = p.xk, p.fk return try: xf = broyden3(p.f, p.x0, iter = p.maxIter) except: p.istop = -1000 return p.xk = p.xf = asfarray(xf) p.fk = p.ff = asfarray(max(abs(p.f(xf)))).flatten() p.istop = 1000 p.iterfcn() openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_broyden_generalized_oo.py000066400000000000000000000016001175775750500303120ustar00rootroot00000000000000from scipy.optimize import broyden_generalized from numpy import asfarray from openopt.kernel.baseSolver import baseSolver class scipy_broyden_generalized(baseSolver): __name__ = 'scipy_broyden_generalized' __license__ = "BSD" #__authors__ = __alg__ = "" __info__ = """ solves system of n non-linear equations with n variables. """ def __init__(self):pass def __solver__(self, p): p.xk = p.x0.copy() p.fk = asfarray(max(abs(p.f(p.x0)))).flatten() p.iterfcn() if p.istop: p.xf, p.ff = p.xk, p.fk return try: xf = broyden_generalized(p.f, p.x0, iter = p.maxIter) except: p.istop = -1000 return p.xk = p.xf = asfarray(xf) p.fk = p.ff = asfarray(max(abs(p.f(xf)))).flatten() p.istop = 1000 p.iterfcn() openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_cg_oo.py000066400000000000000000000016131175775750500246740ustar00rootroot00000000000000from scipy.optimize import fmin_cg from openopt.kernel.baseSolver import baseSolver from openopt.kernel.ooMisc import isSolved class scipy_cg(baseSolver): __name__ = 'scipy_cg' __license__ = "BSD" #__authors__ = __alg__ = "nonlinear conjugate gradient algorithm of Polak and Ribiere See Wright, and Nocedal 'Numerical Optimization', 1999, pg. 120-122" __info__ = 'unconstrained NLP solver' iterfcnConnected = True def __init__(self):pass def __solver__(self, p): def iterfcn(x): p.xk, p.fk = x, p.f(x) p.iterfcn() if p.istop: raise isSolved try: xf = fmin_cg(p.f, p.x0, fprime=p.df, gtol=p.gtol, disp = 0, maxiter=p.maxIter, callback=iterfcn) except isSolved: xf = p.xk ff = p.f(xf) p.xk = p.xf = xf p.fk = p.ff = ff p.istop = 1000 #p.iterfcn() openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_cobyla_oo.py000066400000000000000000000060431175775750500255560ustar00rootroot00000000000000from scipy.optimize import fmin_cobyla import openopt from openopt.kernel.setDefaultIterFuncs import * from openopt.kernel.ooMisc import WholeRepr2LinConst, xBounds2Matrix from openopt.kernel.baseSolver import baseSolver from numpy import inf, array, copy #from openopt.kernel.setDefaultIterFuncs import SMALL_DELTA_X, SMALL_DELTA_F class EmptyClass: pass class scipy_cobyla(baseSolver): __name__ = 'scipy_cobyla' __license__ = "BSD" __authors__ = """undefined""" __alg__ = "Constrained Optimization BY Linear Approximation" __info__ = 'constrained NLP solver, no user-defined derivatives are handled'#TODO: add '__info__' field to other solvers __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] funcForIterFcnConnection = 'f' def __init__(self): pass def __solver__(self, p): #p.kernelIterFuncs.pop(SMALL_DELTA_X) #p.kernelIterFuncs.pop(SMALL_DELTA_F) xBounds2Matrix(p) p.cobyla = EmptyClass() if p.userProvided.c: p.cobyla.nc = p.c(p.x0).size else: p.cobyla.nc = 0 if p.userProvided.h: p.cobyla.nh = p.h(p.x0).size else: p.cobyla.nh = 0 det_arr = cumsum(array((p.cobyla.nc, p.cobyla.nh, p.b.size, p.beq.size, p.cobyla.nh, p.beq.size))) cons = [] for i in range(det_arr[-1]): if i < det_arr[0]: c = lambda x, i=i: - p.c(x)[i] # cobyla requires positive constraints! elif det_arr[0] <= i < det_arr[1]: j = i - det_arr[0] c = lambda x, j=j: p.h(x)[j] elif det_arr[1] <= i < det_arr[2]: j = i - det_arr[1] #assert 0<= j =0)) # "warning" has been removed in latest scipy version xf = fsolve(p.f, p.x0, fprime=p.df, xtol = p.xtol, maxfev = p.maxFunEvals) p.istop = 1000 p.iterfcn(xf) openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_lbfgsb_oo.py000066400000000000000000000034461175775750500255500ustar00rootroot00000000000000from scipy.optimize.lbfgsb import fmin_l_bfgs_b import openopt from openopt.kernel.setDefaultIterFuncs import * from openopt.kernel.ooMisc import WholeRepr2LinConst from openopt.kernel.baseSolver import baseSolver class scipy_lbfgsb(baseSolver): __name__ = 'scipy_lbfgsb' __license__ = "BSD" __authors__ = """Ciyou Zhu, Richard Byrd, and Jorge Nocedal , connected to scipy by David M. Cooke and Travis Oliphant, connected to openopt by Dmitrey""" __alg__ = "l-bfgs-b" __info__ = 'box-bounded limited-memory NLP solver, can handle lb<=x<=ub constraints, some lb-ub coords can be +/- inf'#TODO: add '__info__' field to other solvers __optionalDataThatCanBeHandled__ = ['lb', 'ub'] __isIterPointAlwaysFeasible__ = lambda self, p: True def __init__(self):pass def __solver__(self, p): #WholeRepr2LinConst(p)#TODO: remove me bounds = [] # don't work in Python ver < 2.5 # BOUND = lambda x: x if isfinite(x) else None def BOUND(x): if isfinite(x): return x else: return None for i in range(p.n): bounds.append((BOUND(p.lb[i]), BOUND(p.ub[i]))) xf, ff, d = fmin_l_bfgs_b(p.f, p.x0, fprime=p.df, approx_grad=0, bounds=bounds, iprint=p.iprint, maxfun=p.maxFunEvals) if d['warnflag'] in (0, 2): # if 2 - some problems can be present, but final check from RunProbSolver will set negative istop if solution is unfeasible istop = SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON if d['warnflag'] == 0: msg = 'converged' elif d['warnflag'] == 1: istop = IS_MAX_FUN_EVALS_REACHED p.xk = p.xf = xf p.fk = p.ff = ff p.istop = istop p.iterfcn() openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_leastsq_oo.py000066400000000000000000000023521175775750500257600ustar00rootroot00000000000000from scipy.optimize import leastsq from numpy import asfarray from openopt.kernel.baseSolver import baseSolver class scipy_leastsq(baseSolver): __name__ = 'scipy_leastsq' __license__ = "BSD" #__authors__ = #__alg__ = "" __info__ = """ MINPACK's lmdif and lmder algorithms """ #__constraintsThatCannotBeHandled__ = (all) def __init__(self): pass def __solver__(self, p): p.xk = p.x0.copy() p.fk = asfarray((p.f(p.x0)) ** 2).sum().flatten() p.iterfcn() if p.istop: p.xf, p.ff = p.xk, p.fk return if p.userProvided.df: xf, cov_x, infodict, mesg, ier = leastsq(p.f, p.x0, Dfun=p.df, xtol = p.xtol, ftol = p.ftol, maxfev = p.maxFunEvals, full_output = 1) else: xf, cov_x, infodict, mesg, ier = leastsq(p.f, p.x0, xtol = p.xtol, maxfev = p.maxFunEvals, epsfcn = p.diffInt, ftol = p.ftol, full_output = 1) if ier == 1: p.istop = 1000 else: p.istop = -1000 p.msg = mesg ff = asfarray((p.f(xf)) ** 2).sum().flatten() p.xk = xf p.fk = ff p.xf = xf p.ff = ff p.iterfcn() openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_ncg_oo.py000066400000000000000000000014511175775750500250520ustar00rootroot00000000000000from scipy.optimize import fmin_ncg from openopt.kernel.ooMisc import isSolved from openopt.kernel.baseSolver import baseSolver class scipy_ncg(baseSolver): __name__ = 'scipy_ncg' __license__ = "BSD" #__authors__ = __alg__ = "Newton-CG" __info__ = 'unconstrained NLP solver, can handle 2nd derivatives' iterfcnConnected = True def __init__(self):pass def __solver__(self, p): def iterfcn(x): p.xk, p.fk = x, p.f(x) p.iterfcn() if p.istop: raise isSolved if p.userProvided.d2f: fhess = p.d2f else: fhess = None xf = fmin_ncg(p.f, p.x0, p.df, fhess = fhess, maxiter = p.maxIter+15, disp = 0, callback=iterfcn) ff = p.f(xf) p.istop = 1000 p.xk = p.xf = xf p.fk = p.ff = ff openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_powell_oo.py000066400000000000000000000016251175775750500256100ustar00rootroot00000000000000from scipy.optimize import fmin_powell from openopt.kernel.baseSolver import baseSolver from openopt.kernel.ooMisc import isSolved class scipy_powell(baseSolver): __name__ = 'scipy_powell' __license__ = "BSD" #__authors__ = __alg__ = "" __info__ = 'unconstrained NLP solver, cannot handle user-supplied gradient' iterfcnConnected = True def __init__(self):pass def __solver__(self, p): def iterfcn(x): p.xk, p.fk = x, p.f(x) p.iterfcn() iter = p.iter - 1 if p.istop: raise isSolved try: iterfcn(p.x0) xf = fmin_powell(p.f, p.x0, xtol=p.xtol, ftol = p.ftol, disp = 0, maxiter=p.maxIter, maxfun = p.maxFunEvals, callback=iterfcn) except isSolved: xf = p.xk ff = p.f(p.xk) p.xk = p.xf = xf p.fk = p.ff = ff p.istop = 1000 p.iterfcn() openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_slsqp_oo.py000066400000000000000000000043011175775750500254420ustar00rootroot00000000000000from scipy.optimize import fmin_slsqp import openopt from openopt.kernel.setDefaultIterFuncs import * from openopt.kernel.ooMisc import WholeRepr2LinConst, xBounds2Matrix from openopt.kernel.baseSolver import baseSolver from numpy import * class EmptyClass: pass class scipy_slsqp(baseSolver): __name__ = 'scipy_slsqp' __license__ = "BSD" __authors__ = """Dieter Kraft, connected to scipy by Rob Falck, connected to OO by Dmitrey""" __alg__ = "Sequential Least SQuares Programming" __info__ = 'constrained NLP solver' __optionalDataThatCanBeHandled__ = ['A', 'Aeq', 'b', 'beq', 'lb', 'ub', 'c', 'h'] def __init__(self): pass def __solver__(self, p): bounds = [] if any(isfinite(p.lb)) or any(isfinite(p.ub)): ind_inf = where(p.lb==-inf)[0] p.lb[ind_inf] = -1e50 ind_inf = where(p.ub==inf)[0] p.ub[ind_inf] = 1e50 for i in range(p.n): bounds.append((p.lb[i], p.ub[i])) empty_arr = array(()) empty_arr_n = array(()).reshape(0, p.n) if not p.userProvided.c: p.c = lambda x: empty_arr.copy() p.dc = lambda x: empty_arr_n.copy() if not p.userProvided.h: p.h = lambda x: empty_arr.copy() p.dh = lambda x: empty_arr_n.copy() C = lambda x: -hstack((p.c(x), p.matmult(p.A, x) - p.b)) fprime_ieqcons = lambda x: -vstack((p.dc(x), p.A)) #else: C, fprime_ieqcons = None, None #if p.userProvided.h: H = lambda x: hstack((p.h(x), p.matmult(p.Aeq, x) - p.beq)) fprime_eqcons = lambda x: vstack((p.dh(x), p.Aeq)) #else: H, fprime_eqcons = None, None # fprime_cons = lambda x: vstack((p.dh(x), p.Aeq, p.dc(x), p.A)) x, fx, its, imode, smode = fmin_slsqp(p.f, p.x0, bounds=bounds, f_eqcons = H, f_ieqcons = C, full_output=1, iprint=-1, fprime = p.df, fprime_eqcons = fprime_eqcons, fprime_ieqcons = fprime_ieqcons, acc = p.contol, iter = p.maxIter) p.msg = smode if imode == 0: p.istop = 1000 #elif imode == 9: p.istop = ? CHECKME that OO kernel is capable of handling the case else: p.istop = -1000 p.xk, p.fk = array(x), fx openopt-0.38+svn1589/openopt/solvers/scipy_optim/scipy_tnc_oo.py000066400000000000000000000056031175775750500250720ustar00rootroot00000000000000from scipy.optimize.tnc import fmin_tnc import scipy.optimize.tnc as tnc import openopt from openopt.kernel.setDefaultIterFuncs import * from openopt.kernel.ooMisc import WholeRepr2LinConst from openopt.kernel.baseSolver import baseSolver class scipy_tnc(baseSolver): __name__ = 'scipy_tnc' __license__ = "BSD" __authors__ = "Stephen G. Nash" __alg__ = "undefined" __info__ = 'box-bounded NLP solver, can handle lb<=x<=ub constraints, some lb-ub coords can be +/- inf' __optionalDataThatCanBeHandled__ = ['lb', 'ub'] __isIterPointAlwaysFeasible__ = lambda self, p: True def __init__(self): pass def __solver__(self, p): #WholeRepr2LinConst(p)#TODO: remove me bounds = [] for i in range(p.n): bounds.append((p.lb[i], p.ub[i])) messages = 0#TODO: edit me maxfun=p.maxFunEvals if maxfun > 1e8: p.warn('tnc cannot handle maxFunEvals > 1e8, the value will be used') maxfun = int(1e8) xf, nfeval, rc = fmin_tnc(p.f, x0 = p.x0, fprime=p.df, args=(), approx_grad=0, bounds=bounds, messages=messages, maxfun=maxfun, ftol=p.ftol, xtol=p.xtol, pgtol=p.gtol) if rc in (tnc.INFEASIBLE, tnc.NOPROGRESS): istop = FAILED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON elif rc == tnc.FCONVERGED: istop = SMALL_DELTA_F elif rc == tnc.XCONVERGED: istop = SMALL_DELTA_X elif rc == tnc.MAXFUN: istop = IS_MAX_FUN_EVALS_REACHED elif rc == tnc.LSFAIL: istop = IS_LINE_SEARCH_FAILED elif rc == tnc.CONSTANT: istop = IS_ALL_VARS_FIXED elif rc == tnc.LOCALMINIMUM: istop = SOLVED_WITH_UNIMPLEMENTED_OR_UNKNOWN_REASON else: #TODO: IMPLEMENT USERABORT p.err('unknown stop reason') msg = tnc.RCSTRINGS[rc] p.istop, p.msg = istop, msg p.xf = xf ## INFEASIBLE = -1 # Infeasible (low > up) ## LOCALMINIMUM = 0 # Local minima reach (|pg| ~= 0) ## FCONVERGED = 1 # Converged (|f_n-f_(n-1)| ~= 0) ## XCONVERGED = 2 # Converged (|x_n-x_(n-1)| ~= 0) ## MAXFUN = 3 # Max. number of function evaluations reach ## LSFAIL = 4 # Linear search failed ## CONSTANT = 5 # All lower bounds are equal to the upper bounds ## NOPROGRESS = 6 # Unable to progress ## USERABORT = 7 # User requested end of minimization ##RCSTRINGS = { ## INFEASIBLE : "Infeasible (low > up)", ## LOCALMINIMUM : "Local minima reach (|pg| ~= 0)", ## FCONVERGED : "Converged (|f_n-f_(n-1)| ~= 0)", ## XCONVERGED : "Converged (|x_n-x_(n-1)| ~= 0)", ## MAXFUN : "Max. number of function evaluations reach", ## LSFAIL : "Linear search failed", ## CONSTANT : "All lower bounds are equal to the upper bounds", ## NOPROGRESS : "Unable to progress", ## USERABORT : "User requested end of minimization" ##} openopt-0.38+svn1589/openopt/tests/000077500000000000000000000000001175775750500171325ustar00rootroot00000000000000openopt-0.38+svn1589/openopt/tests/__init__.py000066400000000000000000000000011175775750500212320ustar00rootroot00000000000000 openopt-0.38+svn1589/openopt/tests/blockMisc.py000066400000000000000000000024451175775750500214170ustar00rootroot00000000000000from numpy import * from numpy.linalg import norm def project2box(x, lb, ub): X = atleast_1d(asfarray(x)) lb, ub = atleast_1d(lb), atleast_1d(ub) projection = copy(X) ind = where(projection < lb)[0] projection[ind] = lb[ind] ind = where(projection > ub)[0] projection[ind] = ub[ind] distance = norm(X-projection) return projection, distance def project2box_derivative(x, lb, ub): X = atleast_1d(asfarray(x)) lb, ub = atleast_1d(lb), atleast_1d(ub) projection, distance = project2box(X, lb, ub) dX = zeros(X.shape) if distance == 0: return dX else: dX[where(X > ub)[0]] = 1.0 dX[where(X < lb)[0]] = -1.0 return dX def project2ball(x, radius, center = 0.0): X = atleast_1d(asfarray(x)) distance2center = norm(X-center) if distance2center <= radius: return copy(x), 0.0 else: projection = center + (X-center) * (radius / distance2center) distance = distance2center - radius return projection, distance def project2ball_derivative(x, radius, center = 0.0): X = atleast_1d(asfarray(x)) distance2center = norm(X-center) if distance2center <= radius: return zeros(X.shape) else: distance = distance2center - radius return (X - center) / distance openopt-0.38+svn1589/openopt/tests/chain.py000066400000000000000000000240071175775750500205710ustar00rootroot00000000000000""" The test is related to obsolete OpenOpt version and doesn't work for now It was used to write an article related to numerical optimization. """ from numpy import * from openopt import * #from pylab import * TestCollection = xrange(5, 26) #TestCollection = xrange(5, 11) #TestCollection = [5] TestCollection = [21] P = 0 #P = 5e0 xyCoordsAlwaysExist = False solvers = ['ralg', 'ipopt','scipy_cobyla'] solvers = ['ralg', 'ipopt'] solvers = ['ralg'] #solvers = ['ipopt'] PLOT = 0 Results = {} contol = 1e-8 xl, yl = 0, 15 yThreshold = -1.0 LeftPointForceX = 10.00 LeftPointForceY = -3000.00 #maxY = array([yl, 10.0912237188, 5.81736169843, 2.38892359538,-0.528509686607, -3.61027100044,-7.21539449067,-11.0833587513,-14.5626399121,-17.2632362225,-19.3451872935,-21.3081000933,-23.4618325667,-25.641568098,-27.3915251977,-28.4811563214,-29.0663497915,-29.387570995,-29.4874690862,-29.2098877982,-28.3834712745,-27.140937007,-25.7876146522,-24.3568516911,-22.5652835804,-20.1292934475]) + yThreshold maxY = array([inf, 10.0399786566, 5.61033453009, 2.06002552258, -0.96112448303, -4.13674736433, -7.84375429882, -11.8094052553, -14.9106560481, -17.1598341467, -18.7959512268, -20.240402618, -21.6919090157, -22.9270315304, -23.5750132311, -23.5920241002, -23.2285382362, -22.6103728598, -21.5974976575, -19.9739484665, -17.7441144032, -15.2828386661, -12.9735192373, -10.7235600474, -8.05824588682, -4.62542867851]) + yThreshold #maxY[1] -= 100 for n in TestCollection: oovarInit = oovar('leftPointForces', v0 = [LeftPointForceX, LeftPointForceY], lb=[0, -inf]) MaxForces = 100*sin(arange(n)) + 5000*ones(n)\ + array([ -1.37163831e+03, -1.60694848e+03, -1.74685759e+03,\ -1.77099023e+03, -1.76295446e+03, -1.83232862e+03,\ -2.01327466e+03, -2.23292838e+03, -2.37990432e+03,\ -2.40786079e+03, -2.37604148e+03, -2.39220174e+03,\ -2.51227773e+03, -2.68825834e+03, -2.81448159e+03,\ -2.82791948e+03, -2.76385327e+03, -2.71873406e+03,\ -2.75969731e+03, -2.86237323e+03, -2.93613565e+03,\ -2.91260196e+03, -2.80726185e+03, -2.69990883e+03,\ -2.65982371e+03, -2.68285823e+03, -2.69793719e+03,\ -2.63722331e+03, -2.49886567e+03, -2.34512448e+03,\ -2.24405190e+03, -2.20790597e+03, -2.18342816e+03,\ -2.10368051e+03, -1.95071662e+03, -1.77036769e+03,\ -1.62911926e+03, -1.55345727e+03, -1.50621766e+03,\ -1.42212572e+03, -1.26885753e+03, -1.07614103e+03,\ -9.07638583e+02, -8.02510393e+02, -7.39726398e+02,\ -6.58001243e+02, -5.12877756e+02, -3.17504802e+02,\ -1.30014677e+02, 9.99898976e-03])[:n] lengths = 5*ones(n)+cos(arange(n))#array([4, 3, 1, 2]) masses = 15*ones(n)+4*cos(arange(n))#array([10, 15, 20]) g = 10 Fm = masses * g ######################################################## s = [20, 20] AdditionalMasses = oovar('AdditionalMasses', v0=s + [(100.0-sum(s))/(n-len(s))]*(n-len(s)), lb=zeros(n)) ######################################################## ######################################################## from blockMisc import * #def blockEngineFunc(inp, AdditionalMasses, y_limit, blockID): def blockEngineFunc(inp, AdditionalMasses, blockID): if blockID == 0: lFx, lFy, lx, ly, prevBlockForceThreshold, prev_yLimit = inp[0], inp[1], xl, yl, 0, 0 else: lFx, lFy, lx, ly, prevBlockForceThreshold, prev_yLimit = inp[0], inp[1], inp[2], inp[3], inp[4], inp[5] prevBlockBroken = blockID>=0 and isnan(prevBlockForceThreshold)\ or \ (prevBlockForceThreshold > 0 and P == 0)\ or \ (prev_yLimit > 0 or isnan(prev_yLimit) and P == 0 and not xyCoordsAlwaysExist) # calculate output Fwhole = sqrt(lFx**2+lFy**2) ForceThreshold = (Fwhole - MaxForces[blockID]) / 1e4 CurrentAdditionalMass = AdditionalMasses[blockID] rFy = lFy +Fm[blockID] + CurrentAdditionalMass*g # TODO : store Fm[i] inside blocks rFx = lFx# Fx are same along whole chain dx, dy = lengths[blockID] * lFx/ Fwhole, lengths[blockID] * lFy/ Fwhole rx = lx + dx ry = ly + dy yLimit = ly - maxY[blockID] if P != 0: projection, distance = project2ball(x = [lFx, lFy], radius=MaxForces[blockID], center = 0) ForceThreshold += P * distance / 1e4 projection, distance = project2box(ly, -inf, maxY[blockID]) if distance > 0: yLimit = P/1e4 * distance if prevBlockBroken or (prev_yLimit>0 and P == 0): #and not xyCoordsAlwaysExist: rx, ry, ForceThreshold, rFx, rFy, yLimit = nan, nan, nan, nan, nan, nan r = array((rFx, rFy, rx, ry, ForceThreshold, yLimit)) return r #def derivative_blockEngineFunc(inp, AdditionalMasses, y_limit, blockID): def derivative_blockEngineFunc(inp, AdditionalMasses, blockID): # TODO: return nans if prev block is broken if blockID == 0: lFx, lFy, lx, ly, prevBlockForceThreshold, prev_yLimit = inp[0], inp[1], xl, yl, 0, 0 else: lFx, lFy, lx, ly, prevBlockForceThreshold, prev_yLimit = inp[0], inp[1], inp[2], inp[3], inp[4], inp[5] if blockID == 0: nVars = 2 + len(AdditionalMasses) else: nVars = 6 + len(AdditionalMasses) #r = zeros((len(inp)+1, nVars)) r = zeros((6, nVars)) # d_ rFx / r[0, 0] = 1 # d_lFx # d_rFy/ r[1, 1] = 1 # d_lFy r[1, len(inp) + blockID] = g # TODO: Check it (below) #elif blockID < n-1: #r[3, 5 + blockID] = g # d_rx / if blockID!=0: r[2, 2] = 1 # dlx Fwhole = sqrt(lFx**2+lFy**2) #r[2, 0] = lengths[blockID] / Fwhole # dlFx r[2, 0] = lengths[blockID] * lFy**2 / (Fwhole ** 3) # d_lFx r[2, 1] = - lengths[blockID] * lFx * lFy / (Fwhole ** 3) # d_lFy # d_ry / if blockID!=0: r[3, 3] = 1 # dly r[3, 0] = - lengths[blockID] * lFx * lFy / (Fwhole ** 3) # d_lFx, and is same to r[2,1] r[3, 1] = lengths[blockID] * lFx**2 / (Fwhole ** 3) # d_lFy # dForceThreshold r[4, 0] = lFx / Fwhole / 1e4 # / dlFx r[4, 1] = lFy / Fwhole / 1e4 # / dlFy # dYlimit if blockID != 0: r[5, 3] = 1.0 #d_Ylimit / d_yl if P != 0: projection, distance = project2ball(x = [lFx, lFy], radius=MaxForces[blockID], center = 0) if distance != 0: penalty_derivative = P/1e4 * project2ball_derivative(x = [lFx, lFy], radius=MaxForces[blockID], center = 0) r[4, 0] += penalty_derivative[0] r[4, 1] += penalty_derivative[1] projection, distance = project2box(ly, -inf, maxY[blockID]) if distance > 0: r[5, 3] = P/1e4 * project2box_derivative(ly, -inf, maxY[blockID]) #projection, distance = project2box(ly, maxY[blockID], inf) #yLimit = P * distance prevBlockBroken = blockID>=0 and isnan(prevBlockForceThreshold)\ or \ (prevBlockForceThreshold > 0 and P == 0)\ or \ (prev_yLimit > 0 or isnan(prev_yLimit) and P == 0 and not xyCoordsAlwaysExist) if prevBlockBroken: r *= nan return r ooFuncs, c = [], [] constrYmax = [] for i in xrange(n): oof = oofun(blockEngineFunc, args = copy(i), name = 'blockEngine'+str(i)) if i == 0: oof.input = (oovarInit, AdditionalMasses) else: oof.input = (ooFuncs[i-1], AdditionalMasses) oof.d = derivative_blockEngineFunc ooFuncs.append(oof) # TODO: replace "4" by named output "ForceThreshold" c.append(oolin([0, 0, 0, 0, 1, 0], input = ooFuncs[copy(i)], name='maxForce'+str(i))) c.append(oolin([0, 0, 0, 0, 0, 1], input = ooFuncs[copy(i)], name='Ylimit'+str(i))) #c.append(y_limit) # y_limit = oofun(lambda *inputs: [inp[1]-maxY[i] for i, inp in enumerate(inputs)], input = ooFuncs, name='maxY') # def d_y_limit(*inputs): # r = zeros((n, len(inputs[0])*n)) # for i in xrange(n): # r[i, len(inputs[0]) * i + 1] = 1 # return r # y_limit.d = d_y_limit # # c.append(y_limit) f = oofun(lambda z: z[0]**1.5, input = ooFuncs[-1], d = lambda z:[0, 0, 1.5*z[0]**0.5, 0, 0, 0], name = 'objFunc') #f = oofun(lambda z: z[0], input = ooFuncs[-1], d = lambda z:[0, 0, 1, 0, 0,0], name = 'objFunc') #f = oolin(array([0, 0, 1, 0, 0, 0]), input = ooFuncs[-1], name = 'objFunc') sumOfMasses = oofun(lambda z: 1-z.sum()/100.0, input=AdditionalMasses, d = lambda z: -ones(n)/100.0, name='sOm') c.append(sumOfMasses) colors = ['b', 'r', 'g', 'y', 'm', 'c'] for j, solver in enumerate(solvers): p = NLP(f, c=c, goal = 'max', gtol = 1e-6, plot=0, contol = contol, maxFunEvals = 1e10) def callback(p): print p.c(p.xk) return 0 #p.callback = callback if solver == 'scipy_cobyla': p.f_iter = max((int(n/2), 5)) if solver == 'ipopt': p.maxIter = 1500 - 40*n else: p.maxIter = 15000 r = p.solve(solver, plot=0, showFeas=1, maxTime = 150, iprint = -1, ftol=1e-6, xtol=1e-6) Results[(n, p.solver.__name__)] = r if r.isFeasible: msgF = '+' else: msgF = '-' print 'n=%d' % n, ('f=%3.2f'% r.ff)+'['+msgF+']','Time=%3.1f' % r.elapsed['solver_time'] if PLOT: hold(1) for i, oof in enumerate(ooFuncs): if i == 0: plot([xl, ooFuncs[0](p.xk)[0]], [yl, ooFuncs[0](p.xk)[1]], colors[j]) plot([xl, ooFuncs[0](p.x0)[0]], [yl, ooFuncs[0](p.x0)[1]], 'k') else: plot([ooFuncs[i-1](p.xk)[0], ooFuncs[i](p.xk)[0]], [ooFuncs[i-1](p.xk)[1], ooFuncs[i](p.xk)[1]], colors[j]) plot([ooFuncs[i-1](p.x0)[0], ooFuncs[i](p.x0)[0]], [ooFuncs[i-1](p.x0)[1], ooFuncs[i](p.x0)[1]], 'k') if PLOT: show() openopt-0.38+svn1589/openopt/tests/nlp1.py000066400000000000000000000036551175775750500203670ustar00rootroot00000000000000from numpy import cos, arange, ones, asarray, zeros, mat, array from openopt import NLP def test(complexity=0, **kwargs): n = 15 * (complexity+1) x0 = 15*cos(arange(n)) + 8 f = lambda x: ((x-15)**2).sum() df = lambda x: 2*(x-15) c = lambda x: [2* x[0] **4-32, x[1]**2+x[2]**2 - 8] # dc(x)/dx: non-lin ineq constraints gradients (optional): def dc(x): r = zeros((len(c(x0)), n)) r[0,0] = 2 * 4 * x[0]**3 r[1,1] = 2 * x[1] r[1,2] = 2 * x[2] return r hp = 2 h1 = lambda x: (x[-1]-13)**hp h2 = lambda x: (x[-2]-17)**hp h = lambda x:[h1(x), h2(x)] # dh(x)/dx: non-lin eq constraints gradients (optional): def dh(x): r = zeros((2, n)) r[0, -1] = hp*(x[-1]-13)**(hp-1) r[1, -2] = hp*(x[-2]-17)**(hp-1) return r lb = -8*ones(n) ub = 15*ones(n)+8*cos(arange(n)) ind = 3 A = zeros((2, n)) A[0, ind:ind+2] = 1 A[1, ind+2:ind+4] = 1 b = [15, 8] Aeq = zeros(n) Aeq[ind+4:ind+8] = 1 beq = 45 ######################################################## colors = ['b', 'k', 'y', 'g', 'r'] #solvers = ['ipopt', 'ralg','scipy_cobyla'] solvers = ['ralg','scipy_slsqp', 'ipopt'] solvers = [ 'ralg', 'scipy_slsqp'] solvers = [ 'ralg'] solvers = [ 'r2'] solvers = [ 'ralg', 'scipy_slsqp'] ######################################################## for i, solver in enumerate(solvers): p = NLP(f, x0, df=df, c=c, h=h, dc=dc, dh=dh, lb=lb, ub=ub, A=A, b=b, Aeq=Aeq, beq=beq, maxIter = 1e4, \ show = solver==solvers[-1], color=colors[i], **kwargs ) if not kwargs.has_key('iprint'): p.iprint = -1 # p.checkdf() # p.checkdc() # p.checkdh() r = p.solve(solver) if r.istop>0: return True, r, p else: return False, r, p if __name__ == '__main__': isPassed, r, p = test(iprint= 10, plot=0) assert isPassed openopt-0.38+svn1589/openopt/tests/nlp2.py000066400000000000000000000023731175775750500203640ustar00rootroot00000000000000from numpy import log from openopt import NLP x0 = [4, 5, 6] #h = lambda x: log(1+abs(4+x[1])) #f = lambda x: log(1+abs(x[0])) f = lambda x: x[0]**4 + x[1]**4 + x[2]**4 df = lambda x: [4*x[0]**3, 4*x[1]**3, 4*x[2]**3] h = lambda x: [(x[0]-1)**2, (x[1]-1)**4] dh = lambda x: [[2*(x[0]-1), 0, 0], [0, 4*(x[1]-1)**3, 0]] colors = ['r', 'b', 'g', 'k', 'y'] solvers = ['ralg','scipy_cobyla', 'algencan', 'ipopt', 'scipy_slsqp'] solvers = ['ralg','algencan'] contol = 1e-8 gtol = 1e-8 for i, solver in enumerate(solvers): p = NLP(f, x0, df=df, h=h, dh=dh, gtol = gtol, diffInt = 1e-1, contol = contol, iprint = 1000, maxIter = 1e5, maxTime = 50, maxFunEvals = 1e8, color=colors[i], plot=0, show = i == len(solvers)) p.checkdh() r = p.solve(solver) # #x0 = 4 ##h = lambda x: log(1+abs(4+x[1])) ##f = lambda x: log(1+abs(x[0])) #f = lambda x: x**4 #h = lambda x: (x-1)**2 #colors = ['r', 'b', 'g', 'k', 'y'] #solvers = ['ralg','scipy_cobyla', 'algencan', 'ipopt', 'scipy_slsqp'] ##solvers = ['algencan'] #contol = 1e-8 #gtol = 1e-8 #for i, solver in enumerate(solvers): # p = NLP(f, x0, h=h, gtol = gtol, contol = contol, iprint = 1000, maxIter = 1e5, maxTime = 50, maxFunEvals = 1e8, color=colors[i], plot=0, show = i == len(solvers)) # r = p.solve(solver) openopt-0.38+svn1589/openopt/tests/nlpLC.py000066400000000000000000000050661175775750500205230ustar00rootroot00000000000000from openopt import NLP from numpy import cos, arange, ones, asarray, zeros, mat, array N = 100 # objective function: f = lambda x: ((x-5)**2).sum() # objective function gradient (optional): df = lambda x: 2*(x-5) # start point (initial estimation) x0 = 8*cos(arange(N)) # c(x) <= 0 constraints def c(x): r = zeros(N-1) for i in xrange(N-1): r[i] = x[i]**2 + x[i+1]**2 - 1 return r def dc(x): r = zeros((N-1, N)) for i in xrange(N-1): r[i, i] = 2*x[i] r[i, i+1] = 2*x[i+1] return r # counter = 0 # r = zeros(N*(N-1)/2) # for i in xrange(N): # for j in xrange(i): # r[counter] = x[i]**2 + x[j]**2 - 1 # counter += 1 # return r lb = -6*ones(N) ub = 6*ones(N) ub[4] = 4 lb[5], ub[5] = 8, 15 # general linear inequality constraints #A = zeros((3, N)) #A[0, 9] = 1 #A[0, 19] = 1 #A[1, 10:12] = 1 #A[2] = -ones(N) #b = [7, 9, -825] A, b=None, None # general linear equality constraints #Aeq = zeros(N) #Aeq[10:12] = 1 #beq = 11 Aeq, beq = None, None # required constraints tolerance, default for NLP is 1e-6 contol = 1e-7 # If you use solver algencan, NB! - it ignores xtol and ftol; using maxTime, maxCPUTime, maxIter, maxFunEvals, fEnough is recommended. # Note that in algencan gtol means norm of projected gradient of the Augmented Lagrangian # so it should be something like 1e-3...1e-5 gtol = 1e-7 # (default gtol = 1e-6) # Assign problem: # 1st arg - objective function # 2nd arg - start point p = NLP(f, x0, df=df, c=c, dc=dc, gtol=gtol, contol=contol, iprint = 50, maxIter = 10000, maxFunEvals = 1e7, name = 'NLP_1') #p = NLP(f, x0, df=df, Aeq=Aeq, beq=beq, # gtol=gtol, contol=contol, iprint = 50, maxIter = 10000, maxFunEvals = 1e7, name = 'NLP_1') #p = NLP(f, x0, df=df, lb=lb, ub=ub, gtol=gtol, contol=contol, iprint = 50, maxIter = 10000, maxFunEvals = 1e7, name = 'NLP_1') #optional: graphic output, requires pylab (matplotlib) p.plot = 0 #optional: user-supplied 1st derivatives check p.checkdf() p.checkdc() p.checkdh() def MyIterFcn(p): return 0 # print 'Iteration',p.iter # if p.iter == 50: # p.user.mylist.append(p.xk.copy()) # return 0 p.user.mylist = [] # solve the problem #p.debug=1 solver = 'algencan' solver = 'ralg' #solver = 'ipopt' #solver = 'scipy_slsqp' p.debug=1 r = p.solve(solver, showLS=0, iprint=10, maxTime = 50, callback = MyIterFcn) # string argument is solver name #r = p.solve('r2', iprint = 1, plot=0, showLS=1, maxIter=480) # r.xf and r.ff are optim point and optim objFun value # r.ff should be something like 132.0522 openopt-0.38+svn1589/openopt/tests/nlsp1.py000066400000000000000000000020051175775750500205360ustar00rootroot00000000000000from openopt import NLSP from numpy import asfarray, zeros, cos, sin, inf def test(complexity=0, **kwargs): f = lambda x: (x[0]**3+x[1]**3-9, x[0]-0.5*x[1], cos(x[2])+x[0]-1.5) #optional: gradient def df(x): df = zeros((3,3)) df[0,0] = 3*x[0]**2 df[0,1] = 3*x[1]**2 df[1,0] = 1 df[1,1] = -0.5 df[2,0] = 1 df[2,2] = -sin(x[2]) return df x0 = [8,15, 80] #w/o gradient: #p = NLSP(f, x0) p = NLSP(f, x0, df = df, maxFunEvals = 1e5, iprint = -1, ftol = 1e-6, contol=1e-35) p.lb = [-inf, -inf, 150] p.ub = [inf, inf, 158] # you could try also comment/uncomment nonlinear constraints: p.c = lambda x: (x[2] - 150.8)**2-1.5 # optional: gradient p.dc = lambda x: asfarray((0, 0, 2*(x[2]-150.8))) # also you could set it via p=NLSP(f, x0, ..., c = c, dc = dc) r = p.solve('nssolve', **kwargs) return r.istop>0, r, p if __name__ == '__main__': isPassed, r, p = test() #assert r.istop > 0 openopt-0.38+svn1589/openopt/tests/nsp1.py000066400000000000000000000041111175775750500203620ustar00rootroot00000000000000""" Example: Solving nonsmooth problem |x1| + 1.2|x2| + 1.44|x3| + ... + 1.2^N |xN| -> min N=75 x0 = [cos(1), cos(2), ..., cos(N)] x_opt = all-zeros f_opt = 0 """ from numpy import * from openopt import NSP #N = 12 #K = 11 N = 1000 K = 10 #N = 10 #K = 7 P = 1.0002 P2 = 1.001 a = 3.5 #N = 7 #K = 6 #objFun = lambda x: sum(1.2 ** arange(len(x)) * abs(x)) #objFun = lambda x: sum(1.2 ** arange(len(x)) * x**2) f1 = lambda x: sum(abs(x) ** P) f2 = lambda x: sum(a ** (3+arange(K)) * abs(x[:K])**P2) f = lambda x: f1(x) + f2(x) df1 = lambda x: P * sign(x) * abs(x) ** (P-1) df2 = lambda x: hstack((a ** (3+arange(K)) * P2 * abs(x[:K]) ** (P2-1)*sign(x[:K]), zeros(N-K))) df = lambda x: df1(x) + df2(x) #f, df = f1, df1 #objFun = lambda x: sum(x**2) x0 = cos(1+asfarray(range(N))) #OPTIONAL: user-supplied gradient/subgradient #p.df = lambda x: 1.2 ** arange(len(x)) * 2*x#sign(x) #p.df = lambda x: 2*x #p.plot = 0 #p.xlim = (inf, 5) #p.ylim = (0, 5000000) #p.checkdf() solvers = ['r2', 'ipopt', 'algencan','ralg'] solvers = ['r2', 'algencan','ralg'] #solvers = ['ralg', 'r2'] solvers = ['r2', 'lincher'] solvers = ['ralg'] #solvers = ['r2'] #solvers = ['scipy_slsqp'] #solvers = ['algencan'] #solvers = ['ipopt'] colors = ['r', 'b', 'k', 'g'] maxIter = 1000 for i, solver in enumerate(solvers): p = NSP(f, x0, df=df, xtol = 1e-7, maxIter = maxIter, maxTime=150, ftol=1e-7) #p.checkdf() r = p.solve(solver, maxVectorNum=35, iprint=1, showLS=0, plot=0, color=colors[i], show=solver==solvers[-1]) # ralg is name of a solver #p = NSP(f, x0=r.xf, df=df, xtol = 1e-7, maxIter = maxIter, maxTime=150, ftol=1e-7) #r = p.solve(solver, maxVectorNum=45, iprint=1, showLS=0, plot=0, color=colors[i], show=solver==solvers[-1]) #for i, solver in enumerate(solvers): # p2 = NSP(f, r.xf, df=df, xtol = 1e-6, maxIter = 1200, maxTime=150, ftol=1e-6) # #p.checkdf() # r2 = p2.solve(solver, maxVectorNum=15, iprint=1, showLS=1, plot=0, color=colors[i], show=solver==solvers[-1]) # ralg is name of a solver #print 'x_opt:\n', r.xf print 'f_opt:', r.ff # should print small positive number like 0.00056 openopt-0.38+svn1589/openopt/tests/nsp2.py000066400000000000000000000025641175775750500203750ustar00rootroot00000000000000""" Example: Solving nonsmooth problem #K|x1| + |x2| -> min #x0 = [10^4, 10] x_opt = all-zeros f_opt = 0 """ from numpy import * from openopt import NSP K = 10**3 f = lambda x: abs(x[0]) + abs(x[1])*K + abs(x[2]) * K**2 x0 = [1000, 0.011, 0.01] #OPTIONAL: user-supplied gradient/subgradient df = lambda x: [sign(x[0]), sign(x[1])*K, sign(x[2]) * K**2] #p.df = lambda x: 2*x #p.plot = 0 #p.xlim = (inf, 5) #p.ylim = (0, 5000000) #p.checkdf() solvers = ['r2', 'ipopt', 'algencan','ralg'] solvers = ['r2', 'algencan','ralg'] #solvers = ['ralg', 'r2'] solvers = ['r2', 'lincher'] solvers = ['ralg'] solvers = ['r2'] #solvers = ['scipy_slsqp'] #solvers = ['algencan'] #solvers = ['ipopt'] colors = ['r', 'b', 'k', 'g'] maxIter = 1000 for i, solver in enumerate(solvers): p = NSP(f, x0, df=df, xtol = 1e-11, ftol=1e-10, maxIter = maxIter, maxTime=150) #p.checkdf() r = p.solve(solver, maxVectorNum=4, iprint=1, showLS=0, plot=0, color=colors[i], show=solver==solvers[-1]) # ralg is name of a solver #for i, solver in enumerate(solvers): # p2 = NSP(f, r.xf, df=df, xtol = 1e-6, maxIter = 1200, maxTime=150, ftol=1e-6) # #p.checkdf() # r2 = p2.solve(solver, maxVectorNum=15, iprint=1, showLS=1, plot=0, color=colors[i], show=solver==solvers[-1]) # ralg is name of a solver #print 'x_opt:\n', r.xf print 'f_opt:', r.ff # should print small positive number like 0.00056 openopt-0.38+svn1589/openopt/tests/oosolver.py000066400000000000000000000007061175775750500213570ustar00rootroot00000000000000from openopt import oosolver, NLP ipopt = oosolver('ipopt', color='r') # oosolver can hanlde prob parameters ralg = oosolver('ralg', color='k', alp = 4.0) # as well as solver parameters solvers = [ralg, ipopt] for solver in solvers: assert solver.isInstalled, 'solver ' + solver.__name__ + ' is not installed' p = NLP(x0 = 15, f = lambda x: x**4, df = lambda x: 4 * x**3, iprint = 0) r = p.solve(solver, plot=1, show = solver == solvers[-1]) openopt-0.38+svn1589/openopt/tests/rastrigin.py000066400000000000000000000004561175775750500215130ustar00rootroot00000000000000from openopt import GLP from numpy import * f = lambda x: (x*x - 10*cos(2*pi*x) + 10).sum() #Rastrigin function p = GLP(f, lb = -ones(10)*5.12, ub = ones(10)*5.12, maxIter = 1e3, maxFunEvals = 1e5, maxTime = 10, maxCPUTime = 10) r = p.solve('de', plot=0) x_opt, f_opt = r.xf, r.ff print x_opt openopt-0.38+svn1589/setup.cfg000066400000000000000000000000641175775750500161250ustar00rootroot00000000000000[egg_info] #tag_svn_revision = 1 #tag_build = .dev openopt-0.38+svn1589/setup.py000066400000000000000000000073751175775750500160320ustar00rootroot00000000000000#! /usr/bin/env python descr = """ """ from os.path import join import os import sys, compileall DISTNAME = 'openopt' DESCRIPTION = 'A python module for numerical optimization' LONG_DESCRIPTION = descr MAINTAINER = 'Dmitrey Kroshko', MAINTAINER_EMAIL = 'dmitrey-at-openopt-dot-org', URL = 'http://openopt.org', LICENSE = 'new BSD' sys.path.append(os.getcwd() + os.sep + 'openopt') from ooVersionNumber import __version__ as ooVer openopt_version = ooVer DOWNLOAD_URL = 'http://openopt.org/images/3/33/OpenOpt.zip' try: import setuptools except: print('you should have setuptools installed (http://pypi.python.org/pypi/setuptools), for some Linux distribs you can get it via [sudo] apt-get install python-setuptools') print('press Enter for exit...') raw_input() exit() from distutils.errors import DistutilsError #from numpy.distutils.system_info import system_info, NotFoundError, dict_append, so_ext from numpy.distutils.core import setup, Extension DOC_FILES = [] def configuration(parent_package='',top_path=None, package_name=DISTNAME): if os.path.exists('MANIFEST'): os.remove('MANIFEST') pkg_prefix_dir = 'openopt' # Get the version from numpy.distutils.misc_util import Configuration config = Configuration(package_name,parent_package,top_path, version = openopt_version, maintainer = MAINTAINER, maintainer_email = MAINTAINER_EMAIL, description = DESCRIPTION, license = LICENSE, url = URL, download_url = DOWNLOAD_URL, long_description = LONG_DESCRIPTION) # XXX: once in SVN, should add svn version... #print config.make_svn_version_py() # package_data does not work with sdist for setuptools 0.5 (setuptools bug), # so we need to add them here while the bug is not solved... return config if __name__ == "__main__": # solverPaths = {} # #File = string.join(__file__.split(os.sep)[:-1], os.sep) # for root, dirs, files in os.walk('openopt'+os.sep +'solvers'): # #for root, dirs, files in os.walk(os.path.dirname(file)+os.sep+'solvers'): # rd = root.split(os.sep) # if '.svn' in rd: continue # rd = rd[rd.index('solvers')+1:] # for file in files: # if len(file)>6 and file[-6:] == '_oo.py': # solverPaths[file[:-6]] = string.join(rd,'.') + '.'+file[:-3] # f = open('solverPaths.py', 'w') # f.write('solverPaths = ' + str(solverPaths)) # f.close() # shutil.move('solverPaths.py', 'openopt' + os.sep + 'kernel' + os.sep + 'solverPaths.py') # setuptools version of config script # package_data does not work with sdist for setuptools 0.5 (setuptools bug) # So we cannot add data files via setuptools yet. #data_files = ['test_data/' + i for i in TEST_DATA_FILES] #data_files.extend(['docs/' + i for i in doc_files]) setup(configuration = configuration, install_requires=['numpy','setproctitle'], # can also add version specifiers #namespace_packages=['kernel'], #setup_requires = 'setproctitle', #py_modules = ['kernel', 'tests', 'examples', 'solvers'], packages=setuptools.find_packages(), include_package_data = True, #package_data = '*.txt', test_suite='',#"openopt.tests", # for python setup.py test zip_safe=False, # the package can run out of an .egg file #FIXME url, download_url, ext_modules classifiers = [ 'Development Status :: 4 - Beta', 'Environment :: Console', 'Intended Audience :: Developers', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: BSD License', 'Topic :: Scientific/Engineering'] )